With all the discussion about the index file in the last few days I would have thought that this issue would have come up. But I don't think it has. I have been editing a set of files to make a commit, and after editing each one had done a git update-index. At this point I am just about to commit when I realise that one of the files has changes in it that really ought to be a separate commit. So effectively, I want to do one of three things a) git-commit <that-file> Except I can't because there is a safety valve that prevents this and there is no force option. b) Revert the index entry for that file back to the previous HEAD commit point, whilst leaving the edits in the working tree, so that I can then commit without that one file. I can't find a command to do that. The nearest seems to be git-update-index --remove, but the manual says that it will not do anything if the file still exists. c) Revert the entire index back to the state it was at the last commit so I can selectively add back in the files that I have editted. The command to do that seems to be git-read-tree HEAD I tried this, and it did indeed seem to exactly this - not quite what I wanted, but actually a reasonable compromise. However, it took me a long time scanning possible commands before I found it so I thought I might add some text to one of the tutorials Any ideas of where? What happened to the text written here http://marc.theaimsgroup.com/?l=git&m=116406699903565&w=2 I thought this might be a place to put something like this, but having just updated my version of git from source, it doesn't seem to have been put in to git anywhere yet. -- Alan Chandler http://www.chandlerfamily.org.uk -
I think that is actually a misfeature. This _should_ just work. It's the easy and logical way to do it, and it's the one that matches all the other behaviours of "git commit" these days. The reason for the safety valve is actually not really "safety" any more, it's purely "historical behaviour". Ie the sanity check is not there because you would be doing anything unsafe, but simply because the behaviour in this area _changed_, so the semantics are different from what they were originally. But those "original" semantics are now so old and so uninteresting that the safety feature has gone from being a safety feature to just being annoying, and hindering you from doing what you want to do. Side note: you -can- do what you want to do, but it's insanely stupid. Here's what you'd do: git ls-tree HEAD -- that-file | git update-index --index-info git commit that-file but there is no way in hell I will claim that this is a _good_ thing. [ That said, the whole git ls-tree <treeish> -- <file-list> | git update-index --index-info is a useful pattern to know. You can basically insert _any_ part of old historical state into the index with this, which can be useful if you want to play games without changing the _other_ parts of the index. ] So anyway, I would suggest that we just get rid of that partial commit "safety check" in "git commit" for now. It still makes sense for when you're in the middle of a _merge_, but the "verify that index matches" is not worth it. Or at _least_ there should be a flag to force it. Junio? Linus -
I agree that if this sequence:
$ edit foo
$ git update-index foo
$ edit foo
$ git commit foo
is what the user actually gives from the command line, after
this commit is made, the user would want to _lose_ the state of
foo at the update-index after this commit is made, 100% of the
time (not "most likely", nor "usually", but "always"). So I am
very in favor of removing that check.
I am a bit worried if the reason behind this safety valve might
have been something else, and we describe the reason as "we
would lose data with this sequence otherwise" only to illustrate
what's happening behind the scene in technical terms.
In other words, while I think no user would ever want to keep
the state of foo at update-index after the above exact sequence
as the end-user action, I am worried if a usage sequence that
involve a group of operations encapsulated in a larger command
(a synthetic command that touches index and working files
without making the user painfully aware of the index -- likes of
git-mv, git-rm, ...) might have been the true motivation of the
safety valve.
I need to be reminded by somebody who went back to the list
discussion around the time we introduced --only, and made sure
that the "you would lose the snapshot you staged in the index if
we allowed it" literally meant only that and nothing else; not
some other common sequence that had the above command sequence
inside, and keeping the state of 'foo' at update-index time made
sense for that usage pattern, although I do not think of
anything offhand...
-
I don't quite understand this - maybe it should be git ls-tree HEAD -- that-file | git update-index --index-info git commit git commit -a either I want to ONLY commit that file at the working tree state (and index before these commands), or I want to commit ALL except this file (so I can later come and commit just that file) so having reset the index to the state of HEAD for "that-file" then the commit should make a commit with all the other changes in the index (but NOT that-file) and then the git commit -a picks up "that-file" -- Alan Chandler http://www.chandlerfamily.org.uk -
Sure. It depends on which file you want to commit first. If you want to commit "that-file" first, you do my sequence. If you want to commit everything _but_ "that-file", you do the second sequence (which basically removes the changes to "that-file" from the index, then commits the index, and then with "git commit -a" commits the remaining dirty state, which is obviously those changes to "that-file" Right. If you do git ls-tree HEAD -- that-file | git update-index --index-info git commit that-file you basically ONLY commit "that-file". You first reset it (in the index) to the old state, but that's just so that "git commit that-file" will now happily commit the current state (in the working tree) of "that-file". So "git commit that-file" will basically _ignore_ your current index. Because you told "git commit" (by naming "that-file") that you _only_ wanted to commit "that-file". So whatever state you had in your current index doesn't matter at all - it will only look at the HEAD tree _and_ that single file that you specified. Linus -
The codepath has a big "don't do this during a merge" check in front. I think this is a safe thing to do, so let's do this. diff --git a/git-commit.sh b/git-commit.sh index 81c3a0c..c829791 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -350,19 +350,9 @@ t,) refuse_partial "Cannot do a partial commit during a merge." fi TMP_INDEX="$GIT_DIR/tmp-index$$" - if test -z "$initial_commit" - then - # make sure index is clean at the specified paths, or - # they are additions. - dirty_in_index=`git-diff-index --cached --name-status \ - --diff-filter=DMTU HEAD -- "$@"` - test -z "$dirty_in_index" || - refuse_partial "Different in index and the last commit: -$dirty_in_index" - fi commit_only=`git-ls-files --error-unmatch -- "$@"` || exit - # Build the temporary index and update the real index + # Build a temporary index and update the real index # the same way. if test -z "$initial_commit" then -
A side note on this.. It definitely works, but it's not really the right thing to do for a few reasons: - it isn't even what you wanted. You didn't want to reset _all_ the index values, you only really wanted to reset a few of them. So as mentioned in the previous email, the command sequence you'd wanted for that operation is git ls-tree <tree> -- <path pattern list> | git update-index --index-info But, that said, if you actually want to reset the whole index, "git-read-tree HEAD" works, but is not what you should do: - you really want to keep the index "stat()" cache valid, and git-read-tree will throw that all out. So you would need to do a git update-index --refresh after you've reset the index ("git status" will do it for you, and if you don't do either "git status" or the above, - instead of re-reading the index 100% and then having to refresh it back to mostly the same stat() into it already had, you can _merge_ the old index with the information in HEAD, by using git read-tree -m HEAD which basically does a merge from the old index and the HEAD tree. - However, that actually fails if the old index wasn't just dirty, but had unmerged paths etc, because then a "merge" would throw away that unmerged information. So what you _really_ want to do is git read-tree --reset HEAD which (as the flag implies) will _reset_ the index to the tree in HEAD, and this will do exactly what you were looking for: keep the "stat()" information alone, but reset the actual index contents. - HOWEVER. This is exactly what "git reset" does. So in short, you should just have done "git reset", and you'd have reset your index back to the state of your last commit. So "git reset" is generally your friend whenever something goes wrong. If you also want to reset your checked-out files (which you did NOT want to do in this case, of course), you would have added the "--hard" flag to git ...
One observation about git, made in a relatively distant past, was "git is not a usable system yet; there is no 'git undo'". I think it was on the kernel list (I think it was from Alan who seems to have lost his last name from his From: line lately, but I may be mistaken). It left a deep psychological trauma in me, not because it was stated in a brutal way (it wasn't) but because I fully agreed with that statement from the end user point of view, but I did not see a good solution to the problem (and I from the beginning kept saying "I do not do Porcelains" and kept calling what is shipped with core "Porcelain-ish"). "git reset" is one part of "undo". For example, undoing a commit can be approximated with "reset HEAD^" or "reset --hard HEAD^"; undoing a conflicted and unfinished merge can be approximated with "reset HEAD" or "reset --hard HEAD". But for one thing, these are only "approximations" (the working tree files after these two forms of reset are different from the state you had before running "commit" or "merge"). And for another thing, "reset" is only one part of "undo". "reset" would not help "undo"-ing a botched "git bisect good", for example; you need "git bisect reset". Similarly, "git rebase" in the middle can be undone with its own --abort option. But the user has to know about them. Another twist is that once completed, "rebase --abort" obviously would not mean "undo the last rebase". I think one cause of the "problem" (if not having a general "undo" is a problem, and I think it is to some extent) is that git Porcelain-ish commands try to stay stateless to allow mixing and matching of different commands to leave the door open to the end user to be flexible, but they go too far. Some of the commands do leave its state (e.g. MERGE_HEAD is a sign of a merge in progress, and git-commit notices it), and some of the commands know about state markers from the other commands (e.g. "git reset" removes MERGE_HEAD). However, I think we do not do enough ...
They go too far by doing too little.
And here is throwing an idea to remedy it; it is far from
complete but sending it out early before spending too much time
on pursuit of a wild goose.
-- >8 --
[PATCH] git-explain
This patch adds "git-explain" script that notices various clues
other commands can leave the working tree and repository in and
intended to guide the end user out of the confused mess.
This is only a demonstration-of-concept, as many commands do not
leave enough information for us to truly figure out what state
we are in nor how we got into the mess. As a demonstration, it
makes "git merge" to leave a new "$GIT_DIR/FAILED_MERGE" file
when it gives up before touching the working tree.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
git-explain.sh | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
git-merge.sh | 3 +-
git-reset.sh | 3 +-
3 files changed, 176 insertions(+), 2 deletions(-)
diff --git a/git-explain.sh b/git-explain.sh
new file mode 100755
index 0000000..07115ae
--- /dev/null
+++ b/git-explain.sh
@@ -0,0 +1,172 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Junio C Hamano
+#
+
+SUBDIRECTORY_OK=Yes
+. git-sh-setup
+
+TOP=`git-rev-parse --show-cdup`
+test -z "$TOP" && TOP=./
+
+say_with_indent() {
+ echo "$@" | sed -e 's/^/ /'
+}
+
+explain_merge_conflict () {
+ test -f $GIT_DIR/HEAD &&
+ test -f "$GIT_DIR/MERGE_HEAD" &&
+ test -f "$GIT_DIR/MERGE_MSG" &&
+ test "z`git ls-files -u`" != z || return 1
+
+ title=$(sed -e q "$GIT_DIR/MERGE_MSG")
+
+ conflicts=$(git ls-files -u |
+ sed -e 's/^[0-7]* [0-9a-f]* [0-3] //' |
+ uniq)
+
+ git diff-index -r --name-only HEAD >"$tmp-1"
+ git diff-tree -r --name-only HEAD MERGE_HEAD >"$tmp-2"
+ locals=`comm -23 "$tmp-1" "$tmp-2"`
+
+ cat <<EOF
+You tried a merge whose title will be
+
+ $title
+
+This may have successfully merged some paths and they are already
+staged for the next commit, but the following paths could not be
+automatically ...Should I take these responses to mean that you two are negative about the approach of spending extra cycles to commands that can leave the working tree in a "in the middle of doing something" state to help having a unified command to explain what the situation is and suggest the user possible exits, or are you saying that it might be a good idea but "git explain" is a bad name? An issue with this approach is that this can be the beginning of hardwiring the official "right way of doing things" in the set of tools. Pursuing this approach would enhance the set of state markers like "FAILED_MERGE" in the example, which means: - more commands would actively record what they were attempting to do, obviously; - over time "git explain" will learn about these state markers, and we would hardwire the "best current practice" exits from various states in the help messages; - also commands other than "git explain" would learn about the state markers of other commands, and change their behaviour. For example, "git am" might learn to refuse running while a merge in progress much earlier than with the current implementation. The last point can easily become a double-edged sword. Hardwiring the recommended workflow in the tools would reduce chances of mistakes, but it could rob the flexibility from them if we are not careful and forget to take into account some useful combination of tools when adding such safety valves. -
It seems like the point of this command is to show some state information which would otherwise be hard to see. I think of 'git status' as the way to look at the repository state. Perhaps we should enhance the output of 'git status' to note things such as failed merges, whether we're bisecting, in the middle of applying a patch series, etc. There could be an optional verbosity switch to give "full explanations" As long as the safety valves don't come up _routinely_ in certain workflows, it seems OK to bypass them with a '-f' force switch. I suspect the best way to figure out if such workflows are in use is to put in the safety valves and see who complains; otherwise we're stuck with brainstorming workflows and deciding whether they make sense. -Peff -
I wholeheartedly agree that 'git status' should show something like this. I actually had some stuff that was a work-in-progress several months ago that enhanced status with several things like this; but got distracted and forgot about that repository. I'll try to dig it out sometime tomorrow. I remember my work started from wanting to know what 'git-rerere' would be recording. -- Eric Wong -
This is the stuff I mentioned I had been working on several months before in a reply to the git-explain/git-wtf/git-whatsup thread. I've rebased it against the current master and everything still seems to work (I don't have unit tests for them). This has been forgotten and abandoned for a while. I especially don't expect the changes to git-commit.sh (status) to be applied as-is, as it should go into the new runstatus (my work predates runstatus). git-am.sh | 18 ++++++++++++++---- git-commit.sh | 45 ++++++++++++++++++++++++++++++++++++++++++++- git-rebase.sh | 43 ++++++++++++++++++++++++++++++------------- git-rerere.perl | 25 +++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 18 deletions(-) [PATCH 1/5] rerere: avoid misrecording on a skipped or aborted rebase/am [PATCH 2/5] status: show files that would have resolutions recorded by rerere [PATCH 3/5] am and rebase resolve states get picked up by status/commit [PATCH 4/5] am: run git rerere to record resolution on successful --resolved [PATCH 5/5] rerere: add the diff command -- Eric Wong -
Signed-off-by: Eric Wong <normalperson@yhbt.net> --- git-am.sh | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/git-am.sh b/git-am.sh index 179b967..d0714c6 100755 --- a/git-am.sh +++ b/git-am.sh @@ -414,6 +414,10 @@ do stop_here_user_resolve $this fi apply_status=0 + if test -d "$GIT_DIR/rr-cache" + then + git rerere + fi ;; esac -- 1.4.4.2.g860f4 -
Sometimes I like to see what I'm recording resolutions for and
what's changed during a resolution.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
git-rerere.perl | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/git-rerere.perl b/git-rerere.perl
index b78194a..7a3ae84 100755
--- a/git-rerere.perl
+++ b/git-rerere.perl
@@ -186,6 +186,13 @@ if (my $arg = shift @ARGV) {
for my $path (keys %merge_rr) {
print $path, "\n";
}
+ } elsif ($arg eq 'diff') {
+ for my $path (keys %merge_rr) {
+ my $name = $merge_rr{$path};
+ system(qw/diff/, @ARGV,
+ '-L', "a/$path", '-L', "b/$path",
+ "$rr_dir/$name/preimage", $path);
+ }
}
exit 0;
}
--
1.4.4.2.g860f4
-
Data in rr-cache isn't valid after a patch application is
skipped or and aborted, so our next commit could be misrecorded
as a resolution of that skipped/failed commit, which is wrong.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
git-am.sh | 4 ++++
git-rebase.sh | 8 ++++++++
git-rerere.perl | 12 ++++++++++++
3 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/git-am.sh b/git-am.sh
index afe322b..28ccae3 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -246,6 +246,10 @@ last=`cat "$dotest/last"`
this=`cat "$dotest/next"`
if test "$skip" = t
then
+ if test -d "$GIT_DIR/rr-cache"
+ then
+ git-rerere clear
+ fi
this=`expr "$this" + 1`
resume=
fi
diff --git a/git-rebase.sh b/git-rebase.sh
index 25530df..2b4f347 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -139,6 +139,10 @@ do
--skip)
if test -d "$dotest"
then
+ if test -d "$GIT_DIR/rr-cache"
+ then
+ git-rerere clear
+ fi
prev_head="`cat $dotest/prev_head`"
end="`cat $dotest/end`"
msgnum="`cat $dotest/msgnum`"
@@ -157,6 +161,10 @@ do
exit
;;
--abort)
+ if test -d "$GIT_DIR/rr-cache"
+ then
+ git-rerere clear
+ fi
if test -d "$dotest"
then
rm -r "$dotest"
diff --git a/git-rerere.perl b/git-rerere.perl
index d3664ff..dd86577 100755
--- a/git-rerere.perl
+++ b/git-rerere.perl
@@ -172,6 +172,18 @@ sub merge {
-d "$rr_dir" || exit(0);
read_rr();
+
+if (@ARGV && $ARGV[0] eq 'clear') {
+ for my $path (keys %merge_rr) {
+ my $name = $merge_rr{$path};
+ if (-d "$rr_dir/$name") {
+ rmtree(["$rr_dir/$name"]);
+ }
+ }
+ unlink $merge_rr;
+ exit 0;
+}
+
my %conflict = map { $_ => 1 } find_conflict();
# MERGE_RR records paths with conflicts immediately after merge
--
1.4.4.2.g860f4
-
This is good, but Documentation/git-rerere.txt should talk about this new option you added. -
Signed-off-by: Eric Wong <normalperson@yhbt.net> --- Documentation/git-rerere.txt | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index 8b6b651..de65cce 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -7,8 +7,7 @@ git-rerere - Reuse recorded resolve SYNOPSIS -------- -'git-rerere' - +'git-rerere' [clear|diff] DESCRIPTION ----------- @@ -167,6 +166,25 @@ would conflict the same way the test merge you resolved earlier. `git-rerere` is run by `git rebase` to help you resolve this conflict. +COMMANDS +-------- + +Normally, git-rerere is run without arguments or user-intervention. +However, it has several commands that allow it to interact with +its working state. + +'clear':: + +This resets the metadata used by rerere if a merge resolution is to be +is aborted. Calling gitlink:git-am[1] --skip or gitlink:git-rebase[1] +[--skip|--abort] will automatcally invoke this command. + +'diff':: + +This displays diffs for the current state of the resolution. It is +useful for tracking what has changed while the user is resolving +conflicts. Additional arguments are passed directly to the system +diff(1) command installed in PATH. Author ------ -- 1.4.4.2.g860f4 -
Come to think of it, I am not sure about this one. Don't you
need to make sure that there is no existing resolution before
removing it? In other words, shouldn't the removal be like this?
if (-d "$rr_dir/$name" && ! -f "$rr_dir/$name/postimage") {
rmtree(["$rr_dir/$name"]);
}
-
Yes. However, it seems unlikely, that MERGE_RR would point to something that has a postimage. I suppose that a machine could crash or a user could've hit ^C at the correct millisecond that would cause rerere to not update MERGE_RR correctly. Updated patches on the way (leaving out the status updates). -- Eric Wong -
git-am and git-rebase will be updated to use 'clear', and
diff/status can be used to aid the user in tracking progress in
the resolution process.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
Documentation/git-rerere.txt | 27 +++++++++++++++++++++++++--
git-rerere.perl | 25 +++++++++++++++++++++++++
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index 8b6b651..22494b2 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -7,8 +7,7 @@ git-rerere - Reuse recorded resolve
SYNOPSIS
--------
-'git-rerere'
-
+'git-rerere' [clear|diff|status]
DESCRIPTION
-----------
@@ -167,6 +166,30 @@ would conflict the same way the test merge you resolved earlier.
`git-rerere` is run by `git rebase` to help you resolve this
conflict.
+COMMANDS
+--------
+
+Normally, git-rerere is run without arguments or user-intervention.
+However, it has several commands that allow it to interact with
+its working state.
+
+'clear'::
+
+This resets the metadata used by rerere if a merge resolution is to be
+is aborted. Calling gitlink:git-am[1] --skip or gitlink:git-rebase[1]
+[--skip|--abort] will automatcally invoke this command.
+
+'diff'::
+
+This displays diffs for the current state of the resolution. It is
+useful for tracking what has changed while the user is resolving
+conflicts. Additional arguments are passed directly to the system
+diff(1) command installed in PATH.
+
+'status'::
+
+Like diff, but this only prints the filenames that will be tracked
+for resolutions.
Author
------
diff --git a/git-rerere.perl b/git-rerere.perl
index d3664ff..2703d01 100755
--- a/git-rerere.perl
+++ b/git-rerere.perl
@@ -172,6 +172,31 @@ sub merge {
-d "$rr_dir" || exit(0);
read_rr();
+
+if (my $arg = shift @ARGV) {
+ if ($arg eq 'clear') {
+ for my $path (keys %merge_rr) {
+ my $name = $merge_rr{$path};
+ if (-d "$rr_dir/$name" ...Data in rr-cache isn't valid after a patch application is skipped or and aborted, so our next commit could be misrecorded as a resolution of that skipped/failed commit, which is wrong. git-am --skip, git-rebase --skip/--abort will automatically invoke git-rerere clear to avoid this. Also, since git-am --resolved indicates a resolution was succesful, remember to run git-rerere to record the resolution (and not surprise the user when the next commit is made). Signed-off-by: Eric Wong <normalperson@yhbt.net> --- git-am.sh | 8 ++++++++ git-rebase.sh | 8 ++++++++ 2 files changed, 16 insertions(+), 0 deletions(-) diff --git a/git-am.sh b/git-am.sh index afe322b..5df6787 100755 --- a/git-am.sh +++ b/git-am.sh @@ -246,6 +246,10 @@ last=`cat "$dotest/last"` this=`cat "$dotest/next"` if test "$skip" = t then + if test -d "$GIT_DIR/rr-cache" + then + git-rerere clear + fi this=`expr "$this" + 1` resume= fi @@ -408,6 +412,10 @@ do stop_here_user_resolve $this fi apply_status=0 + if test -d "$GIT_DIR/rr-cache" + then + git rerere + fi ;; esac diff --git a/git-rebase.sh b/git-rebase.sh index 25530df..2b4f347 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -139,6 +139,10 @@ do --skip) if test -d "$dotest" then + if test -d "$GIT_DIR/rr-cache" + then + git-rerere clear + fi prev_head="`cat $dotest/prev_head`" end="`cat $dotest/end`" msgnum="`cat $dotest/msgnum`" @@ -157,6 +161,10 @@ do exit ;; --abort) + if test -d "$GIT_DIR/rr-cache" + then + git-rerere clear + fi if test -d "$dotest" then rm -r "$dotest" -- 1.4.4.2.g860f4 -
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
git-commit.sh | 17 ++++++++++++++++-
git-rerere.perl | 18 ++++++++++++------
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/git-commit.sh b/git-commit.sh
index 81c3a0c..9f6d1ef 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -48,7 +48,22 @@ run_status () {
GIT_INDEX_FILE="$NEXT_INDEX"
export GIT_INDEX_FILE
fi
-
+ if test -d "$GIT_DIR/rr-cache"
+ then
+ rr_shown=
+ git-rerere status | while read line; do
+ if [ -z "$rr_shown" ]; then
+ echo '#'
+ echo '# Resolutions to be recorded for files:'
+ echo '# (git-rerere will automatically record' \
+ 'conflict resolutions'
+ echo '# when these files are committed)'
+ echo '#'
+ rr_shown=1
+ fi
+ echo "# $line"
+ done
+ fi
case "$status_only" in
t) color= ;;
*) color=--nocolor ;;
diff --git a/git-rerere.perl b/git-rerere.perl
index dd86577..b78194a 100755
--- a/git-rerere.perl
+++ b/git-rerere.perl
@@ -173,14 +173,20 @@ sub merge {
read_rr();
-if (@ARGV && $ARGV[0] eq 'clear') {
- for my $path (keys %merge_rr) {
- my $name = $merge_rr{$path};
- if (-d "$rr_dir/$name") {
- rmtree(["$rr_dir/$name"]);
+if (my $arg = shift @ARGV) {
+ if ($arg eq 'clear') {
+ for my $path (keys %merge_rr) {
+ my $name = $merge_rr{$path};
+ if (-d "$rr_dir/$name") {
+ rmtree(["$rr_dir/$name"]);
+ }
+ }
+ unlink $merge_rr;
+ } elsif ($arg eq 'status') {
+ for my $path (keys %merge_rr) {
+ print $path, "\n";
}
}
- unlink $merge_rr;
exit 0;
}
--
1.4.4.2.g860f4
-
This should help warn of accidental commits in the middle of a
rebase operation. It also saves messages in $dotest/resolvemsg
and shows it in "git status" so the user can be reminded of
how to continue the am or rebase operation.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
git-am.sh | 10 ++++++----
git-commit.sh | 28 ++++++++++++++++++++++++++++
git-rebase.sh | 35 ++++++++++++++++++++++-------------
3 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/git-am.sh b/git-am.sh
index 28ccae3..179b967 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -16,7 +16,7 @@ stop_here () {
stop_here_user_resolve () {
if [ -n "$resolvemsg" ]; then
- echo "$resolvemsg"
+ echo "$resolvemsg" | tee "$dotest/resolvemsg"
stop_here $1
fi
cmdline=$(basename $0)
@@ -32,9 +32,11 @@ stop_here_user_resolve () {
then
cmdline="$cmdline -d=$dotest"
fi
- echo "When you have resolved this problem run \"$cmdline --resolved\"."
- echo "If you would prefer to skip this patch, instead run \"$cmdline --skip\"."
-
+ cat > "$dotest/resolvemsg" <<EOF
+When you have resolved this problem run \"$cmdline --resolved\".
+If you would prefer to skip this patch, instead run \"$cmdline --skip\".
+EOF
+ cat "$dotest/resolvemsg"
stop_here $1
}
diff --git a/git-commit.sh b/git-commit.sh
index 9f6d1ef..4691835 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -32,6 +32,33 @@ save_index () {
cp -p "$THIS_INDEX" "$NEXT_INDEX"
}
+check_dotest () {
+ if test -d .dotest
+ then
+ echo ''
+ if test -f .dotest/resolvemsg
+ then
+ cat .dotest/resolvemsg
+ else
+ echo 'A .dotest directory exists.'
+ echo 'Either a "git rebase" or "git am"' \
+ 'operation is in progress'
+ fi
+ fi
+ if test -d "$GIT_DIR/.dotest-merge"
+ then
+ echo ''
+ if test -f "$GIT_DIR/.dotest-merge/resolvemsg"
+ then
+ cat "$GIT_DIR/.dotest-merge/resolvemsg"
+ else
+ echo "A $GIT_DIR/.dotest-merge/resolvemsg ...Jeff King <peff@peff.net> wrote: Problem is that nobody reads the manuals, next to nobody complains, and when it doesn't work out via road A you try plan B. A might have been exactly right, but it is blocked, and you'll never know if it is because of fundamental reasons or by decree. -- Dr. Horst H. von Brand User #22616 counter.li.org Departamento de Informatica Fono: +56 32 2654431 Universidad Tecnica Federico Santa Maria +56 32 2654239 Casilla 110-V, Valparaiso, Chile Fax: +56 32 2797513 -
Hi, I think they just were in the mood for some slashdot style As has been the case not at all long ago, a saftey valve which no longer made sense was just removed. As for the inflexibility of a recommended workflow: by now, long-time gitsters have had enough time to fiddle around with git and to develop a workflow which Just Works. It is just a nice gesture of old-time users towards new-time users to pass that knowledge. And new-time users are often not in the least interested in learning the ropes the hard way. Besides, the recommended workflow(s) can be changed/replaced by other porcelainish commands, because only those will contain the safety valves, right? Ciao, Dscho -
Wouldn't it be better to create some kind of action-log (that's cleared at the end of the command if everything was all right) instead of creating special markers for different commands? That way there would be only 1 place to check for what happened ... -- best regards Ray -
On Sunday 03 December 2006 18:34, Linus Torvalds wrote: Doh [slaps head with wet blanket] I was so worried about NOT changing my working tree - I totally overlooked the reset command. I had never quite understood what --mixed really meant before. But re-reading the man page now, its obvious. -- Alan Chandler http://www.chandlerfamily.org.uk -
