From: 阿德烈 via GitGitGadget <hidden> Date: 2021-02-07 15:23:36
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view In turn.
If there is a commit with many files and we exit in search,
We will have to traverse list again to get the file diff which
we want to see.Therefore,here is a new method:every time before
we view the file diff,the current coordinates will be stored in
`GIT_DIR/difftool_skip_to`,this file will be deleted after
successful traversing.But if an unexpected exit occurred midway,
git will view the coordinates in the save point,ask user if they
want continue from the last saved point.This will improve the
user experience.
Signed-off-by: ZheNing Hu <redacted>
---
git-difftool-helper.sh: learn a new way skip to save point
this patch's origin discuss is here:
https://lore.kernel.org/git/gOXOaoqn-E9A2ob7ykWEcDc7ZxmSwAjcP5CCFKfr5ejCOWZQ1lfAUZcbgYT9AyQCcDgJvCrnrtziXiels-Hxol3xlkGTVHk24SvAdaSUtKQ=@rtzoeller.com/
git user may should travel the diff list to choice file diff to view, if
they exit in midway,they must travel it again. I’m on the basis of the
"difftool_skip_to" suggested by Junio,Provides a possibility for this
user-friendly solution.
Thanks!
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/870
git-difftool--helper.sh | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
@@ -6,6 +6,7 @@# Copyright (c) 2009, 2010 David AguilarTOOL_MODE=diff+GIT_DIFFTOOL_SKIP_TO_FILE="$GIT_DIR/difftool-skip-to" .git-mergetool--lib# difftool.prompt controls the default prompt/no-prompt behavior
@@ -40,6 +41,31 @@ launch_merge_tool () {# the user with the real $MERGED name before launching $merge_tool.ifshould_promptthen+iftest-f"$GIT_DIFFTOOL_SKIP_TO_FILE"+then+SAVE_POINT_NUM=$(cat"$GIT_DIFFTOOL_SKIP_TO_FILE")+iftest$SAVE_POINT_NUM-le$GIT_DIFF_PATH_TOTAL&&+test$SAVE_POINT_NUM-gt$GIT_DIFF_PATH_COUNTER+then+# choice skip or not skip when check first file.+iftest$GIT_DIFF_PATH_COUNTER-eq"1"+then+printf"do you want to skip to last time difftool save point($SAVE_POINT_NUM) [Y/n]?"+readskip_ans||return+iftest"$skip_ans"=y+then+return+fi+else+return+fi+fi+fi+# write the current coordinates to .git/difftool-skip-to+iftest!$SAVE_POINT_NUM||$SAVE_POINT_NUM-ne$GIT_DIFF_PATH_COUNTER+then+echo$GIT_DIFF_PATH_COUNTER>$GIT_DIFFTOOL_SKIP_TO_FILE+fiprintf"\nViewing (%s/%s): '%s'\n""$GIT_DIFF_PATH_COUNTER"\"$GIT_DIFF_PATH_TOTAL""$MERGED"ifuse_ext_cmd
From: ZheNing Hu via GitGitGadget <hidden> Date: 2021-02-08 17:10:33
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
we want to see. Therefore, here is a new method: every time before
we view the file diff, the current coordinates will be stored in
`GIT_DIR/difftool-last-position`, this file will be deleted after
successful traversing. But if an unexpected exit occurred midway or
users similar to using "ctrl+c" kill the process,and the user wants
to redo the same `git difftoool`, git will view the coordinates in
the save point, ask user if they want continue from the last position.
This will improve the user experience.
Signed-off-by: ZheNing Hu <redacted>
---
git-difftool-helper.sh: learn a new way skip to save point
git user may should travel the diff list to choice file diff to view, if
they exit in midway,they must travel it again. By saving current
coordinates in GIT_DIR/difftool-last-position method, provides a
possibility for this user-friendly solution.
this patch's origin discuss is here:
https://lore.kernel.org/git/gOXOaoqn-E9A2ob7ykWEcDc7ZxmSwAjcP5CCFKfr5ejCOWZQ1lfAUZcbgYT9AyQCcDgJvCrnrtziXiels-Hxol3xlkGTVHk24SvAdaSUtKQ=@rtzoeller.com/
Thanks!
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/870
Range-diff vs v1:
1: e77c3e33ba85 ! 1: 2468eaff322b git-difftool-helper.sh: learn a new way skip to save point
@@ Metadata
Author: ZheNing Hu [off-list ref]
## Commit message ##
- git-difftool-helper.sh: learn a new way skip to save point
+ git-difftool-helper.sh: learn a new way go back to last save point
- `git difftool` only allow us to select file to view In turn.
- If there is a commit with many files and we exit in search,
+ `git difftool` only allow us to select file to view in turn.
+ If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
- we want to see.Therefore,here is a new method:every time before
- we view the file diff,the current coordinates will be stored in
- `GIT_DIR/difftool_skip_to`,this file will be deleted after
- successful traversing.But if an unexpected exit occurred midway,
- git will view the coordinates in the save point,ask user if they
- want continue from the last saved point.This will improve the
- user experience.
+ we want to see. Therefore, here is a new method: every time before
+ we view the file diff, the current coordinates will be stored in
+ `GIT_DIR/difftool-last-position`, this file will be deleted after
+ successful traversing. But if an unexpected exit occurred midway or
+ users similar to using "ctrl+c" kill the process,and the user wants
+ to redo the same `git difftoool`, git will view the coordinates in
+ the save point, ask user if they want continue from the last position.
+ This will improve the user experience.
Signed-off-by: ZheNing Hu [off-list ref]
@@ git-difftool--helper.sh
# Copyright (c) 2009, 2010 David Aguilar
TOOL_MODE=diff
-+GIT_DIFFTOOL_SKIP_TO_FILE="$GIT_DIR/difftool-skip-to"
++GIT_DIFFTOOL_LAST_POSITION="$GIT_DIR/difftool-last-position"
++DIFFTOOL_FIRST_NUM="1"
. git-mergetool--lib
# difftool.prompt controls the default prompt/no-prompt behavior
@@ git-difftool--helper.sh: launch_merge_tool () {
# the user with the real $MERGED name before launching $merge_tool.
if should_prompt
then
-+ if test -f "$GIT_DIFFTOOL_SKIP_TO_FILE"
++ if test -f "$GIT_DIFFTOOL_LAST_POSITION"
+ then
-+ SAVE_POINT_NUM=$(cat "$GIT_DIFFTOOL_SKIP_TO_FILE")
-+ if test $SAVE_POINT_NUM -le $GIT_DIFF_PATH_TOTAL &&
-+ test $SAVE_POINT_NUM -gt $GIT_DIFF_PATH_COUNTER
++ if SAVE_POINT_NUM=$(cat 2>/dev/null "$GIT_DIFFTOOL_LAST_POSITION") &&
++ test "$SAVE_POINT_NUM" -le "$GIT_DIFF_PATH_TOTAL" &&
++ test "$SAVE_POINT_NUM" -gt "$GIT_DIFF_PATH_COUNTER"
+ then
-+ # choice skip or not skip when check first file.
-+ if test $GIT_DIFF_PATH_COUNTER -eq "1"
++ if test "$GIT_DIFF_PATH_COUNTER" -eq "$DIFFTOOL_FIRST_NUM"
+ then
-+ printf "do you want to skip to last time difftool save point($SAVE_POINT_NUM) [Y/n]?"
++ printf "Do you want to start from the possible last file you were viewing? [Y/n]?"
+ read skip_ans || return
+ if test "$skip_ans" = y
+ then
@@ git-difftool--helper.sh: launch_merge_tool () {
+ fi
+ fi
+ fi
-+ # write the current coordinates to .git/difftool-skip-to
-+ if test !$SAVE_POINT_NUM || $SAVE_POINT_NUM -ne $GIT_DIFF_PATH_COUNTER
++ if test -z "$SAVE_POINT_NUM" ||
++ test "$SAVE_POINT_NUM" -ne "$GIT_DIFF_PATH_COUNTER"
+ then
-+ echo $GIT_DIFF_PATH_COUNTER > $GIT_DIFFTOOL_SKIP_TO_FILE
++ echo "$GIT_DIFF_PATH_COUNTER" >"$GIT_DIFFTOOL_LAST_POSITION"
+ fi
printf "\nViewing (%s/%s): '%s'\n" "$GIT_DIFF_PATH_COUNTER" \
"$GIT_DIFF_PATH_TOTAL" "$MERGED"
@@ git-difftool--helper.sh: else
done
fi
-+if test -f $GIT_DIFFTOOL_SKIP_TO_FILE &&
-+ test $GIT_DIFF_PATH_COUNTER -eq $GIT_DIFF_PATH_TOTAL
++if test "$GIT_DIFF_PATH_COUNTER" -eq "$GIT_DIFF_PATH_TOTAL"
+then
-+ rm $GIT_DIFFTOOL_SKIP_TO_FILE
++ rm -f "$GIT_DIFFTOOL_LAST_POSITION"
+
+fi
exit 0
git-difftool--helper.sh | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
@@ -6,6 +6,8 @@# Copyright (c) 2009, 2010 David AguilarTOOL_MODE=diff+GIT_DIFFTOOL_LAST_POSITION="$GIT_DIR/difftool-last-position"+DIFFTOOL_FIRST_NUM="1" .git-mergetool--lib# difftool.prompt controls the default prompt/no-prompt behavior
@@ -40,6 +42,30 @@ launch_merge_tool () {# the user with the real $MERGED name before launching $merge_tool.ifshould_promptthen+iftest-f"$GIT_DIFFTOOL_LAST_POSITION"+then+ifSAVE_POINT_NUM=$(cat2>/dev/null"$GIT_DIFFTOOL_LAST_POSITION")&&+test"$SAVE_POINT_NUM"-le"$GIT_DIFF_PATH_TOTAL"&&+test"$SAVE_POINT_NUM"-gt"$GIT_DIFF_PATH_COUNTER"+then+iftest"$GIT_DIFF_PATH_COUNTER"-eq"$DIFFTOOL_FIRST_NUM"+then+printf"Do you want to start from the possible last file you were viewing? [Y/n]?"+readskip_ans||return+iftest"$skip_ans"=y+then+return+fi+else+return+fi+fi+fi+iftest-z"$SAVE_POINT_NUM"||+test"$SAVE_POINT_NUM"-ne"$GIT_DIFF_PATH_COUNTER"+then+echo"$GIT_DIFF_PATH_COUNTER">"$GIT_DIFFTOOL_LAST_POSITION"+fiprintf"\nViewing (%s/%s): '%s'\n""$GIT_DIFF_PATH_COUNTER"\"$GIT_DIFF_PATH_TOTAL""$MERGED"ifuse_ext_cmd
From: David Aguilar <hidden> Date: 2021-02-08 22:16:48
(cc'd Ryan since the thread involving him was mentioned in the commit message)
On Mon, Feb 8, 2021 at 9:02 AM ZheNing Hu via GitGitGadget
[off-list ref] wrote:
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
we want to see. Therefore, here is a new method: every time before
we view the file diff, the current coordinates will be stored in
`GIT_DIR/difftool-last-position`, this file will be deleted after
successful traversing. But if an unexpected exit occurred midway or
users similar to using "ctrl+c" kill the process,and the user wants
to redo the same `git difftoool`, git will view the coordinates in
the save point, ask user if they want continue from the last position.
This will improve the user experience.
Signed-off-by: ZheNing Hu <redacted>
---
git-difftool-helper.sh: learn a new way skip to save point
git user may should travel the diff list to choice file diff to view, if
they exit in midway,they must travel it again. By saving current
coordinates in GIT_DIR/difftool-last-position method, provides a
possibility for this user-friendly solution.
this patch's origin discuss is here:
https://lore.kernel.org/git/gOXOaoqn-E9A2ob7ykWEcDc7ZxmSwAjcP5CCFKfr5ejCOWZQ1lfAUZcbgYT9AyQCcDgJvCrnrtziXiels-Hxol3xlkGTVHk24SvAdaSUtKQ=@rtzoeller.com/
Thanks!
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/870
Range-diff vs v1:
1: e77c3e33ba85 ! 1: 2468eaff322b git-difftool-helper.sh: learn a new way skip to save point
@@ Metadata
Author: ZheNing Hu [off-list ref]
## Commit message ##
- git-difftool-helper.sh: learn a new way skip to save point
+ git-difftool-helper.sh: learn a new way go back to last save point
- `git difftool` only allow us to select file to view In turn.
- If there is a commit with many files and we exit in search,
+ `git difftool` only allow us to select file to view in turn.
+ If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
- we want to see.Therefore,here is a new method:every time before
- we view the file diff,the current coordinates will be stored in
- `GIT_DIR/difftool_skip_to`,this file will be deleted after
- successful traversing.But if an unexpected exit occurred midway,
- git will view the coordinates in the save point,ask user if they
- want continue from the last saved point.This will improve the
- user experience.
+ we want to see. Therefore, here is a new method: every time before
+ we view the file diff, the current coordinates will be stored in
+ `GIT_DIR/difftool-last-position`, this file will be deleted after
+ successful traversing. But if an unexpected exit occurred midway or
+ users similar to using "ctrl+c" kill the process,and the user wants
+ to redo the same `git difftoool`, git will view the coordinates in
+ the save point, ask user if they want continue from the last position.
+ This will improve the user experience.
Signed-off-by: ZheNing Hu [off-list ref]
@@ git-difftool--helper.sh
# Copyright (c) 2009, 2010 David Aguilar
TOOL_MODE=diff
-+GIT_DIFFTOOL_SKIP_TO_FILE="$GIT_DIR/difftool-skip-to"
++GIT_DIFFTOOL_LAST_POSITION="$GIT_DIR/difftool-last-position"
++DIFFTOOL_FIRST_NUM="1"
. git-mergetool--lib
# difftool.prompt controls the default prompt/no-prompt behavior
@@ git-difftool--helper.sh: launch_merge_tool () {
# the user with the real $MERGED name before launching $merge_tool.
if should_prompt
then
-+ if test -f "$GIT_DIFFTOOL_SKIP_TO_FILE"
++ if test -f "$GIT_DIFFTOOL_LAST_POSITION"
+ then
-+ SAVE_POINT_NUM=$(cat "$GIT_DIFFTOOL_SKIP_TO_FILE")
-+ if test $SAVE_POINT_NUM -le $GIT_DIFF_PATH_TOTAL &&
-+ test $SAVE_POINT_NUM -gt $GIT_DIFF_PATH_COUNTER
++ if SAVE_POINT_NUM=$(cat 2>/dev/null "$GIT_DIFFTOOL_LAST_POSITION") &&
++ test "$SAVE_POINT_NUM" -le "$GIT_DIFF_PATH_TOTAL" &&
++ test "$SAVE_POINT_NUM" -gt "$GIT_DIFF_PATH_COUNTER"
+ then
-+ # choice skip or not skip when check first file.
-+ if test $GIT_DIFF_PATH_COUNTER -eq "1"
++ if test "$GIT_DIFF_PATH_COUNTER" -eq "$DIFFTOOL_FIRST_NUM"
+ then
-+ printf "do you want to skip to last time difftool save point($SAVE_POINT_NUM) [Y/n]?"
++ printf "Do you want to start from the possible last file you were viewing? [Y/n]?"
+ read skip_ans || return
+ if test "$skip_ans" = y
+ then
@@ git-difftool--helper.sh: launch_merge_tool () {
+ fi
+ fi
+ fi
Similar to Junio's question about, "where does this possible come
from?", I wasn't able to make out the behavior in the following
situation.
What about when the user switches branches or specifies a pathspec on
the command-line or some other avenue that ends up with the number of
files to diff being very different than the last difftool invocation?
Will difftool, for example, skip over a smaller set of files on
invocation 2 if invocation 1 involved many files and we exited out
with a counter number that is very high?
One thing that's not too good about having state files in .git/ is
that they're global data and we also have to think about, "what if the
user has multiple difftools running?" and those kind of complexities.
I don't want this to seem like I'm trying to be dismissive of this
feature which does seem like a useful thing in general, so I'll try to
come up with an alternative interface that is slightly more general
but a admittedly a little bit more cumbersome because it's not as
automatic.
What if instead of global state, maybe the user could specify a path
that difftool could skip forward to? For example, we could teach
difftool to resume by telling it where we last left off:
git difftool --resume-from=foo/bar099.txt
Then we don't need the global counter state file?
Finally, I'm going to plug what I believe to be the right tool for the
job here. Have you tried git cola?[1] Difftool is tightly
integrated, and the UI is such that you can trivially choose any of
the modified/staged files and difftool them by using the Ctrl-d
hotkey.
https://github.com/git-cola/git-cola/
Cola is purpose-built for driving difftool, and for interactive
staging, so not mentioning it in the context of wanting a better UI
for difftool would be a disservice to difftool users.
--
David
David Aguilar [off-list ref] 于2021年2月9日周二 上午6:16写道:
(cc'd Ryan since the thread involving him was mentioned in the commit message)
On Mon, Feb 8, 2021 at 9:02 AM ZheNing Hu via GitGitGadget
[off-list ref] wrote:
quoted
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
we want to see. Therefore, here is a new method: every time before
we view the file diff, the current coordinates will be stored in
`GIT_DIR/difftool-last-position`, this file will be deleted after
successful traversing. But if an unexpected exit occurred midway or
users similar to using "ctrl+c" kill the process,and the user wants
to redo the same `git difftoool`, git will view the coordinates in
the save point, ask user if they want continue from the last position.
This will improve the user experience.
Signed-off-by: ZheNing Hu <redacted>
---
git-difftool-helper.sh: learn a new way skip to save point
git user may should travel the diff list to choice file diff to view, if
they exit in midway,they must travel it again. By saving current
coordinates in GIT_DIR/difftool-last-position method, provides a
possibility for this user-friendly solution.
this patch's origin discuss is here:
https://lore.kernel.org/git/gOXOaoqn-E9A2ob7ykWEcDc7ZxmSwAjcP5CCFKfr5ejCOWZQ1lfAUZcbgYT9AyQCcDgJvCrnrtziXiels-Hxol3xlkGTVHk24SvAdaSUtKQ=@rtzoeller.com/
Thanks!
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/870
Range-diff vs v1:
1: e77c3e33ba85 ! 1: 2468eaff322b git-difftool-helper.sh: learn a new way skip to save point
@@ Metadata
Author: ZheNing Hu [off-list ref]
## Commit message ##
- git-difftool-helper.sh: learn a new way skip to save point
+ git-difftool-helper.sh: learn a new way go back to last save point
- `git difftool` only allow us to select file to view In turn.
- If there is a commit with many files and we exit in search,
+ `git difftool` only allow us to select file to view in turn.
+ If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
- we want to see.Therefore,here is a new method:every time before
- we view the file diff,the current coordinates will be stored in
- `GIT_DIR/difftool_skip_to`,this file will be deleted after
- successful traversing.But if an unexpected exit occurred midway,
- git will view the coordinates in the save point,ask user if they
- want continue from the last saved point.This will improve the
- user experience.
+ we want to see. Therefore, here is a new method: every time before
+ we view the file diff, the current coordinates will be stored in
+ `GIT_DIR/difftool-last-position`, this file will be deleted after
+ successful traversing. But if an unexpected exit occurred midway or
+ users similar to using "ctrl+c" kill the process,and the user wants
+ to redo the same `git difftoool`, git will view the coordinates in
+ the save point, ask user if they want continue from the last position.
+ This will improve the user experience.
Signed-off-by: ZheNing Hu [off-list ref]
@@ git-difftool--helper.sh
# Copyright (c) 2009, 2010 David Aguilar
TOOL_MODE=diff
-+GIT_DIFFTOOL_SKIP_TO_FILE="$GIT_DIR/difftool-skip-to"
++GIT_DIFFTOOL_LAST_POSITION="$GIT_DIR/difftool-last-position"
++DIFFTOOL_FIRST_NUM="1"
. git-mergetool--lib
# difftool.prompt controls the default prompt/no-prompt behavior
@@ git-difftool--helper.sh: launch_merge_tool () {
# the user with the real $MERGED name before launching $merge_tool.
if should_prompt
then
-+ if test -f "$GIT_DIFFTOOL_SKIP_TO_FILE"
++ if test -f "$GIT_DIFFTOOL_LAST_POSITION"
+ then
-+ SAVE_POINT_NUM=$(cat "$GIT_DIFFTOOL_SKIP_TO_FILE")
-+ if test $SAVE_POINT_NUM -le $GIT_DIFF_PATH_TOTAL &&
-+ test $SAVE_POINT_NUM -gt $GIT_DIFF_PATH_COUNTER
++ if SAVE_POINT_NUM=$(cat 2>/dev/null "$GIT_DIFFTOOL_LAST_POSITION") &&
++ test "$SAVE_POINT_NUM" -le "$GIT_DIFF_PATH_TOTAL" &&
++ test "$SAVE_POINT_NUM" -gt "$GIT_DIFF_PATH_COUNTER"
+ then
-+ # choice skip or not skip when check first file.
-+ if test $GIT_DIFF_PATH_COUNTER -eq "1"
++ if test "$GIT_DIFF_PATH_COUNTER" -eq "$DIFFTOOL_FIRST_NUM"
+ then
-+ printf "do you want to skip to last time difftool save point($SAVE_POINT_NUM) [Y/n]?"
++ printf "Do you want to start from the possible last file you were viewing? [Y/n]?"
+ read skip_ans || return
+ if test "$skip_ans" = y
+ then
@@ git-difftool--helper.sh: launch_merge_tool () {
+ fi
+ fi
+ fi
Similar to Junio's question about, "where does this possible come
from?", I wasn't able to make out the behavior in the following
situation.
What about when the user switches branches or specifies a pathspec on
the command-line or some other avenue that ends up with the number of
files to diff being very different than the last difftool invocation?
Will difftool, for example, skip over a smaller set of files on
invocation 2 if invocation 1 involved many files and we exited out
with a counter number that is very high?
This is what I worry about.
One thing that's not too good about having state files in .git/ is
that they're global data and we also have to think about, "what if the
user has multiple difftools running?" and those kind of complexities.
I admit that I did not consider the situation where multiple `git difftool`
processes are going on at the same time.
I don't want this to seem like I'm trying to be dismissive of this
feature which does seem like a useful thing in general, so I'll try to
come up with an alternative interface that is slightly more general
but a admittedly a little bit more cumbersome because it's not as
automatic.
What if instead of global state, maybe the user could specify a path
that difftool could skip forward to? For example, we could teach
difftool to resume by telling it where we last left off:
git difftool --resume-from=foo/bar099.txt
Then we don't need the global counter state file?
Wonderful idea.But as Junio said, there may be no global state support,
`start-from` will be more applicable.
Finally, I'm going to plug what I believe to be the right tool for the
job here. Have you tried git cola?[1] Difftool is tightly
integrated, and the UI is such that you can trivially choose any of
the modified/staged files and difftool them by using the Ctrl-d
hotkey.
https://github.com/git-cola/git-cola/
Cola is purpose-built for driving difftool, and for interactive
staging, so not mentioning it in the context of wanting a better UI
for difftool would be a disservice to difftool users.
I saw the difftool UI of git-cola, and it is great to view the differences
by selecting files.I have been using vscode's git plugin before, and it
works well tool.
From: ZheNing Hu via GitGitGadget <hidden> Date: 2021-02-09 15:31:56
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
we want to see. Therefore, here is a new method: user can use
`git difftool --start-from=<filename>` to start viewing from
the specified file. This will improve the user experience.
At the same time, turn bit field constants into bit shift format
in `diff.h`.
Signed-off-by: ZheNing Hu <redacted>
---
difftool.c: learn a new way start at specified file
git user may should travel the diff list to choice file diff to view, if
they exit in midway,they must travel it again. By starting from the
specified file method, provides a possibility for this user-friendly
solution.
this patch's origin discuss is here:
https://lore.kernel.org/git/gOXOaoqn-E9A2ob7ykWEcDc7ZxmSwAjcP5CCFKfr5ejCOWZQ1lfAUZcbgYT9AyQCcDgJvCrnrtziXiels-Hxol3xlkGTVHk24SvAdaSUtKQ=@rtzoeller.com/
Maybe this patch is more like skip to in Junio's original thread than
the previous versions.
Thanks!
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/870
Range-diff vs v2:
1: 2468eaff322b < -: ------------ git-difftool-helper.sh: learn a new way go back to last save point
-: ------------ > 1: 29fc6b4bc08f difftool.c: learn a new way start from specified file
Documentation/git-difftool.txt | 3 +++
builtin/difftool.c | 7 ++++++-
diff.c | 9 +++++++++
diff.h | 20 ++++++++++----------
t/t7800-difftool.sh | 12 ++++++++++++
5 files changed, 40 insertions(+), 11 deletions(-)
@@ -34,6 +34,9 @@ OPTIONS This is the default behaviour; the option is provided to override any configuration settings.+--start-from::+ Start viewing diff from the specified file.+ -t <tool>:: --tool=<tool>:: Use the diff tool specified by <tool>. Valid values include
@@ -690,7 +690,7 @@ int cmd_difftool(int argc, const char **argv, const char *prefix){intuse_gui_tool=0,dir_diff=0,prompt=-1,symlinks=0,tool_help=0,no_index=0;-staticchar*difftool_cmd=NULL,*extcmd=NULL;+staticchar*difftool_cmd=NULL,*extcmd=NULL,*start_file=NULL;structoptionbuiltin_difftool_options[]={OPT_BOOL('g',"gui",&use_gui_tool,N_("use `diff.guitool` instead of `diff.tool`")),
@@ -714,6 +714,8 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)OPT_STRING('x',"extcmd",&extcmd,N_("command"),N_("specify a custom command for viewing diffs")),OPT_ARGUMENT("no-index",&no_index,N_("passed to `diff`")),+OPT_STRING(0,"start-from",&start_file,N_("start-from"),+N_("start viewing diff from the specified file")),OPT_END()};
From: ZheNing Hu via GitGitGadget <hidden> Date: 2021-02-14 13:10:14
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
we want to see. Therefore, here is a new method: user can use
`git difftool --start-from=<filename>` to start viewing from
the specified file, This will improve the user experience.
`difftool --start-from=<file>` will pass the file name to
`diffcore-rotate`, it will traverse all files in diff_queue,
if it finds a matching file, it will rearrange the order of
diff_filepair of diff_queue, Rotate the file specified by the
user to the first one. If the file name specified by the user
does not match any item in the diff queue, Git will also rotate
the queue, it will find the the first file name larger than the
specified file name as the first element of the new diff_queue.
This will help users find their mistakes.
Signed-off-by: ZheNing Hu <redacted>
---
difftool.c: learn a new way start at specified file
git user may should travel the diff list to choice file diff to view, if
they exit in midway,they must travel it again. By starting from the
specified file method, provides a possibility for this user-friendly
solution.
this patch's origin discuss is here:
https://lore.kernel.org/git/gOXOaoqn-E9A2ob7ykWEcDc7ZxmSwAjcP5CCFKfr5ejCOWZQ1lfAUZcbgYT9AyQCcDgJvCrnrtziXiels-Hxol3xlkGTVHk24SvAdaSUtKQ=@rtzoeller.com/
Maybe this patch is more like skip to in Junio's original thread than
the previous versions.
Thanks!
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/870
Range-diff vs v3:
1: 29fc6b4bc08f ! 1: 3accfb942301 difftool.c: learn a new way start from specified file
@@ Metadata
Author: ZheNing Hu [off-list ref]
## Commit message ##
- difftool.c: learn a new way start from specified file
+ difftool.c: learn a new way start at specified file
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
we want to see. Therefore, here is a new method: user can use
`git difftool --start-from=<filename>` to start viewing from
- the specified file. This will improve the user experience.
- At the same time, turn bit field constants into bit shift format
- in `diff.h`.
+ the specified file, This will improve the user experience.
+
+ `difftool --start-from=<file>` will pass the file name to
+ `diffcore-rotate`, it will traverse all files in diff_queue,
+ if it finds a matching file, it will rearrange the order of
+ diff_filepair of diff_queue, Rotate the file specified by the
+ user to the first one. If the file name specified by the user
+ does not match any item in the diff queue, Git will also rotate
+ the queue, it will find the the first file name larger than the
+ specified file name as the first element of the new diff_queue.
+ This will help users find their mistakes.
Signed-off-by: ZheNing Hu [off-list ref]
@@ Documentation/git-difftool.txt: OPTIONS
This is the default behaviour; the option is provided to
override any configuration settings.
-+--start-from::
++--start-from=<file>::
+ Start viewing diff from the specified file.
+
-t <tool>::
--tool=<tool>::
Use the diff tool specified by <tool>. Valid values include
- ## builtin/difftool.c ##
-@@ builtin/difftool.c: int cmd_difftool(int argc, const char **argv, const char *prefix)
- {
- int use_gui_tool = 0, dir_diff = 0, prompt = -1, symlinks = 0,
- tool_help = 0, no_index = 0;
-- static char *difftool_cmd = NULL, *extcmd = NULL;
-+ static char *difftool_cmd = NULL, *extcmd = NULL, *start_file = NULL;
- struct option builtin_difftool_options[] = {
- OPT_BOOL('g', "gui", &use_gui_tool,
- N_("use `diff.guitool` instead of `diff.tool`")),
-@@ builtin/difftool.c: int cmd_difftool(int argc, const char **argv, const char *prefix)
- OPT_STRING('x', "extcmd", &extcmd, N_("command"),
- N_("specify a custom command for viewing diffs")),
- OPT_ARGUMENT("no-index", &no_index, N_("passed to `diff`")),
-+ OPT_STRING(0, "start-from", &start_file, N_("start-from"),
-+ N_("start viewing diff from the specified file")),
- OPT_END()
- };
-
-@@ builtin/difftool.c: int cmd_difftool(int argc, const char **argv, const char *prefix)
- builtin_difftool_usage, PARSE_OPT_KEEP_UNKNOWN |
- PARSE_OPT_KEEP_DASHDASH);
-
-+ if (start_file)
-+ setenv("START_FILE", start_file, 1);
-+
- if (tool_help)
- return print_tool_help();
-
+ ## Makefile ##
+@@ Makefile: LIB_OBJS += diffcore-delta.o
+ LIB_OBJS += diffcore-order.o
+ LIB_OBJS += diffcore-pickaxe.o
+ LIB_OBJS += diffcore-rename.o
++LIB_OBJS += diffcore-rotate.o
+ LIB_OBJS += dir-iterator.o
+ LIB_OBJS += dir.o
+ LIB_OBJS += editor.o
## diff.c ##
-@@ diff.c: static void run_external_diff(const char *pgm,
- const char *xfrm_msg,
- struct diff_options *o)
- {
-+ const char *start_file = NULL;
- struct strvec argv = STRVEC_INIT;
- struct strvec env = STRVEC_INIT;
- struct diff_queue_struct *q = &diff_queued_diff;
-@@ diff.c: static void run_external_diff(const char *pgm,
-
- diff_free_filespec_data(one);
- diff_free_filespec_data(two);
-+
-+ start_file = xstrdup_or_null(getenv("START_FILE"));
-+ if (start_file) {
-+ if (strcmp(start_file, name))
-+ goto finish;
-+ unsetenv("START_FILE");
-+ }
- if (run_command_v_opt_cd_env(argv.v, RUN_USING_SHELL, NULL, env.v))
- die(_("external diff died, stopping at %s"), name);
-
-+finish:
- remove_tempfile();
- strvec_clear(&argv);
- strvec_clear(&env);
+@@ diff.c: static void prep_parse_options(struct diff_options *options)
+ DIFF_PICKAXE_REGEX, PARSE_OPT_NONEG),
+ OPT_FILENAME('O', NULL, &options->orderfile,
+ N_("control the order in which files appear in the output")),
++ OPT_STRING(0, "rotate-to", &options->rotate_to, N_("<path>"),
++ N_("show the change in the specified path first")),
++ OPT_STRING(0, "start-from", &options->rotate_to, N_("<path>"),
++ N_("pass from difftool to diff, has the same effort as `rotate-to`")),
+ OPT_CALLBACK_F(0, "find-object", options, N_("<object-id>"),
+ N_("look for differences that change the number of occurrences of the specified object"),
+ PARSE_OPT_NONEG, diff_opt_find_object),
+@@ diff.c: void diffcore_std(struct diff_options *options)
+ diffcore_pickaxe(options);
+ if (options->orderfile)
+ diffcore_order(options->orderfile);
++ if (options->rotate_to)
++ diffcore_rotate(options->rotate_to);
+ if (!options->found_follow)
+ /* See try_to_follow_renames() in tree-diff.c */
+ diff_resolve_rename_copy();
## diff.h ##
-@@ diff.h: typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
-
- typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data);
-
--#define DIFF_FORMAT_RAW 0x0001
--#define DIFF_FORMAT_DIFFSTAT 0x0002
--#define DIFF_FORMAT_NUMSTAT 0x0004
--#define DIFF_FORMAT_SUMMARY 0x0008
--#define DIFF_FORMAT_PATCH 0x0010
--#define DIFF_FORMAT_SHORTSTAT 0x0020
--#define DIFF_FORMAT_DIRSTAT 0x0040
-+#define DIFF_FORMAT_RAW (1U<<0)
-+#define DIFF_FORMAT_DIFFSTAT (1U<<1)
-+#define DIFF_FORMAT_NUMSTAT (1U<<2)
-+#define DIFF_FORMAT_SUMMARY (1U<<3)
-+#define DIFF_FORMAT_PATCH (1U<<4)
-+#define DIFF_FORMAT_SHORTSTAT (1U<<5)
-+#define DIFF_FORMAT_DIRSTAT (1U<<6)
+@@ diff.h: enum diff_submodule_format {
+ */
+ struct diff_options {
+ const char *orderfile;
++ const char *rotate_to;
- /* These override all above */
--#define DIFF_FORMAT_NAME 0x0100
--#define DIFF_FORMAT_NAME_STATUS 0x0200
--#define DIFF_FORMAT_CHECKDIFF 0x0400
-+#define DIFF_FORMAT_NAME (1U<<8)
-+#define DIFF_FORMAT_NAME_STATUS (1U<<9)
-+#define DIFF_FORMAT_CHECKDIFF (1U<<10)
+ /**
+ * A constant string (can and typically does contain newlines to look for
+
+ ## diffcore-rotate.c (new) ##
+@@
++/*
++ * Copyright (C) 2021, Google LLC.
++ * Based on diffcore-order.c, which is Copyright (C) 2005, Junio C Hamano
++ */
++#include "cache.h"
++#include "diff.h"
++#include "diffcore.h"
++
++void diffcore_rotate(const char *rotate_to_filename)
++{
++ struct diff_queue_struct *q = &diff_queued_diff;
++ struct diff_queue_struct outq;
++ int rotate_to, i;
++
++ if (!q->nr)
++ return;
++
++ for (i = 0; i < q->nr; i++)
++ if (strcmp(rotate_to_filename, q->queue[i]->two->path) <= 0)
++ break;
++ /* we did not find the specified path */
++ if (q->nr <= i)
++ return;
++
++ DIFF_QUEUE_CLEAR(&outq);
++ rotate_to = i;
++
++ for (i = rotate_to; i < q->nr; i++)
++ diff_q(&outq, q->queue[i]);
++ for (i = 0; i < rotate_to; i++)
++ diff_q(&outq, q->queue[i]);
++
++ free(q->queue);
++ *q = outq;
++}
+
+ ## diffcore.h ##
+@@ diffcore.h: void diffcore_rename(struct diff_options *);
+ void diffcore_merge_broken(void);
+ void diffcore_pickaxe(struct diff_options *);
+ void diffcore_order(const char *orderfile);
++void diffcore_rotate(const char *rotate_to_filename);
- /* Same as output_format = 0 but we know that -s flag was given
- * and we should not give default value to output_format.
+ /* low-level interface to diffcore_order */
+ struct obj_order {
## t/t7800-difftool.sh ##
@@ t/t7800-difftool.sh: test_expect_success 'difftool --gui, --tool and --extcmd are mutually exclusive'
@@ t/t7800-difftool.sh: test_expect_success 'difftool --gui, --tool and --extcmd ar
+ test_when_finished git reset --hard &&
+ echo 1 >1 &&
+ echo 2 >2 &&
-+ echo 3 >3 &&
-+ git add 1 2 3 &&
-+ git commit -a -m "123" &&
-+ git difftool --start-from="2" HEAD^ 2>&1 >output &&
-+ test_line_count = 4 output
++ echo 4 >4 &&
++ git add 1 2 4 &&
++ git commit -a -m "124" &&
++ git difftool --no-prompt --extcmd=cat --start-from="2" HEAD^ >output &&
++ cat >expect <<-\EOF &&
++ 2
++ 4
++ 1
++ EOF
++ test_cmp output expect &&
++ git difftool --no-prompt --extcmd=cat --start-from="3" HEAD^ >output &&
++ cat >expect <<-\EOF &&
++ 4
++ 1
++ 2
++ EOF
++ test_cmp output expect
+'
-+
test_done
Documentation/git-difftool.txt | 3 +++
Makefile | 1 +
diff.c | 6 ++++++
diff.h | 1 +
diffcore-rotate.c | 35 ++++++++++++++++++++++++++++++++++
diffcore.h | 1 +
t/t7800-difftool.sh | 23 ++++++++++++++++++++++
7 files changed, 70 insertions(+)
create mode 100644 diffcore-rotate.c
@@ -34,6 +34,9 @@ OPTIONS This is the default behaviour; the option is provided to override any configuration settings.+--start-from=<file>::+ Start viewing diff from the specified file.+ -t <tool>:: --tool=<tool>:: Use the diff tool specified by <tool>. Valid values include
@@ -5599,6 +5599,10 @@ static void prep_parse_options(struct diff_options *options)DIFF_PICKAXE_REGEX,PARSE_OPT_NONEG),OPT_FILENAME('O',NULL,&options->orderfile,N_("control the order in which files appear in the output")),+OPT_STRING(0,"rotate-to",&options->rotate_to,N_("<path>"),+N_("show the change in the specified path first")),+OPT_STRING(0,"start-from",&options->rotate_to,N_("<path>"),+N_("pass from difftool to diff, has the same effort as `rotate-to`")),OPT_CALLBACK_F(0,"find-object",options,N_("<object-id>"),N_("look for differences that change the number of occurrences of the specified object"),PARSE_OPT_NONEG,diff_opt_find_object),
@@ -6669,6 +6673,8 @@ void diffcore_std(struct diff_options *options)diffcore_pickaxe(options);if(options->orderfile)diffcore_order(options->orderfile);+if(options->rotate_to)+diffcore_rotate(options->rotate_to);if(!options->found_follow)/* See try_to_follow_renames() in tree-diff.c */diff_resolve_rename_copy();
@@ -0,0 +1,35 @@+/*+*Copyright(C)2021,GoogleLLC.+*Basedondiffcore-order.c,whichisCopyright(C)2005,JunioCHamano+*/+#include"cache.h"+#include"diff.h"+#include"diffcore.h"++voiddiffcore_rotate(constchar*rotate_to_filename)+{+structdiff_queue_struct*q=&diff_queued_diff;+structdiff_queue_structoutq;+introtate_to,i;++if(!q->nr)+return;++for(i=0;i<q->nr;i++)+if(strcmp(rotate_to_filename,q->queue[i]->two->path)<=0)+break;+/* we did not find the specified path */+if(q->nr<=i)+return;++DIFF_QUEUE_CLEAR(&outq);+rotate_to=i;++for(i=rotate_to;i<q->nr;i++)+diff_q(&outq,q->queue[i]);+for(i=0;i<rotate_to;i++)+diff_q(&outq,q->queue[i]);++free(q->queue);+*q=outq;+}
From: ZheNing Hu via GitGitGadget <hidden> Date: 2021-02-16 12:57:25
git user may should travel the diff list to choice file diff to view, if
they exit in midway,they must travel it again. By starting from the
specified file method, provides a possibility for this user-friendly
solution.
this patch's origin discuss is here:
https://lore.kernel.org/git/gOXOaoqn-E9A2ob7ykWEcDc7ZxmSwAjcP5CCFKfr5ejCOWZQ1lfAUZcbgYT9AyQCcDgJvCrnrtziXiels-Hxol3xlkGTVHk24SvAdaSUtKQ=@rtzoeller.com/
Thanks!
Junio C Hamano (1):
diff: --{rotate,skip}-to=<path>
ZheNing Hu (1):
difftool.c: learn a new way start at specified file
Documentation/diff-options.txt | 8 ++++
Documentation/git-difftool.txt | 10 +++++
Documentation/gitdiffcore.txt | 21 ++++++++++
Makefile | 1 +
builtin/diff-files.c | 1 +
builtin/diff-index.c | 2 +
builtin/diff-tree.c | 3 ++
builtin/diff.c | 1 +
diff.c | 21 ++++++++++
diff.h | 21 ++++++++++
diffcore-rotate.c | 46 ++++++++++++++++++++++
diffcore.h | 1 +
t/t4056-diff-order.sh | 72 +++++++++++++++++++++++++++++++++-
t/t7800-difftool.sh | 30 ++++++++++++++
14 files changed, 237 insertions(+), 1 deletion(-)
create mode 100644 diffcore-rotate.c
base-commit: c6102b758572c7515f606b2423dfe38934fe6764
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v5
Pull-Request: https://github.com/gitgitgadget/git/pull/870
Range-diff vs v4:
1: 3accfb942301 ! 1: fb4bfd0f8b16 difftool.c: learn a new way start at specified file
@@
## Metadata ##
-Author: ZheNing Hu [off-list ref]
+Author: Junio C Hamano [off-list ref]
## Commit message ##
- difftool.c: learn a new way start at specified file
-
- `git difftool` only allow us to select file to view in turn.
- If there is a commit with many files and we exit in the search,
- We will have to traverse list again to get the file diff which
- we want to see. Therefore, here is a new method: user can use
- `git difftool --start-from=<filename>` to start viewing from
- the specified file, This will improve the user experience.
-
- `difftool --start-from=<file>` will pass the file name to
- `diffcore-rotate`, it will traverse all files in diff_queue,
- if it finds a matching file, it will rearrange the order of
- diff_filepair of diff_queue, Rotate the file specified by the
- user to the first one. If the file name specified by the user
- does not match any item in the diff queue, Git will also rotate
- the queue, it will find the the first file name larger than the
- specified file name as the first element of the new diff_queue.
- This will help users find their mistakes.
-
- Signed-off-by: ZheNing Hu [off-list ref]
-
- ## Documentation/git-difftool.txt ##
-@@ Documentation/git-difftool.txt: OPTIONS
- This is the default behaviour; the option is provided to
- override any configuration settings.
-
-+--start-from=<file>::
-+ Start viewing diff from the specified file.
-+
- -t <tool>::
- --tool=<tool>::
- Use the diff tool specified by <tool>. Valid values include
+ diff: --{rotate,skip}-to=<path>
+
+ In the implementation of "git difftool", there is a case where the
+ user wants to start viewing the diffs at a specific path and
+ continue on to the rest, optionally wrapping around to the
+ beginning. Since it is somewhat cumbersome to implement such a
+ feature as a post-processing step of "git diff" output, let's
+ support it internally with two new options.
+
+ - "git diff --rotate-to=C", when the resulting patch would show
+ paths A B C D E without the option, would "rotate" the paths to
+ shows patch to C D E A B instead. It is an error when there is
+ no patch for C is shown.
+
+ - "git diff --skip-to=C" would instead "skip" the paths before C,
+ and shows patch to C D E. Again, it is an error when there is no
+ patch for C is shown.
+
+ - "git log [-p]" also accepts these two options, but it is not an
+ error if there is no change to the specified path. Instead, the
+ set of output paths are rotated or skipped to the specified path
+ or the first path that sorts after the specified path.
+
+ Signed-off-by: Junio C Hamano [off-list ref]
+
+ ## Documentation/diff-options.txt ##
+@@ Documentation/diff-options.txt: matches a pattern if removing any number of the final pathname
+ components matches the pattern. For example, the pattern "`foo*bar`"
+ matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`".
+
++--skip-to=<file>::
++--rotate-to=<file::
++ Discard the files before the named <file> from the output
++ (i.e. 'skip to'), or move them to the end of the output
++ (i.e. 'rotate to'). These were invented primarily for use
++ of the `git difftool` command, and may not be very useful
++ otherwise.
++
+ ifndef::git-format-patch[]
+ -R::
+ Swap two inputs; that is, show differences from index or
+
+ ## Documentation/gitdiffcore.txt ##
+@@ Documentation/gitdiffcore.txt: into another list. There are currently 5 such transformations:
+ - diffcore-merge-broken
+ - diffcore-pickaxe
+ - diffcore-order
++- diffcore-rotate
+
+ These are applied in sequence. The set of filepairs 'git diff-{asterisk}'
+ commands find are used as the input to diffcore-break, and
+@@ Documentation/gitdiffcore.txt: Documentation
+ t
+ ------------------------------------------------
+
++diffcore-rotate: For Changing At Which Path Output Starts
++---------------------------------------------------------
++
++This transformation takes one pathname, and rotates the set of
++filepairs so that the filepair for the given pathname comes first,
++optionally discarding the paths that come before it. This is used
++to implement the `--skip-to` and the `--rotate-to` options. It is
++an error when the specified pathname is not in the set of filepairs,
++but it is not useful to error out when used with "git log" family of
++commands, because it is unreasonable to expect that a given path
++would be modified by each and every commit shown by the "git log"
++command. For this reason, when used with "git log", the filepair
++that sorts the same as, or the first one that sorts after, the given
++pathname is where the output starts.
++
++Use of this transformation combined with diffcore-order will produce
++unexpected results, as the input to this transformation is likely
++not sorted when diffcore-order is in effect.
++
++
+ SEE ALSO
+ --------
+ linkgit:git-diff[1],
## Makefile ##
@@ Makefile: LIB_OBJS += diffcore-delta.o
@@ Makefile: LIB_OBJS += diffcore-delta.o
LIB_OBJS += dir.o
LIB_OBJS += editor.o
+ ## builtin/diff-files.c ##
+@@ builtin/diff-files.c: int cmd_diff_files(int argc, const char **argv, const char *prefix)
+ }
+ if (!rev.diffopt.output_format)
+ rev.diffopt.output_format = DIFF_FORMAT_RAW;
++ rev.diffopt.rotate_to_strict = 1;
+
+ /*
+ * Make sure there are NO revision (i.e. pending object) parameter,
+
+ ## builtin/diff-index.c ##
+@@ builtin/diff-index.c: int cmd_diff_index(int argc, const char **argv, const char *prefix)
+ if (!rev.diffopt.output_format)
+ rev.diffopt.output_format = DIFF_FORMAT_RAW;
+
++ rev.diffopt.rotate_to_strict = 1;
++
+ /*
+ * Make sure there is one revision (i.e. pending object),
+ * and there is no revision filtering parameters.
+
+ ## builtin/diff-tree.c ##
+@@ builtin/diff-tree.c: int cmd_diff_tree(int argc, const char **argv, const char *prefix)
+ if (merge_base && opt->pending.nr != 2)
+ die(_("--merge-base only works with two commits"));
+
++ opt->diffopt.rotate_to_strict = 1;
++
+ /*
+ * NOTE! We expect "a..b" to expand to "^a b" but it is
+ * perfectly valid for revision range parser to yield "b ^a",
+@@ builtin/diff-tree.c: int cmd_diff_tree(int argc, const char **argv, const char *prefix)
+ int saved_nrl = 0;
+ int saved_dcctc = 0;
+
++ opt->diffopt.rotate_to_strict = 0;
+ if (opt->diffopt.detect_rename) {
+ if (!the_index.cache)
+ repo_read_index(the_repository);
+
+ ## builtin/diff.c ##
+@@ builtin/diff.c: int cmd_diff(int argc, const char **argv, const char *prefix)
+ }
+
+ rev.diffopt.flags.recursive = 1;
++ rev.diffopt.rotate_to_strict = 1;
+
+ setup_diff_pager(&rev.diffopt);
+
+
## diff.c ##
+@@ diff.c: static int diff_opt_word_diff_regex(const struct option *opt,
+ return 0;
+ }
+
++static int diff_opt_rotate_to(const struct option *opt, const char *arg, int unset)
++{
++ struct diff_options *options = opt->value;
++
++ BUG_ON_OPT_NEG(unset);
++ if (!strcmp(opt->long_name, "skip-to"))
++ options->skip_instead_of_rotate = 1;
++ else
++ options->skip_instead_of_rotate = 0;
++ options->rotate_to = arg;
++ return 0;
++}
++
+ static void prep_parse_options(struct diff_options *options)
+ {
+ struct option parseopts[] = {
@@ diff.c: static void prep_parse_options(struct diff_options *options)
DIFF_PICKAXE_REGEX, PARSE_OPT_NONEG),
OPT_FILENAME('O', NULL, &options->orderfile,
N_("control the order in which files appear in the output")),
-+ OPT_STRING(0, "rotate-to", &options->rotate_to, N_("<path>"),
-+ N_("show the change in the specified path first")),
-+ OPT_STRING(0, "start-from", &options->rotate_to, N_("<path>"),
-+ N_("pass from difftool to diff, has the same effort as `rotate-to`")),
++ OPT_CALLBACK_F(0, "rotate-to", options, N_("<path>"),
++ N_("show the change in the specified path first"),
++ PARSE_OPT_NONEG, diff_opt_rotate_to),
++ OPT_CALLBACK_F(0, "skip-to", options, N_("<path>"),
++ N_("skip the output to the specified path"),
++ PARSE_OPT_NONEG, diff_opt_rotate_to),
OPT_CALLBACK_F(0, "find-object", options, N_("<object-id>"),
N_("look for differences that change the number of occurrences of the specified object"),
PARSE_OPT_NONEG, diff_opt_find_object),
@@ diff.c: void diffcore_std(struct diff_options *options)
if (options->orderfile)
diffcore_order(options->orderfile);
+ if (options->rotate_to)
-+ diffcore_rotate(options->rotate_to);
++ diffcore_rotate(options);
if (!options->found_follow)
/* See try_to_follow_renames() in tree-diff.c */
diff_resolve_rename_copy();
## diff.h ##
@@ diff.h: enum diff_submodule_format {
- */
struct diff_options {
const char *orderfile;
-+ const char *rotate_to;
++ /*
++ * "--rotate-to=<file>" would start showing at <file> and when
++ * the output reaches the end, wrap around by default.
++ * Setting skip_instead_of_rotate to true stops the output at the
++ * end, effectively discarding the earlier part of the output
++ * before <file>'s diff (this is used to implement the
++ * "--skip-to=<file>" option).
++ *
++ * When rotate_to_strict is set, it is an error if there is no
++ * <file> in the diff. Otherwise, the output starts at the
++ * path that is the same as, or first path that sorts after,
++ * <file>. Because it is unreasonable to require the exact
++ * match for "git log -p --rotate-to=<file>" (i.e. not all
++ * commit would touch that single <file>), "git log" sets it
++ * to false. "git diff" sets it to true to detect an error
++ * in the command line option.
++ */
++ const char *rotate_to;
++ int skip_instead_of_rotate;
++ int rotate_to_strict;
++
/**
* A constant string (can and typically does contain newlines to look for
+ * a block of text, not just a single line) to filter out the filepairs
## diffcore-rotate.c (new) ##
@@
@@ diffcore-rotate.c (new)
+#include "diff.h"
+#include "diffcore.h"
+
-+void diffcore_rotate(const char *rotate_to_filename)
++void diffcore_rotate(struct diff_options *opt)
+{
+ struct diff_queue_struct *q = &diff_queued_diff;
+ struct diff_queue_struct outq;
@@ diffcore-rotate.c (new)
+ if (!q->nr)
+ return;
+
-+ for (i = 0; i < q->nr; i++)
-+ if (strcmp(rotate_to_filename, q->queue[i]->two->path) <= 0)
-+ break;
-+ /* we did not find the specified path */
-+ if (q->nr <= i)
++ for (i = 0; i < q->nr; i++) {
++ int cmp = strcmp(opt->rotate_to, q->queue[i]->two->path);
++ if (!cmp)
++ break; /* exact match */
++ if (!opt->rotate_to_strict && cmp < 0)
++ break; /* q->queue[i] is now past the target pathname */
++ }
++
++ if (q->nr <= i) {
++ /* we did not find the specified path */
++ if (opt->rotate_to_strict)
++ die(_("No such path '%s' in the diff"), opt->rotate_to);
+ return;
++ }
+
+ DIFF_QUEUE_CLEAR(&outq);
+ rotate_to = i;
+
+ for (i = rotate_to; i < q->nr; i++)
+ diff_q(&outq, q->queue[i]);
-+ for (i = 0; i < rotate_to; i++)
-+ diff_q(&outq, q->queue[i]);
-+
++ for (i = 0; i < rotate_to; i++) {
++ if (opt->skip_instead_of_rotate)
++ diff_free_filepair(q->queue[i]);
++ else
++ diff_q(&outq, q->queue[i]);
++ }
+ free(q->queue);
+ *q = outq;
+}
@@ diffcore.h: void diffcore_rename(struct diff_options *);
void diffcore_merge_broken(void);
void diffcore_pickaxe(struct diff_options *);
void diffcore_order(const char *orderfile);
-+void diffcore_rotate(const char *rotate_to_filename);
++void diffcore_rotate(struct diff_options *);
/* low-level interface to diffcore_order */
struct obj_order {
- ## t/t7800-difftool.sh ##
-@@ t/t7800-difftool.sh: test_expect_success 'difftool --gui, --tool and --extcmd are mutually exclusive'
- test_must_fail git difftool --gui --tool=test-tool --extcmd=cat
- '
-
-+test_expect_success 'difftool --start-from' '
-+ difftool_test_setup &&
-+ test_when_finished git reset --hard &&
-+ echo 1 >1 &&
-+ echo 2 >2 &&
-+ echo 4 >4 &&
-+ git add 1 2 4 &&
-+ git commit -a -m "124" &&
-+ git difftool --no-prompt --extcmd=cat --start-from="2" HEAD^ >output &&
+ ## t/t4056-diff-order.sh ##
+@@
+ #!/bin/sh
+
+-test_description='diff order'
++test_description='diff order & rotate'
+
+ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+@@ t/t4056-diff-order.sh: do
+ '
+ done
+
++### rotate and skip
++
++test_expect_success 'rotate and skip setup' '
++ >sample1.t &&
++ >sample2.t &&
++ >sample3.t &&
++ >sample4.t &&
++ git add sample[1234].t &&
++ git commit -m "added" sample[1234].t &&
++ echo modified >>sample1.t &&
++ echo modified >>sample2.t &&
++ echo modified >>sample4.t &&
++ git commit -m "updated" sample[1234].t
++'
++
++test_expect_success 'diff --rotate-to' '
++ git diff --rotate-to=sample2.t --name-only HEAD^ >actual &&
++ test_write_lines sample2.t sample4.t sample1.t >expect &&
++ test_cmp expect actual
++'
++
++test_expect_success 'diff --skip-to' '
++ git diff --skip-to=sample2.t --name-only HEAD^ >actual &&
++ test_write_lines sample2.t sample4.t >expect &&
++ test_cmp expect actual
++'
++
++test_expect_success 'diff --rotate/skip-to error condition' '
++ test_must_fail git diff --rotate-to=sample3.t HEAD^ &&
++ test_must_fail git diff --skip-to=sample3.t HEAD^
++'
++
++test_expect_success 'log --rotate-to' '
++ git log --rotate-to=sample3.t --raw HEAD~2.. >raw &&
++ # just distill the commit header and paths
++ sed -n -e "s/^commit.*/commit/p" \
++ -e "/^:/s/^.* //p" raw >actual &&
++
+ cat >expect <<-\EOF &&
-+ 2
-+ 4
-+ 1
++ commit
++ sample4.t
++ sample1.t
++ sample2.t
++ commit
++ sample3.t
++ sample4.t
++ sample1.t
++ sample2.t
+ EOF
-+ test_cmp output expect &&
-+ git difftool --no-prompt --extcmd=cat --start-from="3" HEAD^ >output &&
++
++ test_cmp expect actual
++'
++
++test_expect_success 'log --skip-to' '
++ git log --skip-to=sample3.t --raw HEAD~2.. >raw &&
++ # just distill the commit header and paths
++ sed -n -e "s/^commit.*/commit/p" \
++ -e "/^:/s/^.* //p" raw >actual &&
++
+ cat >expect <<-\EOF &&
-+ 4
-+ 1
-+ 2
++ commit
++ sample4.t
++ commit
++ sample3.t
++ sample4.t
+ EOF
-+ test_cmp output expect
++
++ test_cmp expect actual
+'
++
test_done
-: ------------ > 2: 98e2707ee2fa difftool.c: learn a new way start at specified file
--
gitgitgadget
From: Junio C Hamano via GitGitGadget <hidden> Date: 2021-02-16 12:57:37
From: Junio C Hamano <redacted>
In the implementation of "git difftool", there is a case where the
user wants to start viewing the diffs at a specific path and
continue on to the rest, optionally wrapping around to the
beginning. Since it is somewhat cumbersome to implement such a
feature as a post-processing step of "git diff" output, let's
support it internally with two new options.
- "git diff --rotate-to=C", when the resulting patch would show
paths A B C D E without the option, would "rotate" the paths to
shows patch to C D E A B instead. It is an error when there is
no patch for C is shown.
- "git diff --skip-to=C" would instead "skip" the paths before C,
and shows patch to C D E. Again, it is an error when there is no
patch for C is shown.
- "git log [-p]" also accepts these two options, but it is not an
error if there is no change to the specified path. Instead, the
set of output paths are rotated or skipped to the specified path
or the first path that sorts after the specified path.
Signed-off-by: Junio C Hamano <redacted>
---
Documentation/diff-options.txt | 8 ++++
Documentation/gitdiffcore.txt | 21 ++++++++++
Makefile | 1 +
builtin/diff-files.c | 1 +
builtin/diff-index.c | 2 +
builtin/diff-tree.c | 3 ++
builtin/diff.c | 1 +
diff.c | 21 ++++++++++
diff.h | 21 ++++++++++
diffcore-rotate.c | 46 ++++++++++++++++++++++
diffcore.h | 1 +
t/t4056-diff-order.sh | 72 +++++++++++++++++++++++++++++++++-
12 files changed, 197 insertions(+), 1 deletion(-)
create mode 100644 diffcore-rotate.c
@@ -700,6 +700,14 @@ matches a pattern if removing any number of the final pathname components matches the pattern. For example, the pattern "`foo*bar`" matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`".+--skip-to=<file>::+--rotate-to=<file::+ Discard the files before the named <file> from the output+ (i.e. 'skip to'), or move them to the end of the output+ (i.e. 'rotate to'). These were invented primarily for use+ of the `git difftool` command, and may not be very useful+ otherwise.+ ifndef::git-format-patch[] -R:: Swap two inputs; that is, show differences from index or
@@ -74,6 +74,7 @@ into another list. There are currently 5 such transformations: - diffcore-merge-broken - diffcore-pickaxe - diffcore-order+- diffcore-rotate These are applied in sequence. The set of filepairs 'git diff-{asterisk}' commands find are used as the input to diffcore-break, and
@@ -276,6 +277,26 @@ Documentation t ------------------------------------------------+diffcore-rotate: For Changing At Which Path Output Starts+---------------------------------------------------------++This transformation takes one pathname, and rotates the set of+filepairs so that the filepair for the given pathname comes first,+optionally discarding the paths that come before it. This is used+to implement the `--skip-to` and the `--rotate-to` options. It is+an error when the specified pathname is not in the set of filepairs,+but it is not useful to error out when used with "git log" family of+commands, because it is unreasonable to expect that a given path+would be modified by each and every commit shown by the "git log"+command. For this reason, when used with "git log", the filepair+that sorts the same as, or the first one that sorts after, the given+pathname is where the output starts.++Use of this transformation combined with diffcore-order will produce+unexpected results, as the input to this transformation is likely+not sorted when diffcore-order is in effect.++ SEE ALSO -------- linkgit:git-diff[1],
@@ -156,6 +156,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)if(merge_base&&opt->pending.nr!=2)die(_("--merge-base only works with two commits"));+opt->diffopt.rotate_to_strict=1;+/**NOTE!Weexpect"a..b"toexpandto"^a b"butitis*perfectlyvalidforrevisionrangeparsertoyield"b ^a",
@@ -5348,6 +5348,19 @@ static int diff_opt_word_diff_regex(const struct option *opt,return0;}+staticintdiff_opt_rotate_to(conststructoption*opt,constchar*arg,intunset)+{+structdiff_options*options=opt->value;++BUG_ON_OPT_NEG(unset);+if(!strcmp(opt->long_name,"skip-to"))+options->skip_instead_of_rotate=1;+else+options->skip_instead_of_rotate=0;+options->rotate_to=arg;+return0;+}+staticvoidprep_parse_options(structdiff_options*options){structoptionparseopts[]={
@@ -5599,6 +5612,12 @@ static void prep_parse_options(struct diff_options *options)DIFF_PICKAXE_REGEX,PARSE_OPT_NONEG),OPT_FILENAME('O',NULL,&options->orderfile,N_("control the order in which files appear in the output")),+OPT_CALLBACK_F(0,"rotate-to",options,N_("<path>"),+N_("show the change in the specified path first"),+PARSE_OPT_NONEG,diff_opt_rotate_to),+OPT_CALLBACK_F(0,"skip-to",options,N_("<path>"),+N_("skip the output to the specified path"),+PARSE_OPT_NONEG,diff_opt_rotate_to),OPT_CALLBACK_F(0,"find-object",options,N_("<object-id>"),N_("look for differences that change the number of occurrences of the specified object"),PARSE_OPT_NONEG,diff_opt_find_object),
@@ -6669,6 +6688,8 @@ void diffcore_std(struct diff_options *options)diffcore_pickaxe(options);if(options->orderfile)diffcore_order(options->orderfile);+if(options->rotate_to)+diffcore_rotate(options);if(!options->found_follow)/* See try_to_follow_renames() in tree-diff.c */diff_resolve_rename_copy();
@@ -0,0 +1,46 @@+/*+*Copyright(C)2021,GoogleLLC.+*Basedondiffcore-order.c,whichisCopyright(C)2005,JunioCHamano+*/+#include"cache.h"+#include"diff.h"+#include"diffcore.h"++voiddiffcore_rotate(structdiff_options*opt)+{+structdiff_queue_struct*q=&diff_queued_diff;+structdiff_queue_structoutq;+introtate_to,i;++if(!q->nr)+return;++for(i=0;i<q->nr;i++){+intcmp=strcmp(opt->rotate_to,q->queue[i]->two->path);+if(!cmp)+break;/* exact match */+if(!opt->rotate_to_strict&&cmp<0)+break;/* q->queue[i] is now past the target pathname */+}++if(q->nr<=i){+/* we did not find the specified path */+if(opt->rotate_to_strict)+die(_("No such path '%s' in the diff"),opt->rotate_to);+return;+}++DIFF_QUEUE_CLEAR(&outq);+rotate_to=i;++for(i=rotate_to;i<q->nr;i++)+diff_q(&outq,q->queue[i]);+for(i=0;i<rotate_to;i++){+if(opt->skip_instead_of_rotate)+diff_free_filepair(q->queue[i]);+else+diff_q(&outq,q->queue[i]);+}+free(q->queue);+*q=outq;+}
@@ -1,6 +1,6 @@#!/bin/sh-test_description='diff order'+test_description='diff order & rotate'GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=mainexportGIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
@@ -127,4 +127,74 @@ do'done+### rotate and skip++test_expect_success'rotate and skip setup''+>sample1.t&&+>sample2.t&&+>sample3.t&&+>sample4.t&&+gitaddsample[1234].t&&+gitcommit-m"added"sample[1234].t&&+echomodified>>sample1.t&&+echomodified>>sample2.t&&+echomodified>>sample4.t&&+gitcommit-m"updated"sample[1234].t+'++test_expect_success'diff --rotate-to''+gitdiff--rotate-to=sample2.t--name-onlyHEAD^>actual&&+test_write_linessample2.tsample4.tsample1.t>expect&&+test_cmpexpectactual+'++test_expect_success'diff --skip-to''+gitdiff--skip-to=sample2.t--name-onlyHEAD^>actual&&+test_write_linessample2.tsample4.t>expect&&+test_cmpexpectactual+'++test_expect_success'diff --rotate/skip-to error condition''+test_must_failgitdiff--rotate-to=sample3.tHEAD^&&+test_must_failgitdiff--skip-to=sample3.tHEAD^+'++test_expect_success'log --rotate-to''+gitlog--rotate-to=sample3.t--rawHEAD~2..>raw&&+# just distill the commit header and paths+sed-n-e"s/^commit.*/commit/p"\+-e"/^:/s/^.* //p"raw>actual&&++cat>expect<<-\EOF&&+commit+sample4.t+sample1.t+sample2.t+commit+sample3.t+sample4.t+sample1.t+sample2.t+EOF++test_cmpexpectactual+'++test_expect_success'log --skip-to''+gitlog--skip-to=sample3.t--rawHEAD~2..>raw&&+# just distill the commit header and paths+sed-n-e"s/^commit.*/commit/p"\+-e"/^:/s/^.* //p"raw>actual&&++cat>expect<<-\EOF&&+commit+sample4.t+commit+sample3.t+sample4.t+EOF++test_cmpexpectactual+'+ test_done
From: ZheNing Hu via GitGitGadget <hidden> Date: 2021-02-16 12:57:38
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
We will have to traverse list again to get the file diff which
we want to see. Therefore, here is a new method: user can use
`git difftool --rotate-to=<filename>` or `git difftool --skip-to=<filename>`
to start viewing from the specified file, This will improve the
user experience.
`git difftool --rotate-to=<file>` or `git difftool --skip-to=<filename>`
will pass the path to `diffcore-rotate`, and diff-core will
adjust the order of files, make the specified file sorted to
the first.`git difftool --rotate-to=<file>` will move files before
the specified path to the last output, and
`git difftool --skip-to=<filename>` will ignore these files output.
It is an error when there is no patch for specified file is shown.
Signed-off-by: ZheNing Hu <redacted>
---
Documentation/diff-options.txt | 2 +-
Documentation/git-difftool.txt | 10 ++++++++++
t/t7800-difftool.sh | 30 ++++++++++++++++++++++++++++++
3 files changed, 41 insertions(+), 1 deletion(-)
@@ -701,7 +701,7 @@ components matches the pattern. For example, the pattern "`foo*bar`" matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`". --skip-to=<file>::---rotate-to=<file::+--rotate-to=<file>:: Discard the files before the named <file> from the output (i.e. 'skip to'), or move them to the end of the output (i.e. 'rotate to'). These were invented primarily for use
@@ -34,6 +34,16 @@ OPTIONS This is the default behaviour; the option is provided to override any configuration settings.+--rotate-to=<file>::+ Internally call `git diff --rotate-to=<file>`,+ show the change in the specified path first.+ Files before the specified path will be moved to the last output.++--skip-to=<file>::+ Internally call `git diff --skip-to=<file>`,+ skip the output to the specified path.+ Files before the specified path will not output.+ -t <tool>:: --tool=<tool>:: Use the diff tool specified by <tool>. Valid values include
From: Junio C Hamano <hidden> Date: 2021-02-17 10:32:16
"ZheNing Hu via GitGitGadget" [off-list ref] writes:
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
I am not sure what "in the search" refers to. "in the middle" I
would understand, though.
We will have to traverse list again to get the file diff which
Let's downcase this "We".
we want to see. Therefore, here is a new method: user can use
`git difftool --rotate-to=<filename>` or `git difftool --skip-to=<filename>`
to start viewing from the specified file, This will improve the
user experience.
Do we need both? I'd rather not to give end-user-facing commands
too many knobs that would do similar things. Too many choices to
choose from without clear answer to "which one should I prefer to
use?" is a bad combination for end-users.
@@ -701,7 +701,7 @@ components matches the pattern. For example, the pattern "`foo*bar`" matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`". --skip-to=<file>::---rotate-to=<file::+--rotate-to=<file>:: Discard the files before the named <file> from the output (i.e. 'skip to'), or move them to the end of the output (i.e. 'rotate to'). These were invented primarily for use
Thanks for correcting, but this change should not be a part of this
patch. Instead, you help the other's topic by giving a review (and
you could just have said "there there is closing '>' missing").
@@ -34,6 +34,16 @@ OPTIONS This is the default behaviour; the option is provided to override any configuration settings.+--rotate-to=<file>::+ Internally call `git diff --rotate-to=<file>`,+ show the change in the specified path first.+ Files before the specified path will be moved to the last output.++--skip-to=<file>::+ Internally call `git diff --skip-to=<file>`,+ skip the output to the specified path.+ Files before the specified path will not output.+
This, unlike the "diffcore" stuff, is end-user facing, and it is
better not to force the readers even know what --skip-to option
to the diff does (after all, difftool users are using 'git difftool'
and they are not necessarily 'git diff' users).
--skip-to=<file>::
Start showing the diff for the given path, skipping all
the paths before it.
or something, perhaps.
This probably should be split into two independent tests. One to
check that the non-failing case works as expected, the other to
check that a bogus command line option errors out as expected.
Thanks.
From: ZheNing Hu <hidden> Date: 2021-02-17 16:19:33
Junio C Hamano [off-list ref] 于2021年2月17日周三 下午6:31写道:
"ZheNing Hu via GitGitGadget" [off-list ref] writes:
quoted
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the search,
I am not sure what "in the search" refers to. "in the middle" I
would understand, though.
quoted
We will have to traverse list again to get the file diff which
Let's downcase this "We".
quoted
we want to see. Therefore, here is a new method: user can use
`git difftool --rotate-to=<filename>` or `git difftool --skip-to=<filename>`
to start viewing from the specified file, This will improve the
user experience.
Do we need both? I'd rather not to give end-user-facing commands
too many knobs that would do similar things. Too many choices to
choose from without clear answer to "which one should I prefer to
use?" is a bad combination for end-users.
So users will not need to use `git difftool --skip-to`? Then I am confused
about the meaning of `git difftool --skip-to`.
@@ -701,7 +701,7 @@ components matches the pattern. For example, the pattern "`foo*bar`" matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`". --skip-to=<file>::---rotate-to=<file::+--rotate-to=<file>:: Discard the files before the named <file> from the output (i.e. 'skip to'), or move them to the end of the output (i.e. 'rotate to'). These were invented primarily for use
Thanks for correcting, but this change should not be a part of this
patch. Instead, you help the other's topic by giving a review (and
you could just have said "there there is closing '>' missing").
@@ -34,6 +34,16 @@ OPTIONS This is the default behaviour; the option is provided to override any configuration settings.+--rotate-to=<file>::+ Internally call `git diff --rotate-to=<file>`,+ show the change in the specified path first.+ Files before the specified path will be moved to the last output.++--skip-to=<file>::+ Internally call `git diff --skip-to=<file>`,+ skip the output to the specified path.+ Files before the specified path will not output.+
This, unlike the "diffcore" stuff, is end-user facing, and it is
better not to force the readers even know what --skip-to option
to the diff does (after all, difftool users are using 'git difftool'
and they are not necessarily 'git diff' users).
--skip-to=<file>::
Start showing the diff for the given path, skipping all
the paths before it.
or something, perhaps.
This probably should be split into two independent tests. One to
check that the non-failing case works as expected, the other to
check that a bogus command line option errors out as expected.
I will finish it.
Thanks.
Besides, I have some curiosity about one place in the code in your
patch:
int cmd_diff_tree(...)
...
if (read_stdin) {
...
opt->diffopt.rotate_to_strict = 0;
...
}
This is the only place where rotate_to_strict is set to zero,
So the "git log -p" you mentioned earlier is here Called this code
to avoid exiting the program because of the wrong path, right?
Thanks.
From: ZheNing Hu via GitGitGadget <hidden> Date: 2021-02-19 12:55:10
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the middle,
we will have to traverse list again to get the file diff which
we want to see. Therefore,teach the command an option
`--skip-to=<path>` to allow the user to say that diffs for earlier
paths are not interesting (because they were already seen in an
earlier session) and start this session with the named path.
Signed-off-by: ZheNing Hu <redacted>
---
difftool.c: learn a new way start at specified file
* The patch of the previous version implemented the jump through
environment variables. The current version is based on the "diff
--skip-to=" feature implemented by gitster, which implements a
possible solution for the jump of difftool.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v6
Pull-Request: https://github.com/gitgitgadget/git/pull/870
Range-diff vs v5:
1: fb4bfd0f8b16 < -: ------------ diff: --{rotate,skip}-to=<path>
2: 98e2707ee2fa ! 1: 4377a917ca9e difftool.c: learn a new way start at specified file
@@ Commit message
difftool.c: learn a new way start at specified file
`git difftool` only allow us to select file to view in turn.
- If there is a commit with many files and we exit in the search,
- We will have to traverse list again to get the file diff which
- we want to see. Therefore, here is a new method: user can use
- `git difftool --rotate-to=<filename>` or `git difftool --skip-to=<filename>`
- to start viewing from the specified file, This will improve the
- user experience.
-
- `git difftool --rotate-to=<file>` or `git difftool --skip-to=<filename>`
- will pass the path to `diffcore-rotate`, and diff-core will
- adjust the order of files, make the specified file sorted to
- the first.`git difftool --rotate-to=<file>` will move files before
- the specified path to the last output, and
- `git difftool --skip-to=<filename>` will ignore these files output.
- It is an error when there is no patch for specified file is shown.
+ If there is a commit with many files and we exit in the middle,
+ we will have to traverse list again to get the file diff which
+ we want to see. Therefore,teach the command an option
+ `--skip-to=<path>` to allow the user to say that diffs for earlier
+ paths are not interesting (because they were already seen in an
+ earlier session) and start this session with the named path.
Signed-off-by: ZheNing Hu [off-list ref]
- ## Documentation/diff-options.txt ##
-@@ Documentation/diff-options.txt: components matches the pattern. For example, the pattern "`foo*bar`"
- matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`".
-
- --skip-to=<file>::
----rotate-to=<file::
-+--rotate-to=<file>::
- Discard the files before the named <file> from the output
- (i.e. 'skip to'), or move them to the end of the output
- (i.e. 'rotate to'). These were invented primarily for use
-
## Documentation/git-difftool.txt ##
@@ Documentation/git-difftool.txt: OPTIONS
This is the default behaviour; the option is provided to
override any configuration settings.
+--rotate-to=<file>::
-+ Internally call `git diff --rotate-to=<file>`,
-+ show the change in the specified path first.
-+ Files before the specified path will be moved to the last output.
++ Start showing the diff for the given path,
++ the paths before it will move to end and output.
+
+--skip-to=<file>::
-+ Internally call `git diff --skip-to=<file>`,
-+ skip the output to the specified path.
-+ Files before the specified path will not output.
++ Start showing the diff for the given path, skipping all
++ the paths before it.
+
-t <tool>::
--tool=<tool>::
@@ t/t7800-difftool.sh: test_expect_success 'difftool --gui, --tool and --extcmd ar
+ 4
+ 1
+ EOF
-+ test_cmp output expect &&
-+ test_must_fail git difftool --no-prompt --extcmd=cat --rotate-to="3" HEAD^
++ test_cmp output expect
+'
+
+test_expect_success 'difftool --skip-to' '
@@ t/t7800-difftool.sh: test_expect_success 'difftool --gui, --tool and --extcmd ar
+ 2
+ 4
+ EOF
-+ test_cmp output expect &&
-+ test_must_fail git difftool --no-prompt --extcmd=cat --skip-to="3" HEAD^
++ test_cmp output expect
+'
+
++test_expect_success 'difftool --rotate/skip-to error condition' '
++ test_must_fail git difftool --no-prompt --extcmd=cat --rotate-to="3" HEAD^ &&
++ test_must_fail git difftool --no-prompt --extcmd=cat --skip-to="3" HEAD^
++'
test_done
Documentation/git-difftool.txt | 8 ++++++++
t/t7800-difftool.sh | 32 ++++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+)
@@ -34,6 +34,14 @@ OPTIONS This is the default behaviour; the option is provided to override any configuration settings.+--rotate-to=<file>::+ Start showing the diff for the given path,+ the paths before it will move to end and output.++--skip-to=<file>::+ Start showing the diff for the given path, skipping all+ the paths before it.+ -t <tool>:: --tool=<tool>:: Use the diff tool specified by <tool>. Valid values include
From: ZheNing Hu <hidden> Date: 2021-02-22 15:12:50
Hi,Junio,
ZheNing Hu via GitGitGadget [off-list ref] 于2021年2月19日周五 下午8:53写道:
quoted hunk
From: ZheNing Hu <redacted>
`git difftool` only allow us to select file to view in turn.
If there is a commit with many files and we exit in the middle,
we will have to traverse list again to get the file diff which
we want to see. Therefore,teach the command an option
`--skip-to=<path>` to allow the user to say that diffs for earlier
paths are not interesting (because they were already seen in an
earlier session) and start this session with the named path.
Signed-off-by: ZheNing Hu <redacted>
---
difftool.c: learn a new way start at specified file
* The patch of the previous version implemented the jump through
environment variables. The current version is based on the "diff
--skip-to=" feature implemented by gitster, which implements a
possible solution for the jump of difftool.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-870%2Fadlternative%2Fdifftool_save_point-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-870/adlternative/difftool_save_point-v6
Pull-Request: https://github.com/gitgitgadget/git/pull/870
Range-diff vs v5:
1: fb4bfd0f8b16 < -: ------------ diff: --{rotate,skip}-to=<path>
2: 98e2707ee2fa ! 1: 4377a917ca9e difftool.c: learn a new way start at specified file
@@ Commit message
difftool.c: learn a new way start at specified file
`git difftool` only allow us to select file to view in turn.
- If there is a commit with many files and we exit in the search,
- We will have to traverse list again to get the file diff which
- we want to see. Therefore, here is a new method: user can use
- `git difftool --rotate-to=<filename>` or `git difftool --skip-to=<filename>`
- to start viewing from the specified file, This will improve the
- user experience.
-
- `git difftool --rotate-to=<file>` or `git difftool --skip-to=<filename>`
- will pass the path to `diffcore-rotate`, and diff-core will
- adjust the order of files, make the specified file sorted to
- the first.`git difftool --rotate-to=<file>` will move files before
- the specified path to the last output, and
- `git difftool --skip-to=<filename>` will ignore these files output.
- It is an error when there is no patch for specified file is shown.
+ If there is a commit with many files and we exit in the middle,
+ we will have to traverse list again to get the file diff which
+ we want to see. Therefore,teach the command an option
+ `--skip-to=<path>` to allow the user to say that diffs for earlier
+ paths are not interesting (because they were already seen in an
+ earlier session) and start this session with the named path.
Signed-off-by: ZheNing Hu [off-list ref]
- ## Documentation/diff-options.txt ##
-@@ Documentation/diff-options.txt: components matches the pattern. For example, the pattern "`foo*bar`"
- matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`".
-
- --skip-to=<file>::
----rotate-to=<file::
-+--rotate-to=<file>::
- Discard the files before the named <file> from the output
- (i.e. 'skip to'), or move them to the end of the output
- (i.e. 'rotate to'). These were invented primarily for use
-
## Documentation/git-difftool.txt ##
@@ Documentation/git-difftool.txt: OPTIONS
This is the default behaviour; the option is provided to
override any configuration settings.
+--rotate-to=<file>::
-+ Internally call `git diff --rotate-to=<file>`,
-+ show the change in the specified path first.
-+ Files before the specified path will be moved to the last output.
++ Start showing the diff for the given path,
++ the paths before it will move to end and output.
+
+--skip-to=<file>::
-+ Internally call `git diff --skip-to=<file>`,
-+ skip the output to the specified path.
-+ Files before the specified path will not output.
++ Start showing the diff for the given path, skipping all
++ the paths before it.
+
-t <tool>::
--tool=<tool>::
@@ t/t7800-difftool.sh: test_expect_success 'difftool --gui, --tool and --extcmd ar
+ 4
+ 1
+ EOF
-+ test_cmp output expect &&
-+ test_must_fail git difftool --no-prompt --extcmd=cat --rotate-to="3" HEAD^
++ test_cmp output expect
+'
+
+test_expect_success 'difftool --skip-to' '
@@ t/t7800-difftool.sh: test_expect_success 'difftool --gui, --tool and --extcmd ar
+ 2
+ 4
+ EOF
-+ test_cmp output expect &&
-+ test_must_fail git difftool --no-prompt --extcmd=cat --skip-to="3" HEAD^
++ test_cmp output expect
+'
+
++test_expect_success 'difftool --rotate/skip-to error condition' '
++ test_must_fail git difftool --no-prompt --extcmd=cat --rotate-to="3" HEAD^ &&
++ test_must_fail git difftool --no-prompt --extcmd=cat --skip-to="3" HEAD^
++'
test_done
Documentation/git-difftool.txt | 8 ++++++++
t/t7800-difftool.sh | 32 ++++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+)
@@ -34,6 +34,14 @@ OPTIONS This is the default behaviour; the option is provided to override any configuration settings.+--rotate-to=<file>::+ Start showing the diff for the given path,+ the paths before it will move to end and output.++--skip-to=<file>::+ Start showing the diff for the given path, skipping all+ the paths before it.+ -t <tool>:: --tool=<tool>:: Use the diff tool specified by <tool>. Valid values include