-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This introduces a --patch mode for git-checkout. In the index usage git checkout --patch -- [files...] it lets the user discard edits from the <files> at the granularity of hunks (by selecting hunks from 'git diff' and then reverse applying them to the worktree). We also accept a revision argument. In the case git checkout --patch HEAD -- [files...] we offer hunks from the difference between HEAD and the worktree, and reverse applies them to both index and worktree, allowing you to discard staged changes completely. In the non-HEAD usage git checkout --patch <revision> -- [files...] it offers hunks from the difference between the worktree and <revision>. The chosen hunks are then applied to both index and worktree. The application to worktree and index is done "atomically" in the sense that we first check if the patch applies to the index (it should always apply to the worktree). If it does not, we give the user a choice to either abort or apply to the worktree anyway. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
- Loading branch information
Thomas Rast
authored and
Junio C Hamano
committed
Aug 15, 2009
1 parent
d002ef4
commit 4f35365
Showing
4 changed files
with
199 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/bin/sh | ||
|
||
test_description='git checkout --patch' | ||
|
||
. ./lib-patch-mode.sh | ||
|
||
test_expect_success 'setup' ' | ||
mkdir dir && | ||
echo parent > dir/foo && | ||
echo dummy > bar && | ||
git add bar dir/foo && | ||
git commit -m initial && | ||
test_tick && | ||
test_commit second dir/foo head && | ||
set_and_save_state bar bar_work bar_index && | ||
save_head | ||
' | ||
|
||
# note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar' | ||
|
||
test_expect_success 'saying "n" does nothing' ' | ||
set_and_save_state dir/foo work head && | ||
(echo n; echo n) | git checkout -p && | ||
verify_saved_state bar && | ||
verify_saved_state dir/foo | ||
' | ||
|
||
test_expect_success 'git checkout -p' ' | ||
(echo n; echo y) | git checkout -p && | ||
verify_saved_state bar && | ||
verify_state dir/foo head head | ||
' | ||
|
||
test_expect_success 'git checkout -p with staged changes' ' | ||
set_state dir/foo work index | ||
(echo n; echo y) | git checkout -p && | ||
verify_saved_state bar && | ||
verify_state dir/foo index index | ||
' | ||
|
||
test_expect_success 'git checkout -p HEAD with NO staged changes: abort' ' | ||
set_and_save_state dir/foo work head && | ||
(echo n; echo y; echo n) | git checkout -p HEAD && | ||
verify_saved_state bar && | ||
verify_saved_state dir/foo | ||
' | ||
|
||
test_expect_success 'git checkout -p HEAD with NO staged changes: apply' ' | ||
(echo n; echo y; echo y) | git checkout -p HEAD && | ||
verify_saved_state bar && | ||
verify_state dir/foo head head | ||
' | ||
|
||
test_expect_success 'git checkout -p HEAD with change already staged' ' | ||
set_state dir/foo index index | ||
# the third n is to get out in case it mistakenly does not apply | ||
(echo n; echo y; echo n) | git checkout -p HEAD && | ||
verify_saved_state bar && | ||
verify_state dir/foo head head | ||
' | ||
|
||
test_expect_success 'git checkout -p HEAD^' ' | ||
# the third n is to get out in case it mistakenly does not apply | ||
(echo n; echo y; echo n) | git checkout -p HEAD^ && | ||
verify_saved_state bar && | ||
verify_state dir/foo parent parent | ||
' | ||
|
||
# The idea in the rest is that bar sorts first, so we always say 'y' | ||
# first and if the path limiter fails it'll apply to bar instead of | ||
# dir/foo. There's always an extra 'n' to reject edits to dir/foo in | ||
# the failure case (and thus get out of the loop). | ||
|
||
test_expect_success 'path limiting works: dir' ' | ||
set_state dir/foo work head && | ||
(echo y; echo n) | git checkout -p dir && | ||
verify_saved_state bar && | ||
verify_state dir/foo head head | ||
' | ||
|
||
test_expect_success 'path limiting works: -- dir' ' | ||
set_state dir/foo work head && | ||
(echo y; echo n) | git checkout -p -- dir && | ||
verify_saved_state bar && | ||
verify_state dir/foo head head | ||
' | ||
|
||
test_expect_success 'path limiting works: HEAD^ -- dir' ' | ||
# the third n is to get out in case it mistakenly does not apply | ||
(echo y; echo n; echo n) | git checkout -p HEAD^ -- dir && | ||
verify_saved_state bar && | ||
verify_state dir/foo parent parent | ||
' | ||
|
||
test_expect_success 'path limiting works: foo inside dir' ' | ||
set_state dir/foo work head && | ||
# the third n is to get out in case it mistakenly does not apply | ||
(echo y; echo n; echo n) | (cd dir && git checkout -p foo) && | ||
verify_saved_state bar && | ||
verify_state dir/foo head head | ||
' | ||
|
||
test_expect_success 'none of this moved HEAD' ' | ||
verify_saved_head | ||
' | ||
|
||
test_done |