diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt index 228c4d95bd..3144864d85 100644 --- a/Documentation/git-diff.txt +++ b/Documentation/git-diff.txt @@ -22,8 +22,10 @@ the number of trees given to the command. * When one is given, the working tree and the named tree are compared, using `git-diff-index`. The option - `--cached` can be given to compare the index file and + `--index` can be given to compare the index file and the named tree. + `--cached` is a deprecated alias for `--index`. It's use is + discouraged. * When two s are given, these two trees are compared using `git-diff-tree`. @@ -47,7 +49,7 @@ Various ways to check your working tree:: + ------------ $ git diff <1> -$ git diff --cached <2> +$ git diff --index <2> $ git diff HEAD <3> ------------ + diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt index 68ac6a65df..4bc35a1d4b 100644 --- a/Documentation/git-symbolic-ref.txt +++ b/Documentation/git-symbolic-ref.txt @@ -19,29 +19,22 @@ argument to see on which branch your working tree is on. Give two arguments, create or update a symbolic ref to point at the given branch . -Traditionally, `.git/HEAD` is a symlink pointing at -`refs/heads/master`. When we want to switch to another branch, -we did `ln -sf refs/heads/newbranch .git/HEAD`, and when we want +A symbolic ref is a regular file that stores a string that +begins with `ref: refs/`. For example, your `.git/HEAD` is +a regular file whose contents is `ref: refs/heads/master`. + +NOTES +----- +In the past, `.git/HEAD` was a symbolic link pointing at +`refs/heads/master`. When we wanted to switch to another branch, +we did `ln -sf refs/heads/newbranch .git/HEAD`, and when we wanted to find out which branch we are on, we did `readlink .git/HEAD`. This was fine, and internally that is what still happens by default, but on platforms that do not have working symlinks, or that do not have the `readlink(1)` command, this was a bit cumbersome. On some platforms, `ln -sf` does not even work as -advertised (horrors). - -A symbolic ref can be a regular file that stores a string that -begins with `ref: refs/`. For example, your `.git/HEAD` *can* -be a regular file whose contents is `ref: refs/heads/master`. -This can be used on a filesystem that does not support symbolic -links. Instead of doing `readlink .git/HEAD`, `git-symbolic-ref -HEAD` can be used to find out which branch we are on. To point -the HEAD to `newbranch`, instead of `ln -sf refs/heads/newbranch -.git/HEAD`, `git-symbolic-ref HEAD refs/heads/newbranch` can be -used. - -Currently, .git/HEAD uses a regular file symbolic ref on Cygwin, -and everywhere else it is implemented as a symlink. This can be -changed at compilation time. +advertised (horrors). Therefore symbolic links are now deprecated +and symbolic refs are used by default. Author ------ diff --git a/builtin-diff.c b/builtin-diff.c index a6590205e8..1c535b1dd6 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -137,7 +137,7 @@ static int builtin_diff_index(struct rev_info *revs, int cached = 0; while (1 < argc) { const char *arg = argv[1]; - if (!strcmp(arg, "--cached")) + if (!strcmp(arg, "--index") || !strcmp(arg, "--cached")) cached = 1; else usage(builtin_diff_usage); diff --git a/builtin-ls-files.c b/builtin-ls-files.c index ad8c41e731..bc79ce40fc 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -487,10 +487,14 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix) for (num = 0; pathspec[num]; num++) { if (ps_matched[num]) continue; - error("pathspec '%s' did not match any.", + error("pathspec '%s' did not match any file(s) known to git.", pathspec[num] + prefix_offset); errors++; } + + if (errors) + fprintf(stderr, "Did you forget to 'git add'?\n"); + return errors ? 1 : 0; } diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 753bcd57b0..a2dc7d1d9d 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -514,6 +514,8 @@ static void write_pack_file(void) if (do_progress) fputc('\n', stderr); done: + if (written != nr_result) + die("wrote %d objects while expecting %d", written, nr_result); sha1close(f, pack_file_sha1, 1); } @@ -1662,7 +1664,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) } } if (progress) - fprintf(stderr, "Total %d, written %d (delta %d), reused %d (delta %d)\n", - nr_result, written, written_delta, reused, reused_delta); + fprintf(stderr, "Total %d (delta %d), reused %d (delta %d)\n", + written, written_delta, reused, reused_delta); return 0; } diff --git a/git-checkout.sh b/git-checkout.sh index 737abd0c09..5bf399a276 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -168,6 +168,9 @@ else exit 1 ;; esac + # First stash away the local changes + git diff-index --binary -p HEAD >"$GIT_DIR"/LOCAL_DIFF + # Match the index to the working tree, and do a three-way. git diff-files --name-only | git update-index --remove --stdin && work=`git write-tree` && @@ -195,6 +198,10 @@ else sed -e 's/^[0-7]* [0-9a-f]* /'"0 $z40 /" echo "$unmerged" ) | git update-index --index-info + + echo >&2 "Conflicts in locally modified files:" + git diff --name-only --diff-filter=U >&2 + echo >&2 "Your local changes are found in $GIT_DIR/LOCAL_DIFF" ;; esac exit 0 diff --git a/git-merge.sh b/git-merge.sh index 75af10d3e4..798aad3576 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -91,6 +91,51 @@ finish () { esac } +merge_local_changes () { + merge_error=$(git-read-tree -m -u $1 $2 2>&1) || ( + + # First stash away the local changes + git diff-index --binary -p HEAD >"$GIT_DIR"/LOCAL_DIFF + + # Match the index to the working tree, and do a three-way. + git diff-files --name-only | + git update-index --remove --stdin && + work=`git write-tree` && + git read-tree --reset -u $2 && + git read-tree -m -u --aggressive $1 $2 $work || exit + + echo >&2 "Carrying local changes forward." + if result=`git write-tree 2>/dev/null` + then + echo >&2 "Trivially automerged." + else + git merge-index -o git-merge-one-file -a + fi + + # Do not register the cleanly merged paths in the index + # yet; this is not a real merge before committing, but + # just carrying the working tree changes along. + unmerged=`git ls-files -u` + git read-tree --reset $2 + case "$unmerged" in + '') ;; + *) + ( + z40=0000000000000000000000000000000000000000 + echo "$unmerged" | + sed -e 's/^[0-7]* [0-9a-f]* /'"0 $z40 /" + echo "$unmerged" + ) | git update-index --index-info + + echo >&2 "Conflicts in locally modified files:" + git diff --name-only --diff-filter=U >&2 + echo >&2 "Your local changes are found in $GIT_DIR/LOCAL_DIFF" + ;; + esac + exit 0 + ) +} + case "$#" in 0) usage ;; esac rloga= have_message= @@ -189,13 +234,13 @@ else merge_name=$(for remote do rh=$(git-rev-parse --verify "$remote"^0 2>/dev/null) && - if git show-ref -q --verify "refs/heads/$remote" + bh=$(git show-ref -s --verify "refs/heads/$remote") && + if test "$rh" = "$bh" then - what=branch + echo "$rh branch '$remote' of ." else - what=commit - fi && - echo "$rh $what '$remote'" + echo "$rh commit '$remote'" + fi done | git-fmt-merge-msg ) merge_msg="${merge_msg:+$merge_msg$LF$LF}$merge_name" @@ -264,7 +309,7 @@ f,*) echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $1)" git-update-index --refresh 2>/dev/null new_head=$(git-rev-parse --verify "$1^0") && - git-read-tree -u -v -m $head "$new_head" && + merge_local_changes $head $new_head && finish "$new_head" "Fast forward" dropsave exit 0 diff --git a/git-svn.perl b/git-svn.perl index 3891122d73..d0bd0bdeb8 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -2982,7 +2982,7 @@ sub libsvn_fetch_delta { sub libsvn_fetch_full { my ($last_commit, $paths, $rev, $author, $date, $msg) = @_; open my $gui, '| git-update-index -z --index-info' or croak $!; - my @amr; + my %amr; my $p = $SVN->{svn_path}; foreach my $f (keys %$paths) { my $m = $paths->{$f}->action(); @@ -3001,7 +3001,7 @@ sub libsvn_fetch_full { my $t = $SVN->check_path($f, $rev, $pool); if ($t == $SVN::Node::file) { if ($m =~ /^[AMR]$/) { - push @amr, [ $m, $f ]; + $amr{$f} = $m; } else { die "Unrecognized action: $m, ($f r$rev)\n"; } @@ -3009,13 +3009,13 @@ sub libsvn_fetch_full { my @traversed = (); libsvn_traverse($gui, '', $f, $rev, \@traversed); foreach (@traversed) { - push @amr, [ $m, $_ ] + $amr{$_} = $m; } } $pool->clear; } - foreach (@amr) { - libsvn_get_file($gui, $_->[1], $rev, $_->[0]); + foreach (keys %amr) { + libsvn_get_file($gui, $_, $rev, $amr{$_}); } close $gui or croak $?; return libsvn_log_entry($rev, $author, $date, $msg, [$last_commit]); diff --git a/gitk b/gitk index ab383b3ad2..3dabc69516 100755 --- a/gitk +++ b/gitk @@ -554,7 +554,7 @@ proc makewindow {} { pack .ctop.top.lbar.vlabel -side left -fill y global viewhlmenu selectedhlview set viewhlmenu [tk_optionMenu .ctop.top.lbar.vhl selectedhlview None] - $viewhlmenu entryconf 0 -command delvhighlight + $viewhlmenu entryconf None -command delvhighlight $viewhlmenu conf -font $uifont .ctop.top.lbar.vhl conf -font $uifont pack .ctop.top.lbar.vhl -side left -fill y @@ -1474,7 +1474,7 @@ proc doviewmenu {m first cmd op argv} { proc allviewmenus {n op args} { global viewhlmenu - doviewmenu .bar.view 7 [list showview $n] $op $args + doviewmenu .bar.view 5 [list showview $n] $op $args doviewmenu $viewhlmenu 1 [list addvhighlight $n] $op $args } @@ -1516,7 +1516,7 @@ proc newviewok {top n} { set viewperm($n) $newviewperm($n) if {$newviewname($n) ne $viewname($n)} { set viewname($n) $newviewname($n) - doviewmenu .bar.view 7 [list showview $n] \ + doviewmenu .bar.view 5 [list showview $n] \ entryconf [list -label $viewname($n)] doviewmenu $viewhlmenu 1 [list addvhighlight $n] \ entryconf [list -label $viewname($n) -value $viewname($n)] @@ -1632,8 +1632,8 @@ proc showview {n} { set curview $n set selectedview $n - .bar.view entryconf 2 -state [expr {$n == 0? "disabled": "normal"}] - .bar.view entryconf 3 -state [expr {$n == 0? "disabled": "normal"}] + .bar.view entryconf Edit* -state [expr {$n == 0? "disabled": "normal"}] + .bar.view entryconf Delete* -state [expr {$n == 0? "disabled": "normal"}] if {![info exists viewdata($n)]} { set pending_select $selid @@ -4899,9 +4899,9 @@ proc rowmenu {x y id} { } else { set state normal } - $rowctxmenu entryconfigure 0 -state $state - $rowctxmenu entryconfigure 1 -state $state - $rowctxmenu entryconfigure 2 -state $state + $rowctxmenu entryconfigure "Diff this*" -state $state + $rowctxmenu entryconfigure "Diff selected*" -state $state + $rowctxmenu entryconfigure "Make patch" -state $state set rowmenuid $id tk_popup $rowctxmenu $x $y } @@ -6305,8 +6305,8 @@ if {$cmdline_files ne {} || $revtreeargs ne {}} { set viewargs(1) $revtreeargs set viewperm(1) 0 addviewmenu 1 - .bar.view entryconf 2 -state normal - .bar.view entryconf 3 -state normal + .bar.view entryconf Edit* -state normal + .bar.view entryconf Delete* -state normal } if {[info exists permviews]} {