From 733a65aa5d33196fac708ebd12a98a1060cbf3c2 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 13 Jun 2007 02:23:28 -0700 Subject: [PATCH 001/213] git-svn: allow dcommit to retain local merge information dcommit will still rewrite the HEAD commit and the history of the first parents of each HEAD~1, HEAD~2, HEAD~3 as it always has. However, any merge parents (HEAD^2, HEAD^^2, HEAD~2^2) will now be preserved when the new HEAD and HEAD~[0-9]+ commits are rewritten to SVN with dcommit. Commits written to SVN will still not have any merge information besides anything in the commit message. Thanks to Joakim Tjernlund, Junio C Hamano and Steven Grimm for explanations, feedback, examples and test case. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 72 ++++++++++++++++++++++---- t/t9114-git-svn-dcommit-merge.sh | 89 ++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 9 deletions(-) create mode 100755 t/t9114-git-svn-dcommit-merge.sh diff --git a/git-svn.perl b/git-svn.perl index 0ae8d70de1..42906767a1 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -372,16 +372,9 @@ sub cmd_dcommit { die "Unable to determine upstream SVN information from ", "$head history\n"; } - my $c = $refs[-1]; my $last_rev; - foreach my $d (@refs) { - if (!verify_ref("$d~1")) { - fatal "Commit $d\n", - "has no parent commit, and therefore ", - "nothing to diff against.\n", - "You should be working from a repository ", - "originally created by git-svn\n"; - } + my ($linear_refs, $parents) = linearize_history($gs, \@refs); + foreach my $d (@$linear_refs) { unless (defined $last_rev) { (undef, $last_rev, undef) = cmt_metadata("$d~1"); unless (defined $last_rev) { @@ -403,6 +396,9 @@ sub cmd_dcommit { svn_path => ''); if (!SVN::Git::Editor->new(\%ed_opts)->apply_diff) { print "No changes\n$d~1 == $d\n"; + } elsif ($parents->{$d} && @{$parents->{$d}}) { + $gs->{inject_parents_dcommit}->{$last_rev} = + $parents->{$d}; } } } @@ -821,6 +817,59 @@ sub working_head_info { (undef, undef, undef, undef); } +sub read_commit_parents { + my ($parents, $c) = @_; + my ($fh, $ctx) = command_output_pipe(qw/cat-file commit/, $c); + while (<$fh>) { + chomp; + last if ''; + /^parent ($sha1)/ or next; + push @{$parents->{$c}}, $1; + } + close $fh; # break the pipe +} + +sub linearize_history { + my ($gs, $refs) = @_; + my %parents; + foreach my $c (@$refs) { + read_commit_parents(\%parents, $c); + } + + my @linear_refs; + my %skip = (); + my $last_svn_commit = $gs->last_commit; + foreach my $c (reverse @$refs) { + next if $c eq $last_svn_commit; + last if $skip{$c}; + + unshift @linear_refs, $c; + $skip{$c} = 1; + + # we only want the first parent to diff against for linear + # history, we save the rest to inject when we finalize the + # svn commit + my $fp_a = verify_ref("$c~1"); + my $fp_b = shift @{$parents{$c}} if $parents{$c}; + if (!$fp_a || !$fp_b) { + die "Commit $c\n", + "has no parent commit, and therefore ", + "nothing to diff against.\n", + "You should be working from a repository ", + "originally created by git-svn\n"; + } + if ($fp_a ne $fp_b) { + die "$c~1 = $fp_a, however parsing commit $c ", + "revealed that:\n$c~1 = $fp_b\nBUG!\n"; + } + + foreach my $p (@{$parents{$c}}) { + $skip{$p} = 1; + } + } + (\@linear_refs, \%parents); +} + package Git::SVN; use strict; use warnings; @@ -1541,6 +1590,11 @@ sub get_commit_parents { if (my $cur = ::verify_ref($self->refname.'^0')) { push @tmp, $cur; } + if (my $ipd = $self->{inject_parents_dcommit}) { + if (my $commit = delete $ipd->{$log_entry->{revision}}) { + push @tmp, @$commit; + } + } push @tmp, $_ foreach (@{$log_entry->{parents}}, @tmp); while (my $p = shift @tmp) { next if $seen{$p}; diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh new file mode 100755 index 0000000000..d6ca955081 --- /dev/null +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# +# Copyright (c) 2007 Eric Wong +# Based on a script by Joakim Tjernlund + +test_description='git-svn dcommit handles merges' + +. ./lib-git-svn.sh + +big_text_block () { +cat << EOF +# +# (C) Copyright 2000 - 2005 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +EOF +} + +test_expect_success 'setup svn repository' " + svn co $svnrepo mysvnwork && + mkdir -p mysvnwork/trunk && + cd mysvnwork && + big_text_block >> trunk/README && + svn add trunk && + svn ci -m 'first commit' trunk && + cd .. + " + +test_expect_success 'setup git mirror and merge' " + git svn init $svnrepo -t tags -T trunk -b branches && + git svn fetch && + git checkout --track -b svn remotes/trunk && + git checkout -b merge && + echo new file > new_file && + git add new_file && + git commit -a -m 'New file' && + echo hello >> README && + git commit -a -m 'hello' && + echo add some stuff >> new_file && + git commit -a -m 'add some stuff' && + git checkout svn && + mv -f README tmp && + echo friend > README && + cat tmp >> README && + git commit -a -m 'friend' && + git pull . merge + " + +test_debug 'gitk --all & sleep 1' + +test_expect_success 'verify pre-merge ancestry' " + test x\`git rev-parse --verify refs/heads/svn^2\` = \ + x\`git rev-parse --verify refs/heads/merge\` && + git cat-file commit refs/heads/svn^ | grep '^friend$' + " + +test_expect_success 'git svn dcommit merges' " + git svn dcommit + " + +test_debug 'gitk --all & sleep 1' + +test_expect_success 'verify post-merge ancestry' " + test x\`git rev-parse --verify refs/heads/svn\` = \ + x\`git rev-parse --verify refs/remotes/trunk \` && + test x\`git rev-parse --verify refs/heads/svn^2\` = \ + x\`git rev-parse --verify refs/heads/merge\` && + git cat-file commit refs/heads/svn^ | grep '^friend$' + " + +test_done From 9378c16135100fb65ad575cd35074af166de1cab Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 24 Jun 2007 15:11:24 -0700 Subject: [PATCH 002/213] Add core.quotepath configuration variable. We always quote "unusual" byte values in a pathname using C-string style, to make it safer for parsing scripts that do not handle NUL separated records well (or just too lazy to bother). The absolute minimum bytes that need to be quoted for this purpose are TAB, LF (and other control characters), double quote and backslash. However, we have also always quoted the bytes in high 8-bit range; this was partly because we were lazy and partly because we were being cautious. This introduces an internal "quote_path_fully" variable, and core.quotepath configuration variable to control it. When set to false, it does not quote bytes in high 8-bit range anymore but passes them intact. The variable defaults to "true" to retain the traditional behaviour for now. Signed-off-by: Junio C Hamano --- Documentation/config.txt | 12 ++++ cache.h | 1 + config.c | 5 ++ environment.c | 1 + quote.c | 5 +- t/t3902-quoted.sh | 126 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 148 insertions(+), 2 deletions(-) create mode 100755 t/t3902-quoted.sh diff --git a/Documentation/config.txt b/Documentation/config.txt index a2057d9d24..34b1c97102 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -117,6 +117,18 @@ core.fileMode:: the working copy are ignored; useful on broken filesystems like FAT. See gitlink:git-update-index[1]. True by default. +core.quotepath:: + The commands that output paths (e.g. `ls-files`, + `diff`), when not given the `-z` option, will quote + "unusual" characters in the pathname by enclosing the + pathname in a double-quote pair and with backslashes the + same way strings in C source code are quoted. If this + variable is set to false, the bytes higher than 0x80 are + not quoted but output as verbatim. Note that double + quote, backslash and control characters are always + quoted without `-z` regardless of the setting of this + variable. + core.autocrlf:: If true, makes git convert `CRLF` at the end of lines in text files to `LF` when reading from the filesystem, and convert in reverse when diff --git a/cache.h b/cache.h index ed83d92c5a..67763571b5 100644 --- a/cache.h +++ b/cache.h @@ -292,6 +292,7 @@ extern int delete_ref(const char *, const unsigned char *sha1); /* Environment bits from configuration mechanism */ extern int trust_executable_bit; +extern int quote_path_fully; extern int has_symlinks; extern int assume_unchanged; extern int prefer_symlink_refs; diff --git a/config.c b/config.c index e323153ae4..4de8926330 100644 --- a/config.c +++ b/config.c @@ -271,6 +271,11 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.quotepath")) { + quote_path_fully = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.symlinks")) { has_symlinks = git_config_bool(var, value); return 0; diff --git a/environment.c b/environment.c index 8b9b89d0a0..1c2773f1bd 100644 --- a/environment.c +++ b/environment.c @@ -12,6 +12,7 @@ char git_default_email[MAX_GITNAME]; char git_default_name[MAX_GITNAME]; int trust_executable_bit = 1; +int quote_path_fully = 1; int has_symlinks = 1; int assume_unchanged; int prefer_symlink_refs; diff --git a/quote.c b/quote.c index aa440098e1..d88bf75159 100644 --- a/quote.c +++ b/quote.c @@ -188,7 +188,8 @@ static int quote_c_style_counted(const char *name, int namelen, #define EMITQ() EMIT('\\') const char *sp; - int ch, count = 0, needquote = 0; + unsigned char ch; + int count = 0, needquote = 0; if (!no_dq) EMIT('"'); @@ -197,7 +198,7 @@ static int quote_c_style_counted(const char *name, int namelen, if (!ch) break; if ((ch < ' ') || (ch == '"') || (ch == '\\') || - (ch >= 0177)) { + (quote_path_fully && (ch >= 0177))) { needquote = 1; switch (ch) { case '\a': EMITQ(); ch = 'a'; break; diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh new file mode 100755 index 0000000000..63f950b179 --- /dev/null +++ b/t/t3902-quoted.sh @@ -0,0 +1,126 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='quoted output' + +. ./test-lib.sh + +FN='濱野' +GN='純' +HT=' ' +LF=' +' +DQ='"' + +for_each_name () { + for name in \ + Name "Name and a${LF}LF" "Name and an${HT}HT" "Name${DQ}" \ + "$FN$HT$GN" "$FN$LF$GN" "$FN $GN" "$FN$GN" "$FN$DQ$GN" \ + "With SP in it" + do + eval "$1" + done +} + +test_expect_success setup ' + + for_each_name "echo initial >\"\$name\"" + git add . && + git commit -q -m Initial && + + for_each_name "echo second >\"\$name\"" && + git commit -a -m Second + + for_each_name "echo modified >\"\$name\"" + +' + +cat >expect.quoted <<\EOF +Name +"Name and a\nLF" +"Name and an\tHT" +"Name\"" +With SP in it +"\346\277\261\351\207\216\t\347\264\224" +"\346\277\261\351\207\216\n\347\264\224" +"\346\277\261\351\207\216 \347\264\224" +"\346\277\261\351\207\216\"\347\264\224" +"\346\277\261\351\207\216\347\264\224" +EOF + +cat >expect.raw <<\EOF +Name +"Name and a\nLF" +"Name and an\tHT" +"Name\"" +With SP in it +"濱野\t純" +"濱野\n純" +濱野 純 +"濱野\"純" +濱野純 +EOF + +test_expect_success 'check fully quoted output from ls-files' ' + + git ls-files >current && diff -u expect.quoted current + +' + +test_expect_success 'check fully quoted output from diff-files' ' + + git diff --name-only >current && + diff -u expect.quoted current + +' + +test_expect_success 'check fully quoted output from diff-index' ' + + git diff --name-only HEAD >current && + diff -u expect.quoted current + +' + +test_expect_success 'check fully quoted output from diff-tree' ' + + git diff --name-only HEAD^ HEAD >current && + diff -u expect.quoted current + +' + +test_expect_success 'setting core.quotepath' ' + + git config --bool core.quotepath false + +' + +test_expect_success 'check fully quoted output from ls-files' ' + + git ls-files >current && diff -u expect.raw current + +' + +test_expect_success 'check fully quoted output from diff-files' ' + + git diff --name-only >current && + diff -u expect.raw current + +' + +test_expect_success 'check fully quoted output from diff-index' ' + + git diff --name-only HEAD >current && + diff -u expect.raw current + +' + +test_expect_success 'check fully quoted output from diff-tree' ' + + git diff --name-only HEAD^ HEAD >current && + diff -u expect.raw current + +' + +test_done From 0cae23467ada9b94210a0e770064841efea8ad40 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 25 Jun 2007 01:04:11 +0100 Subject: [PATCH 003/213] Move the pick_author code to git-sh-setup At the moment, only git-commit uses that code, to pick the author name, email and date from a given commit. This code will be reused in git rebase --interactive. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-commit.sh | 30 ++---------------------------- git-sh-setup.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/git-commit.sh b/git-commit.sh index 5547a02954..d43bdd87c0 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -483,34 +483,8 @@ fi >>"$GIT_DIR"/COMMIT_EDITMSG # Author if test '' != "$use_commit" then - pick_author_script=' - /^author /{ - s/'\''/'\''\\'\'\''/g - h - s/^author \([^<]*\) <[^>]*> .*$/\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_AUTHOR_NAME='\''&'\''/p - - g - s/^author [^<]* <\([^>]*\)> .*$/\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p - - g - s/^author [^<]* <[^>]*> \(.*\)$/\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_AUTHOR_DATE='\''&'\''/p - - q - } - ' - encoding=$(git config i18n.commitencoding || echo UTF-8) - set_author_env=`git show -s --pretty=raw --encoding="$encoding" "$use_commit" | - LANG=C LC_ALL=C sed -ne "$pick_author_script"` - eval "$set_author_env" - export GIT_AUTHOR_NAME - export GIT_AUTHOR_EMAIL - export GIT_AUTHOR_DATE + eval "$(get_author_ident_from_commit "$use_commit")" + export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE fi if test '' != "$force_author" then diff --git a/git-sh-setup.sh b/git-sh-setup.sh index f24c7f2d23..d861db3b28 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -53,6 +53,33 @@ require_work_tree () { die "fatal: $0 cannot be used without a working tree." } +get_author_ident_from_commit () { + pick_author_script=' + /^author /{ + s/'\''/'\''\\'\'\''/g + h + s/^author \([^<]*\) <[^>]*> .*$/\1/ + s/'\''/'\''\'\'\''/g + s/.*/GIT_AUTHOR_NAME='\''&'\''/p + + g + s/^author [^<]* <\([^>]*\)> .*$/\1/ + s/'\''/'\''\'\'\''/g + s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p + + g + s/^author [^<]* <[^>]*> \(.*\)$/\1/ + s/'\''/'\''\'\'\''/g + s/.*/GIT_AUTHOR_DATE='\''&'\''/p + + q + } + ' + encoding=$(git config i18n.commitencoding || echo UTF-8) + git show -s --pretty=raw --encoding="$encoding" "$1" | + LANG=C LC_ALL=C sed -ne "$pick_author_script" +} + if [ -z "$LONG_USAGE" ] then LONG_USAGE="Usage: $0 $USAGE" From 1b1dce4bae760248a1fc3e29548a72c446e77270 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 25 Jun 2007 01:11:14 +0100 Subject: [PATCH 004/213] Teach rebase an interactive mode Don't you just hate the fact sometimes, that git-rebase just applies the patches, without any possibility to edit them, or rearrange them? With "--interactive", git-rebase now lets you edit the list of patches, so that you can reorder, edit and delete patches. Such a list will typically look like this: pick deadbee The oneline of this commit pick fa1afe1 The oneline of the next commit ... By replacing the command "pick" with the command "edit", you can amend that patch and/or its commit message, and by replacing it with "squash" you can tell rebase to fold that patch into the patch before that. It is derived from the script sent to the list in Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-rebase.txt | 85 +++++++++- Makefile | 2 +- git-rebase--interactive.sh | 289 ++++++++++++++++++++++++++++++++++ git-rebase.sh | 12 +- t/t3404-rebase-interactive.sh | 163 +++++++++++++++++++ 5 files changed, 546 insertions(+), 5 deletions(-) create mode 100755 git-rebase--interactive.sh create mode 100755 t/t3404-rebase-interactive.sh diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 0c00090a6b..2e3363a617 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -8,7 +8,8 @@ git-rebase - Forward-port local commits to the updated upstream head SYNOPSIS -------- [verse] -'git-rebase' [-v] [--merge] [-C] [--onto ] [] +'git-rebase' [-i | --interactive] [-v | --verbose] [--merge] [-C] + [--onto ] [] 'git-rebase' --continue | --skip | --abort DESCRIPTION @@ -208,6 +209,10 @@ OPTIONS context exist they all must match. By default no context is ever ignored. +-i, \--interactive:: + Make a list of the commits which are about to be rebased. Let the + user edit that list before rebasing. + include::merge-strategies.txt[] NOTES @@ -226,9 +231,83 @@ pre-rebase hook script for an example. You must be in the top directory of your project to start (or continue) a rebase. Upon completion, will be the current branch. -Author +INTERACTIVE MODE +---------------- + +Rebasing interactively means that you have a chance to edit the commits +which are rebased. You can reorder the commits, and you can +remove them (weeding out bad or otherwise unwanted patches). + +The interactive mode is meant for this type of workflow: + +1. have a wonderful idea +2. hack on the code +3. prepare a series for submission +4. submit + +where point 2. consists of several instances of + +a. regular use + 1. finish something worthy of a commit + 2. commit +b. independent fixup + 1. realize that something does not work + 2. fix that + 3. commit it + +Sometimes the thing fixed in b.2. cannot be amended to the not-quite +perfect commit it fixes, because that commit is buried deeply in a +patch series. That is exactly what interactive rebase is for: use it +after plenty of "a"s and "b"s, by rearranging and editing +commits, and squashing multiple commits into one. + +Start it with the last commit you want to retain as-is: + + git rebase -i + +An editor will be fired up with all the commits in your current branch +(ignoring merge commits), which come after the given commit. You can +reorder the commits in this list to your heart's content, and you can +remove them. The list looks more or less like this: + +------------------------------------------- +pick deadbee The oneline of this commit +pick fa1afe1 The oneline of the next commit +... +------------------------------------------- + +The oneline descriptions are purely for your pleasure; `git-rebase` will +not look at them but at the commit names ("deadbee" and "fa1afe1" in this +example), so do not delete or edit the names. + +By replacing the command "pick" with the command "edit", you can tell +`git-rebase` to stop after applying that commit, so that you can edit +the files and/or the commit message, amend the commit, and continue +rebasing. + +If you want to fold two or more commits into one, replace the command +"pick" with "squash" for the second and subsequent commit. If the +commits had different authors, it will attribute the squashed commit to +the author of the last commit. + +In both cases, or when a "pick" does not succeed (because of merge +errors), the loop will stop to let you fix things, and you can continue +the loop with `git rebase --continue`. + +For example, if you want to reorder the last 5 commits, such that what +was HEAD~4 becomes the new HEAD. To achieve that, you would call +`git-rebase` like this: + +---------------------- +$ git rebase -i HEAD~5 +---------------------- + +And move the first patch to the end of the list. + +Authors ------ -Written by Junio C Hamano +Written by Junio C Hamano and +Johannes E. Schindelin Documentation -------------- diff --git a/Makefile b/Makefile index a98e27aa7e..4ea5e450bd 100644 --- a/Makefile +++ b/Makefile @@ -204,7 +204,7 @@ SCRIPT_SH = \ git-fetch.sh \ git-ls-remote.sh \ git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \ - git-pull.sh git-rebase.sh \ + git-pull.sh git-rebase.sh git-rebase--interactive.sh \ git-repack.sh git-request-pull.sh git-reset.sh \ git-sh-setup.sh \ git-tag.sh git-verify-tag.sh \ diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh new file mode 100755 index 0000000000..ab3657250e --- /dev/null +++ b/git-rebase--interactive.sh @@ -0,0 +1,289 @@ +#!/bin/sh +# +# Copyright (c) 2006 Johannes E. Schindelin + +# SHORT DESCRIPTION +# +# This script makes it easy to fix up commits in the middle of a series, +# and rearrange commits. +# +# The original idea comes from Eric W. Biederman, in +# http://article.gmane.org/gmane.comp.version-control.git/22407 + +USAGE='(--continue | --abort | --skip | [--onto ] [])' + +. git-sh-setup +require_work_tree + +DOTEST="$GIT_DIR/.dotest-merge" +TODO="$DOTEST"/todo +DONE="$DOTEST"/done +STRATEGY= +VERBOSE= + +warn () { + echo "$*" >&2 +} + +require_clean_work_tree () { + # test if working tree is dirty + git rev-parse --verify HEAD > /dev/null && + git update-index --refresh && + git diff-files --quiet && + git diff-index --cached --quiet HEAD || + die "Working tree is dirty" +} + +ORIG_REFLOG_ACTION="$GIT_REFLOG_ACTION" + +comment_for_reflog () { + case "$ORIG_REFLOG_ACTION" in + ''|rebase*) + GIT_REFLOG_ACTION="rebase -i ($1)" + export GIT_REFLOG_ACTION + esac +} + +mark_action_done () { + sed -e 1q < "$TODO" >> "$DONE" + sed -e 1d < "$TODO" >> "$TODO".new + mv -f "$TODO".new "$TODO" +} + +make_patch () { + parent_sha1=$(git rev-parse --verify "$1"^ 2> /dev/null) + git diff "$parent_sha1".."$1" > "$DOTEST"/patch +} + +die_with_patch () { + make_patch "$1" + die "$2" +} + +pick_one () { + case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac + git rev-parse --verify $sha1 || die "Invalid commit name: $sha1" + parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null) + current_sha1=$(git rev-parse --verify HEAD) + if [ $current_sha1 = $parent_sha1 ]; then + git reset --hard $sha1 + sha1=$(git rev-parse --short $sha1) + warn Fast forward to $sha1 + else + git cherry-pick $STRATEGY "$@" + fi +} + +do_next () { + read command sha1 rest < "$TODO" + case "$command" in + \#|'') + mark_action_done + continue + ;; + pick) + comment_for_reflog pick + + mark_action_done + pick_one $sha1 || + die_with_patch $sha1 "Could not apply $sha1... $rest" + ;; + edit) + comment_for_reflog edit + + mark_action_done + pick_one $sha1 || + die_with_patch $sha1 "Could not apply $sha1... $rest" + make_patch $sha1 + warn + warn "You can amend the commit now, with" + warn + warn " git commit --amend" + warn + exit 0 + ;; + squash) + comment_for_reflog squash + + test -z "$(grep -ve '^$' -e '^#' < $DONE)" && + die "Cannot 'squash' without a previous commit" + + mark_action_done + failed=f + pick_one -n $sha1 || failed=t + MSG="$DOTEST"/message + echo "# This is a combination of two commits." > "$MSG" + echo "# The first commit's message is:" >> "$MSG" + echo >> "$MSG" + git cat-file commit HEAD | sed -e '1,/^$/d' >> "$MSG" + echo >> "$MSG" + echo "# And this is the 2nd commit message:" >> "$MSG" + echo >> "$MSG" + git cat-file commit $sha1 | sed -e '1,/^$/d' >> "$MSG" + git reset --soft HEAD^ + author_script=$(get_author_ident_from_commit $sha1) + case $failed in + f) + # This is like --amend, but with a different message + eval "$author_script" + export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE + git commit -F "$MSG" -e + ;; + t) + cp "$MSG" "$GIT_DIR"/MERGE_MSG + warn + warn "Could not apply $sha1... $rest" + warn "After you fixed that, commit the result with" + warn + warn " $(echo $author_script | tr '\012' ' ') \\" + warn " git commit -F \"$GIT_DIR\"/MERGE_MSG -e" + die_with_patch $sha1 "" + esac + ;; + *) + warn "Unknown command: $command $sha1 $rest" + die_with_patch $sha1 "Please fix this in the file $TODO." + esac + test -s "$TODO" && return + + HEAD=$(git rev-parse HEAD) + HEADNAME=$(cat "$DOTEST"/head-name) + rm -rf "$DOTEST" && + warn "Successfully rebased and updated $HEADNAME." + + exit +} + +do_rest () { + while : + do + do_next + done + test -f "$DOTEST"/verbose && + git diff --stat $(cat "$DOTEST"/head)..HEAD + exit +} + +while case $# in 0) break ;; esac +do + case "$1" in + --continue) + comment_for_reflog continue + + test -d "$DOTEST" || die "No interactive rebase running" + + require_clean_work_tree + do_rest + ;; + --abort) + comment_for_reflog abort + + test -d "$DOTEST" || die "No interactive rebase running" + + HEADNAME=$(cat "$DOTEST"/head-name) + HEAD=$(cat "$DOTEST"/head) + git symbolic-ref HEAD $HEADNAME && + git reset --hard $HEAD && + rm -rf "$DOTEST" + exit + ;; + --skip) + comment_for_reflog skip + + test -d "$DOTEST" || die "No interactive rebase running" + + git reset --hard && do_rest + ;; + -s|--strategy) + shift + case "$#,$1" in + *,*=*) + STRATEGY="-s `expr "z$1" : 'z-[^=]*=\(.*\)'`" ;; + 1,*) + usage ;; + *) + STRATEGY="-s $2" + shift ;; + esac + ;; + --merge) + # we use merge anyway + ;; + -C*) + die "Interactive rebase uses merge, so $1 does not make sense" + ;; + -v) + VERBOSE=t + ;; + -i|--interactive) + # yeah, we know + ;; + ''|-h) + usage + ;; + *) + test -d "$DOTEST" && + die "Interactive rebase already started" + + git var GIT_COMMITTER_IDENT >/dev/null || + die "You need to set your committer info first" + + comment_for_reflog start + + ONTO= + case "$1" in + --onto) + ONTO=$(git rev-parse --verify "$2") || + die "Does not point to a valid commit: $2" + shift; shift + ;; + esac + + require_clean_work_tree + + if [ ! -z "$2"] + then + git show-ref --verify --quiet "refs/heads/$2" || + die "Invalid branchname: $2" + git checkout "$2" || + die "Could not checkout $2" + fi + + HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?" + UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base" + + test -z "$ONTO" && ONTO=$UPSTREAM + + mkdir "$DOTEST" || die "Could not create temporary $DOTEST" + : > "$DOTEST"/interactive || die "Could not mark as interactive" + git symbolic-ref HEAD > "$DOTEST"/head-name || + die "Could not get HEAD" + + echo $HEAD > "$DOTEST"/head + echo $UPSTREAM > "$DOTEST"/upstream + echo $ONTO > "$DOTEST"/onto + test t = "$VERBOSE" && : > "$DOTEST"/verbose + + cat > "$TODO" << EOF +# Rebasing $UPSTREAM..$HEAD onto $ONTO +# +# Commands: +# pick = use commit +# edit = use commit, but stop for amending +# squash = use commit, but meld into previous commit +EOF + git rev-list --no-merges --pretty=oneline --abbrev-commit \ + --abbrev=7 --reverse $UPSTREAM..$HEAD | \ + sed "s/^/pick /" >> "$TODO" + + test -z "$(grep -ve '^$' -e '^#' < $TODO)" && + die "Nothing to do" + + cp "$TODO" "$TODO".backup + ${VISUAL:-${EDITOR:-vi}} "$TODO" || + die "Could not execute editor" + + git reset --hard $ONTO && do_rest + esac + shift +done diff --git a/git-rebase.sh b/git-rebase.sh index 2aa3a011db..388752661f 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano. # -USAGE='[-v] [--onto ] []' +USAGE='[--interactive | -i] [-v] [--onto ] []' LONG_USAGE='git-rebase replaces with a new branch of the same name. When the --onto option is provided the new branch starts out with a HEAD equal to , otherwise it is equal to @@ -120,6 +120,16 @@ finish_rb_merge () { echo "All done." } +is_interactive () { + test -f "$dotest"/interactive || + while case $#,"$1" in 0,|*,-i|*,--interactive) break ;; esac + do + shift + done && test -n "$1" +} + +is_interactive "$@" && exec git-rebase--interactive "$@" + while case "$#" in 0) break ;; esac do case "$1" in diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh new file mode 100755 index 0000000000..48aa8ea814 --- /dev/null +++ b/t/t3404-rebase-interactive.sh @@ -0,0 +1,163 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='git rebase interactive + +This test runs git rebase "interactively", by faking an edit, and verifies +that the result still makes sense. +' +. ./test-lib.sh + +# set up two branches like this: +# +# A - B - C - D - E +# \ +# F - G - H +# \ +# I +# +# where B, D and G touch the same file. + +test_expect_success 'setup' ' + : > file1 && + git add file1 && + test_tick && + git commit -m A && + git tag A && + echo 1 > file1 && + test_tick && + git commit -m B file1 && + : > file2 && + git add file2 && + test_tick && + git commit -m C && + echo 2 > file1 && + test_tick && + git commit -m D file1 && + : > file3 && + git add file3 && + test_tick && + git commit -m E && + git checkout -b branch1 A && + : > file4 && + git add file4 && + test_tick && + git commit -m F && + git tag F && + echo 3 > file1 && + test_tick && + git commit -m G file1 && + : > file5 && + git add file5 && + test_tick && + git commit -m H && + git checkout -b branch2 F && + : > file6 && + git add file6 && + test_tick && + git commit -m I && + git tag I +' + +cat > fake-editor.sh << EOF +#!/bin/sh +test "\$1" = .git/COMMIT_EDITMSG && exit +test -z "\$FAKE_LINES" && exit +grep -v "^#" < "\$1" > "\$1".tmp +rm "\$1" +cat "\$1".tmp +action=pick +for line in \$FAKE_LINES; do + case \$line in + squash) + action="\$line";; + *) + echo sed -n "\${line}s/^pick/\$action/p" + sed -n "\${line}p" < "\$1".tmp + sed -n "\${line}s/^pick/\$action/p" < "\$1".tmp >> "\$1" + action=pick;; + esac +done +EOF + +chmod a+x fake-editor.sh +VISUAL="$(pwd)/fake-editor.sh" +export VISUAL + +test_expect_success 'no changes are a nop' ' + git rebase -i F && + test $(git rev-parse I) = $(git rev-parse HEAD) +' + +test_expect_success 'rebase on top of a non-conflicting commit' ' + git checkout branch1 && + git tag original-branch1 && + git rebase -i branch2 && + test file6 = $(git diff --name-only original-branch1) && + test $(git rev-parse I) = $(git rev-parse HEAD~2) +' + +test_expect_success 'exchange two commits' ' + FAKE_LINES="2 1" git rebase -i HEAD~2 && + test H = $(git cat-file commit HEAD^ | tail -n 1) && + test G = $(git cat-file commit HEAD | tail -n 1) +' + +cat > expect << EOF +diff --git a/file1 b/file1 +index e69de29..00750ed 100644 +--- a/file1 ++++ b/file1 +@@ -0,0 +1 @@ ++3 +EOF + +cat > expect2 << EOF +<<<<<<< HEAD:file1 +2 +======= +3 +>>>>>>> b7ca976... G:file1 +EOF + +test_expect_success 'stop on conflicting pick' ' + git tag new-branch1 && + ! git rebase -i master && + diff -u expect .git/.dotest-merge/patch && + diff -u expect2 file1 && + test 4 = $(grep -v "^#" < .git/.dotest-merge/done | wc -l) && + test 0 = $(grep -v "^#" < .git/.dotest-merge/todo | wc -l) +' + +test_expect_success 'abort' ' + git rebase --abort && + test $(git rev-parse new-branch1) = $(git rev-parse HEAD) && + ! test -d .git/.dotest-merge +' + +test_expect_success 'retain authorship' ' + echo A > file7 && + git add file7 && + GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" && + git tag twerp && + git rebase -i --onto master HEAD^ && + git show HEAD | grep "^Author: Twerp Snog" +' + +test_expect_success 'squash' ' + git reset --hard twerp && + echo B > file7 && + GIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 && + echo "******************************" && + FAKE_LINES="1 squash 2" git rebase -i --onto master HEAD~2 && + test B = $(cat file7) && + test $(git rev-parse HEAD^) = $(git rev-parse master) +' + +test_expect_success 'retain authorship when squashing' ' + git show HEAD | grep "^Author: Nitfol" +' + +test_done From cfc0aef1ffb8a9fe2792667597a05bbf3b6b1258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Mon, 25 Jun 2007 00:23:28 +0200 Subject: [PATCH 005/213] diffcore-rename: don't change similarity index based on basename equality This implements a suggestion from Johannes. It uses a separate field in struct diff_score to keep the result of the file name comparison in the rename detection logic. This reverts the value of the similarity index to be a function of file contents, only, and basename comparison is only used to decide between files with equal amounts of content changes. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- diffcore-rename.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/diffcore-rename.c b/diffcore-rename.c index 79c984c9cf..e0a89f3796 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -138,6 +138,7 @@ struct diff_score { int src; /* index in rename_src */ int dst; /* index in rename_dst */ int score; + int name_score; }; static int estimate_similarity(struct diff_filespec *src, @@ -201,11 +202,8 @@ static int estimate_similarity(struct diff_filespec *src, */ if (!dst->size) score = 0; /* should not happen */ - else { + else score = (int)(src_copied * MAX_SCORE / max_size); - if (basename_same(src, dst)) - score++; - } return score; } @@ -242,6 +240,10 @@ static void record_rename_pair(int dst_index, int src_index, int score) static int score_compare(const void *a_, const void *b_) { const struct diff_score *a = a_, *b = b_; + + if (a->score == b->score) + return b->name_score - a->name_score; + return b->score - a->score; } @@ -360,6 +362,7 @@ void diffcore_rename(struct diff_options *options) m->dst = i; m->score = estimate_similarity(one, two, minimum_score); + m->name_score = basename_same(one, two); diff_free_filespec_data(one); } /* We do not need the text anymore */ From 125b7630521918b75c136bd95309054d3f6d9da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Mon, 25 Jun 2007 00:23:34 +0200 Subject: [PATCH 006/213] diff: round down similarity index Rounding down the printed (dis)similarity index allows us to use "100%" as a special value that indicates complete rewrites and fully equal file contents, respectively. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- Documentation/diff-format.txt | 7 +++++++ diff.c | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index 18d49d2c3b..001503205b 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -126,6 +126,13 @@ the file that rename/copy produces, respectively. If there is need for such substitution then the whole pathname is put in double quotes. +The similarity index is the percentage of unchanged lines, and +the dissimilarity index is the percentage of changed lines. It +is a rounded down integer, followed by a percent sign. The +similarity index value of 100% is thus reserved for two equal +files, while 100% dissimilarity means that no line from the old +file made it into the new one. + combined diff format -------------------- diff --git a/diff.c b/diff.c index 9938969fa5..e0edb98846 100644 --- a/diff.c +++ b/diff.c @@ -1813,6 +1813,11 @@ static void diff_fill_sha1_info(struct diff_filespec *one) hashclr(one->sha1); } +static int similarity_index(struct diff_filepair *p) +{ + return p->score * 100 / MAX_SCORE; +} + static void run_diff(struct diff_filepair *p, struct diff_options *o) { const char *pgm = external_diff(); @@ -1847,23 +1852,20 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) "similarity index %d%%\n" "copy from %s\n" "copy to %s\n", - (int)(0.5 + p->score * 100.0/MAX_SCORE), - name_munged, other_munged); + similarity_index(p), name_munged, other_munged); break; case DIFF_STATUS_RENAMED: len += snprintf(msg + len, sizeof(msg) - len, "similarity index %d%%\n" "rename from %s\n" "rename to %s\n", - (int)(0.5 + p->score * 100.0/MAX_SCORE), - name_munged, other_munged); + similarity_index(p), name_munged, other_munged); break; case DIFF_STATUS_MODIFIED: if (p->score) { len += snprintf(msg + len, sizeof(msg) - len, "dissimilarity index %d%%\n", - (int)(0.5 + p->score * - 100.0/MAX_SCORE)); + similarity_index(p)); complete_rewrite = 1; break; } @@ -2387,8 +2389,7 @@ static void diff_flush_raw(struct diff_filepair *p, } if (p->score) - sprintf(status, "%c%03d", p->status, - (int)(0.5 + p->score * 100.0/MAX_SCORE)); + sprintf(status, "%c%03d", p->status, similarity_index(p)); else { status[0] = p->status; status[1] = 0; @@ -2670,8 +2671,7 @@ static void show_rename_copy(const char *renamecopy, struct diff_filepair *p) { char *names = pprint_rename(p->one->path, p->two->path); - printf(" %s %s (%d%%)\n", renamecopy, names, - (int)(0.5 + p->score * 100.0/MAX_SCORE)); + printf(" %s %s (%d%%)\n", renamecopy, names, similarity_index(p)); free(names); show_mode_change(p, 0); } @@ -2695,7 +2695,7 @@ static void diff_summary(struct diff_filepair *p) if (p->score) { char *name = quote_one(p->two->path); printf(" rewrite %s (%d%%)\n", name, - (int)(0.5 + p->score * 100.0/MAX_SCORE)); + similarity_index(p)); free(name); show_mode_change(p, 0); } else show_mode_change(p, 1); From ad562a817256adff4faadc17900b4aba67ca471a Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Tue, 26 Jun 2007 15:38:42 +0200 Subject: [PATCH 007/213] ignore git-rebase--interactive Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e8b060cbe4..a2a617dc62 100644 --- a/.gitignore +++ b/.gitignore @@ -96,6 +96,7 @@ git-push git-quiltimport git-read-tree git-rebase +git-rebase--interactive git-receive-pack git-reflog git-relink From c54b7817f4f6bf422ea532d81217c28f63c259c5 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 25 Jun 2007 18:56:55 +0100 Subject: [PATCH 008/213] rebase -i: several cleanups Support "--verbose" in addition to "-v", show short names in the list comment, clean up if there is nothing to do, and add several "test_ticks" in the test script. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 19 +++++++++++++++---- t/t3404-rebase-interactive.sh | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index ab3657250e..a81432c0a5 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -60,6 +60,11 @@ die_with_patch () { die "$2" } +die_abort () { + rm -rf "$DOTEST" + die "$1" +} + pick_one () { case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac git rev-parse --verify $sha1 || die "Invalid commit name: $sha1" @@ -212,7 +217,7 @@ do -C*) die "Interactive rebase uses merge, so $1 does not make sense" ;; - -v) + -v|--verbose) VERBOSE=t ;; -i|--interactive) @@ -264,8 +269,11 @@ do echo $ONTO > "$DOTEST"/onto test t = "$VERBOSE" && : > "$DOTEST"/verbose + SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM) + SHORTHEAD=$(git rev-parse --short $HEAD) + SHORTONTO=$(git rev-parse --short $ONTO) cat > "$TODO" << EOF -# Rebasing $UPSTREAM..$HEAD onto $ONTO +# Rebasing $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO # # Commands: # pick = use commit @@ -277,13 +285,16 @@ EOF sed "s/^/pick /" >> "$TODO" test -z "$(grep -ve '^$' -e '^#' < $TODO)" && - die "Nothing to do" + die_abort "Nothing to do" cp "$TODO" "$TODO".backup ${VISUAL:-${EDITOR:-vi}} "$TODO" || die "Could not execute editor" - git reset --hard $ONTO && do_rest + test -z "$(grep -ve '^$' -e '^#' < $TODO)" && + die_abort "Nothing to do" + + git checkout $ONTO && do_rest esac shift done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 48aa8ea814..19a3a8e813 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -140,6 +140,7 @@ test_expect_success 'abort' ' test_expect_success 'retain authorship' ' echo A > file7 && git add file7 && + test_tick && GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" && git tag twerp && git rebase -i --onto master HEAD^ && @@ -149,6 +150,7 @@ test_expect_success 'retain authorship' ' test_expect_success 'squash' ' git reset --hard twerp && echo B > file7 && + test_tick && GIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 && echo "******************************" && FAKE_LINES="1 squash 2" git rebase -i --onto master HEAD~2 && From 68a163c9b483ae352fcfee8c4505d113213daa73 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 25 Jun 2007 18:58:28 +0100 Subject: [PATCH 009/213] rebase -i: provide reasonable reflog for the rebased branch If your rebase succeeded, the HEAD's reflog will still show the whole mess, but "@{1}" now shows the state _before_ the rebase, so that you can reset (or compare) the original and the rebased revisions more easily. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 10 ++++++++-- t/t3404-rebase-interactive.sh | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index a81432c0a5..f0f2457975 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -151,8 +151,14 @@ do_next () { esac test -s "$TODO" && return - HEAD=$(git rev-parse HEAD) - HEADNAME=$(cat "$DOTEST"/head-name) + comment_for_reflog finish && + HEADNAME=$(cat "$DOTEST"/head-name) && + OLDHEAD=$(cat "$DOTEST"/head) && + SHORTONTO=$(git rev-parse --short $(cat "$DOTEST"/onto)) && + NEWHEAD=$(git rev-parse HEAD) && + message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" && + git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD && + git symbolic-ref HEAD $HEADNAME && rm -rf "$DOTEST" && warn "Successfully rebased and updated $HEADNAME." diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 19a3a8e813..9f12bb9321 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -99,6 +99,10 @@ test_expect_success 'rebase on top of a non-conflicting commit' ' test $(git rev-parse I) = $(git rev-parse HEAD~2) ' +test_expect_success 'reflog for the branch shows state before rebase' ' + test $(git rev-parse branch1@{1}) = $(git rev-parse original-branch1) +' + test_expect_success 'exchange two commits' ' FAKE_LINES="2 1" git rebase -i HEAD~2 && test H = $(git cat-file commit HEAD^ | tail -n 1) && From f09c9b8c5ff9d8a15499b09ccd6c3e7b3c76af77 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 25 Jun 2007 18:59:43 +0100 Subject: [PATCH 010/213] Teach rebase -i about --preserve-merges The option "-p" (or long "--preserve-merges") makes it possible to rebase side branches including merges, without straightening the history. Example: X \ A---M---B / ---o---O---P---Q When the current HEAD is "B", "git rebase -i -p --onto Q O" will yield X \ ---o---O---P---Q---A'---M'---B' Note that this will - _not_ touch X [*1*], it does - _not_ work without the --interactive flag [*2*], it does - _not_ guess the type of the merge, but blindly uses recursive or whatever strategy you provided with "-s " for all merges it has to redo, and it does - _not_ make use of the original merge commit via git-rerere. *1*: only commits which reach a merge base between and HEAD are reapplied. The others are kept as-are. *2*: git-rebase without --interactive is inherently patch based (at least at the moment), and therefore merges cannot be preserved. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-rebase.txt | 23 ++++++- git-rebase--interactive.sh | 110 +++++++++++++++++++++++++++++++++- t/t3404-rebase-interactive.sh | 22 +++++++ 3 files changed, 151 insertions(+), 4 deletions(-) diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 2e3363a617..96907d4863 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git-rebase' [-i | --interactive] [-v | --verbose] [--merge] [-C] - [--onto ] [] + [-p | --preserve-merges] [--onto ] [] 'git-rebase' --continue | --skip | --abort DESCRIPTION @@ -213,6 +213,10 @@ OPTIONS Make a list of the commits which are about to be rebased. Let the user edit that list before rebasing. +-p, \--preserve-merges:: + Instead of ignoring merges, try to recreate them. This option + only works in interactive mode. + include::merge-strategies.txt[] NOTES @@ -304,6 +308,23 @@ $ git rebase -i HEAD~5 And move the first patch to the end of the list. +You might want to preserve merges, if you have a history like this: + +------------------ + X + \ + A---M---B + / +---o---O---P---Q +------------------ + +Suppose you want to rebase the side branch starting at "A" to "Q". Make +sure that the current HEAD is "B", and call + +----------------------------- +$ git rebase -i -p --onto Q O +----------------------------- + Authors ------ Written by Junio C Hamano and diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index f0f2457975..0c2a9697c4 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -10,7 +10,8 @@ # The original idea comes from Eric W. Biederman, in # http://article.gmane.org/gmane.comp.version-control.git/22407 -USAGE='(--continue | --abort | --skip | [--onto ] [])' +USAGE='(--continue | --abort | --skip | [--preserve-merges] [--verbose] + [--onto ] [])' . git-sh-setup require_work_tree @@ -18,6 +19,8 @@ require_work_tree DOTEST="$GIT_DIR/.dotest-merge" TODO="$DOTEST"/todo DONE="$DOTEST"/done +REWRITTEN="$DOTEST"/rewritten +PRESERVE_MERGES= STRATEGY= VERBOSE= @@ -68,6 +71,8 @@ die_abort () { pick_one () { case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac git rev-parse --verify $sha1 || die "Invalid commit name: $sha1" + test -d "$REWRITTEN" && + pick_one_preserving_merges "$@" && return parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null) current_sha1=$(git rev-parse --verify HEAD) if [ $current_sha1 = $parent_sha1 ]; then @@ -79,6 +84,75 @@ pick_one () { fi } +pick_one_preserving_merges () { + case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac + sha1=$(git rev-parse $sha1) + + if [ -f "$DOTEST"/current-commit ] + then + current_commit=$(cat "$DOTEST"/current-commit) && + git rev-parse HEAD > "$REWRITTEN"/$current_commit && + rm "$DOTEST"/current-commit || + die "Cannot write current commit's replacement sha1" + fi + + # rewrite parents; if none were rewritten, we can fast-forward. + fast_forward=t + preserve=t + new_parents= + for p in $(git rev-list --parents -1 $sha1 | cut -d\ -f2-) + do + if [ -f "$REWRITTEN"/$p ] + then + preserve=f + new_p=$(cat "$REWRITTEN"/$p) + test $p != $new_p && fast_forward=f + case "$new_parents" in + *$new_p*) + ;; # do nothing; that parent is already there + *) + new_parents="$new_parents $new_p" + esac + fi + done + case $fast_forward in + t) + echo "Fast forward to $sha1" + test $preserve=f && echo $sha1 > "$REWRITTEN"/$sha1 + ;; + f) + test "a$1" = a-n && die "Refusing to squash a merge: $sha1" + + first_parent=$(expr "$new_parents" : " \([^ ]*\)") + # detach HEAD to current parent + git checkout $first_parent 2> /dev/null || + die "Cannot move HEAD to $first_parent" + + echo $sha1 > "$DOTEST"/current-commit + case "$new_parents" in + \ *\ *) + # redo merge + author_script=$(get_author_ident_from_commit $sha1) + eval "$author_script" + msg="$(git cat-file commit $sha1 | \ + sed -e '1,/^$/d' -e "s/[\"\\]/\\\\&/g")" + # NEEDSWORK: give rerere a chance + if ! git merge $STRATEGY -m "$msg" $new_parents + then + echo "$msg" > "$GIT_DIR"/MERGE_MSG + warn Error redoing merge $sha1 + warn + warn After fixup, please use + die "$author_script git commit" + fi + ;; + *) + git cherry-pick $STRATEGY "$@" || + die_with_patch $sha1 "Could not pick $sha1" + esac + esac +} + do_next () { read command sha1 rest < "$TODO" case "$command" in @@ -155,7 +229,15 @@ do_next () { HEADNAME=$(cat "$DOTEST"/head-name) && OLDHEAD=$(cat "$DOTEST"/head) && SHORTONTO=$(git rev-parse --short $(cat "$DOTEST"/onto)) && - NEWHEAD=$(git rev-parse HEAD) && + if [ -d "$REWRITTEN" ] + then + test -f "$DOTEST"/current-commit && + current_commit=$(cat "$DOTEST"/current-commit) && + git rev-parse HEAD > "$REWRITTEN"/$current_commit + NEWHEAD=$(cat "$REWRITTEN"/$OLDHEAD) + else + NEWHEAD=$(git rev-parse HEAD) + fi && message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" && git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD && git symbolic-ref HEAD $HEADNAME && @@ -226,6 +308,9 @@ do -v|--verbose) VERBOSE=t ;; + -p|--preserve-merges) + PRESERVE_MERGES=t + ;; -i|--interactive) # yeah, we know ;; @@ -274,6 +359,25 @@ do echo $UPSTREAM > "$DOTEST"/upstream echo $ONTO > "$DOTEST"/onto test t = "$VERBOSE" && : > "$DOTEST"/verbose + if [ t = "$PRESERVE_MERGES" ] + then + # $REWRITTEN contains files for each commit that is + # reachable by at least one merge base of $HEAD and + # $UPSTREAM. They are not necessarily rewritten, but + # their children might be. + # This ensures that commits on merged, but otherwise + # unrelated side branches are left alone. (Think "X" + # in the man page's example.) + mkdir "$REWRITTEN" && + for c in $(git merge-base --all $HEAD $UPSTREAM) + do + echo $ONTO > "$REWRITTEN"/$c || + die "Could not init rewritten commits" + done + MERGES_OPTION= + else + MERGES_OPTION=--no-merges + fi SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM) SHORTHEAD=$(git rev-parse --short $HEAD) @@ -286,7 +390,7 @@ do # edit = use commit, but stop for amending # squash = use commit, but meld into previous commit EOF - git rev-list --no-merges --pretty=oneline --abbrev-commit \ + git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \ --abbrev=7 --reverse $UPSTREAM..$HEAD | \ sed "s/^/pick /" >> "$TODO" diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 9f12bb9321..883cf29595 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -166,4 +166,26 @@ test_expect_success 'retain authorship when squashing' ' git show HEAD | grep "^Author: Nitfol" ' +test_expect_success 'preserve merges with -p' ' + git checkout -b to-be-preserved master^ && + : > unrelated-file && + git add unrelated-file && + test_tick && + git commit -m "unrelated" && + git checkout -b to-be-rebased master && + echo B > file1 && + test_tick && + git commit -m J file1 && + test_tick && + git merge to-be-preserved && + echo C > file1 && + test_tick && + git commit -m K file1 && + git rebase -i -p --onto branch1 master && + test $(git rev-parse HEAD^^2) = $(git rev-parse to-be-preserved) && + test $(git rev-parse HEAD~3) = $(git rev-parse branch1) && + test $(git show HEAD:file1) = C && + test $(git show HEAD~2:file1) = B +' + test_done From 4576518dd7459f44583f33375dbd8799792fc1f3 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Thu, 7 Jun 2007 07:50:29 -0500 Subject: [PATCH 011/213] Add an option to quiet git-init. git-init lacks an option to suppress non-error and non-warning output - this patch adds one. Signed-off-by: Jeffrey C. Ollie Signed-off-by: Junio C Hamano --- Documentation/git-init-db.txt | 2 +- Documentation/git-init.txt | 6 +++++- builtin-init-db.c | 14 +++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt index ab0201aec2..d4e01cb325 100644 --- a/Documentation/git-init-db.txt +++ b/Documentation/git-init-db.txt @@ -8,7 +8,7 @@ git-init-db - Creates an empty git repository SYNOPSIS -------- -'git-init-db' [--template=] [--shared[=]] +'git-init-db' [-q | --quiet] [--template=] [--shared[=]] DESCRIPTION diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 413ed65143..07484a4fd0 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -8,7 +8,7 @@ git-init - Create an empty git repository or reinitialize an existing one SYNOPSIS -------- -'git-init' [--template=] [--shared[=]] +'git-init' [-q | --quiet] [--template=] [--shared[=]] OPTIONS @@ -16,6 +16,10 @@ OPTIONS -- +-q, \--quiet:: + +Only print error and warning messages, all other output will be suppressed. + --template=:: Provide the directory from which templates will be used. The default template diff --git a/builtin-init-db.c b/builtin-init-db.c index 976f47b323..d429ceda36 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -266,7 +266,7 @@ static int create_default_files(const char *git_dir, const char *template_path) } static const char init_db_usage[] = -"git-init [--template=] [--shared]"; +"git-init [-q | --quiet] [--template=] [--shared]"; /* * If you want to, you can share the DB area with any number of branches. @@ -281,6 +281,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) const char *template_dir = NULL; char *path; int len, i, reinit; + int quiet = 0; for (i = 1; i < argc; i++, argv++) { const char *arg = argv[1]; @@ -290,6 +291,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) shared_repository = PERM_GROUP; else if (!prefixcmp(arg, "--shared=")) shared_repository = git_config_perm("arg", arg+9); + else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet")) + quiet = 1; else usage(init_db_usage); } @@ -336,10 +339,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) git_config_set("receive.denyNonFastforwards", "true"); } - printf("%s%s Git repository in %s/\n", - reinit ? "Reinitialized existing" : "Initialized empty", - shared_repository ? " shared" : "", - git_dir); + if (!quiet) + printf("%s%s Git repository in %s/\n", + reinit ? "Reinitialized existing" : "Initialized empty", + shared_repository ? " shared" : "", + git_dir); return 0; } From 279050d04428e9adaa90aebe54a485a334102ab8 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Thu, 7 Jun 2007 07:50:30 -0500 Subject: [PATCH 012/213] Quiet the output from git-init when cloning, if requested. Now that git-init has an option to quiet itself, use it if the -q option was specified on the clone command line. Signed-off-by: Jeffrey C. Ollie Signed-off-by: Junio C Hamano --- git-clone.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-clone.sh b/git-clone.sh index bd44ce1c84..dacaaa678f 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -184,7 +184,7 @@ yes) GIT_DIR="$D" ;; *) GIT_DIR="$D/.git" ;; -esac && export GIT_DIR && git-init ${template+"$template"} || usage +esac && export GIT_DIR && git-init $quiet ${template+"$template"} || usage if test -n "$reference" then From f2c66ed196d1d1410d014e4ee3e2b585936101f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=97=E3=82=89=E3=81=84=E3=81=97=E3=81=AA=E3=81=AA?= =?UTF-8?q?=E3=81=93?= Date: Sat, 30 Jun 2007 14:37:09 +0900 Subject: [PATCH 013/213] Add git-stash script When my boss has something to show me and I have to update, for some reason I am always in the middle of doing something else, and git pull command refuses to work in such a case. I wrote this little script to save the changes I made, perform the update, and then come back to where I was, but on top of the updated commit. This is how you would use the script: $ git stash $ git pull $ git stash apply [jc: with a few fixlets from the list] Signed-off-by: Nanako Shiraishi Signed-off-by: Junio C Hamano --- .gitignore | 1 + Makefile | 3 +- git-stash.sh | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100755 git-stash.sh diff --git a/.gitignore b/.gitignore index e8b060cbe4..02d9b04da0 100644 --- a/.gitignore +++ b/.gitignore @@ -123,6 +123,7 @@ git-ssh-fetch git-ssh-pull git-ssh-push git-ssh-upload +git-stash git-status git-stripspace git-submodule diff --git a/Makefile b/Makefile index 5d60dc8e12..b3b66b7991 100644 --- a/Makefile +++ b/Makefile @@ -212,7 +212,8 @@ SCRIPT_SH = \ git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \ git-merge-resolve.sh git-merge-ours.sh \ git-lost-found.sh git-quiltimport.sh git-submodule.sh \ - git-filter-branch.sh + git-filter-branch.sh \ + git-stash.sh SCRIPT_PERL = \ git-add--interactive.perl \ diff --git a/git-stash.sh b/git-stash.sh new file mode 100755 index 0000000000..c8c5c5648e --- /dev/null +++ b/git-stash.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# Copyright (c) 2007, Nanako Shiraishi + +USAGE='[ | list | show | apply | clear]' + +. git-sh-setup +require_work_tree + +TMP="$GIT_DIR/.git-stash.$$" +trap 'rm -f "$TMP-*"' 0 + +ref_stash=refs/stash + +no_changes () { + git-diff-index --quiet --cached HEAD && + git-diff-files --quiet +} + +clear_stash () { + logfile="$GIT_DIR/logs/$ref_stash" && + mkdir -p "$(dirname "$logfile")" && + : >"$logfile" +} + +save_stash () { + if no_changes + then + echo >&2 'No local changes to save' + exit 0 + fi + test -f "$GIT_DIR/logs/$ref_stash" || + clear_stash || die "Cannot initialize stash" + + # state of the base commit + if b_commit=$(git-rev-parse --verify HEAD) + then + head=$(git-log --abbrev-commit --pretty=oneline -n 1 HEAD) + else + die "You do not have the initial commit yet" + fi + + if branch=$(git-symbolic-ref -q HEAD) + then + branch=${branch#refs/heads/} + else + branch='(no branch)' + fi + msg=$(printf '%s: %s' "$branch" "$head") + + # state of the index + i_tree=$(git-write-tree) && + i_commit=$(printf 'index on %s' "$msg" | + git-commit-tree $i_tree -p $b_commit) || + die "Cannot save the current index state" + + # state of the working tree + w_tree=$( ( + GIT_INDEX_FILE="$TMP-index" && + export GIT_INDEX_FILE && + + rm -f "$TMP-index" && + git-read-tree $i_tree && + git-add -u && + git-write-tree && + rm -f "$TMP-index" + ) ) || + die "Cannot save the current worktree state" + + # create the stash + w_commit=$(printf 'WIP on %s' "$msg" | + git-commit-tree $w_tree -p $b_commit -p $i_commit) || + die "Cannot record working tree state" + + git-update-ref -m "$msg" $ref_stash $w_commit || + die "Cannot save the current status" + printf >&2 'Saved WIP on %s\n' "$msg" +} + +list_stash () { + git-log --pretty=oneline -g "$@" $ref_stash | + sed -n -e 's/^[.0-9a-f]* refs\///p' +} + +show_stash () { + flags=$(git-rev-parse --no-revs --flags "$@") + if test -z "$flags" + then + flags=--stat + fi + s=$(git-rev-parse --revs-only --no-flags --default $ref_stash "$@") + + w_commit=$(git-rev-parse --verify "$s") && + b_commit=$(git-rev-parse --verify "$s^") && + git-diff $flags $b_commit $w_commit +} + +apply_stash () { + git-diff-files --quiet || + die 'Cannot restore on top of a dirty state' + + # current index state + c_tree=$(git-write-tree) || + die 'Cannot apply a stash in the middle of a merge' + + s=$(git-rev-parse --revs-only --no-flags --default $ref_stash "$@") && + w_tree=$(git-rev-parse --verify "$s:") && + b_tree=$(git-rev-parse --verify "$s^:") || + die "$*: no valid stashed state found" + + eval " + GITHEAD_$w_tree='Stashed changes' && + GITHEAD_$c_tree='Updated upstream' && + GITHEAD_$b_tree='Version stash was based on' && + export GITHEAD_$w_tree GITHEAD_$c_tree GITHEAD_$b_tree + " + + if git-merge-recursive $b_tree -- $c_tree $w_tree + then + # No conflict + a="$TMP-added" && + git-diff --cached --name-only --diff-filter=A $c_tree >"$a" && + git-read-tree --reset $c_tree && + git-update-index --add --stdin <"$a" || + die "Cannot unstage modified files" + git-status + rm -f "$a" + else + # Merge conflict; keep the exit status from merge-recursive + exit + fi +} + +# Main command set +case "$1" in +list) + shift + if test $# = 0 + then + set x -n 10 + shift + fi + list_stash "$@" + ;; +show) + shift + show_stash "$@" + ;; +apply) + shift + apply_stash "$@" + ;; +clear) + clear_stash + ;; +'') + save_stash && git-reset --hard + ;; +*) + usage +esac From d8c3d03a0b7f10977dd508a5a965a417b7f1b065 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 28 Jun 2007 22:54:37 -0700 Subject: [PATCH 014/213] diffcore_count_changes: pass diffcore_filespec We may want to use richer information on the data we are dealing with in this function, so instead of passing a buffer address and length, just pass the diffcore_filespec structure. Existing callers always call this function with parameters taken from a filespec anyway, so there is no functionality changes. Signed-off-by: Junio C Hamano --- diffcore-break.c | 3 +-- diffcore-delta.c | 8 ++++---- diffcore-rename.c | 3 +-- diffcore.h | 4 ++-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/diffcore-break.c b/diffcore-break.c index 9c19b8cab7..ae8a7d03e2 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -66,8 +66,7 @@ static int should_break(struct diff_filespec *src, if (base_size < MINIMUM_BREAK_SIZE) return 0; /* we do not break too small filepair */ - if (diffcore_count_changes(src->data, src->size, - dst->data, dst->size, + if (diffcore_count_changes(src, dst, NULL, NULL, 0, &src_copied, &literal_added)) diff --git a/diffcore-delta.c b/diffcore-delta.c index 7338a40c59..0e1fae79de 100644 --- a/diffcore-delta.c +++ b/diffcore-delta.c @@ -156,8 +156,8 @@ static struct spanhash_top *hash_chars(unsigned char *buf, unsigned int sz) return hash; } -int diffcore_count_changes(void *src, unsigned long src_size, - void *dst, unsigned long dst_size, +int diffcore_count_changes(struct diff_filespec *src, + struct diff_filespec *dst, void **src_count_p, void **dst_count_p, unsigned long delta_limit, @@ -172,14 +172,14 @@ int diffcore_count_changes(void *src, unsigned long src_size, if (src_count_p) src_count = *src_count_p; if (!src_count) { - src_count = hash_chars(src, src_size); + src_count = hash_chars(src->data, src->size); if (src_count_p) *src_count_p = src_count; } if (dst_count_p) dst_count = *dst_count_p; if (!dst_count) { - dst_count = hash_chars(dst, dst_size); + dst_count = hash_chars(dst->data, dst->size); if (dst_count_p) *dst_count_p = dst_count; } diff --git a/diffcore-rename.c b/diffcore-rename.c index 79c984c9cf..cb227366b8 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -189,8 +189,7 @@ static int estimate_similarity(struct diff_filespec *src, delta_limit = (unsigned long) (base_size * (MAX_SCORE-minimum_score) / MAX_SCORE); - if (diffcore_count_changes(src->data, src->size, - dst->data, dst->size, + if (diffcore_count_changes(src, dst, &src->cnt_data, &dst->cnt_data, delta_limit, &src_copied, &literal_added)) diff --git a/diffcore.h b/diffcore.h index 7b9294eab2..990dec50f1 100644 --- a/diffcore.h +++ b/diffcore.h @@ -103,8 +103,8 @@ void diff_debug_queue(const char *, struct diff_queue_struct *); #define diff_debug_queue(a,b) do {} while(0) #endif -extern int diffcore_count_changes(void *src, unsigned long src_size, - void *dst, unsigned long dst_size, +extern int diffcore_count_changes(struct diff_filespec *src, + struct diff_filespec *dst, void **src_count_p, void **dst_count_p, unsigned long delta_limit, From 706098af6b53403b5ea3db9216fb99afbe06f52d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 28 Jun 2007 22:56:07 -0700 Subject: [PATCH 015/213] diffcore_filespec: add is_binary diffcore-break and diffcore-rename would want to behave slightly differently depending on the binary-ness of the data, so add one bit to the filespec, as the structure is now passed down to diffcore_count_changes() function. Signed-off-by: Junio C Hamano --- diff.c | 16 ++++++++++++++++ diffcore.h | 1 + 2 files changed, 17 insertions(+) diff --git a/diff.c b/diff.c index 9938969fa5..74c1198e67 100644 --- a/diff.c +++ b/diff.c @@ -3005,6 +3005,22 @@ void diffcore_std(struct diff_options *options) { if (options->quiet) return; + + /* + * break/rename count similarity differently depending on + * the binary-ness. + */ + if ((options->break_opt != -1) || (options->detect_rename)) { + struct diff_queue_struct *q = &diff_queued_diff; + int i; + + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + p->one->is_binary = file_is_binary(p->one); + p->two->is_binary = file_is_binary(p->two); + } + } + if (options->break_opt != -1) diffcore_break(options->break_opt); if (options->detect_rename) diff --git a/diffcore.h b/diffcore.h index 990dec50f1..0c8abb5b94 100644 --- a/diffcore.h +++ b/diffcore.h @@ -37,6 +37,7 @@ struct diff_filespec { #define DIFF_FILE_VALID(spec) (((spec)->mode) != 0) unsigned should_free : 1; /* data should be free()'ed */ unsigned should_munmap : 1; /* data should be munmap()'ed */ + unsigned is_binary : 1; /* data should be considered "binary" */ }; extern struct diff_filespec *alloc_filespec(const char *); From af3abef94af9c821a0c192c693c3e5342ab8729f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 28 Jun 2007 23:11:40 -0700 Subject: [PATCH 016/213] diffcore-delta.c: update the comment on the algorithm. The comment at the top of the file described an old algorithm that was neutral to text/binary differences (it hashed sliding window of N-byte sequences and counted overlaps), but long time ago we switched to a new heuristics that are more suitable for line oriented (read: text) files that are much faster. Signed-off-by: Junio C Hamano --- diffcore-delta.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/diffcore-delta.c b/diffcore-delta.c index 0e1fae79de..7116df0b83 100644 --- a/diffcore-delta.c +++ b/diffcore-delta.c @@ -5,23 +5,20 @@ /* * Idea here is very simple. * - * We have total of (sz-N+1) N-byte overlapping sequences in buf whose - * size is sz. If the same N-byte sequence appears in both source and - * destination, we say the byte that starts that sequence is shared - * between them (i.e. copied from source to destination). + * Almost all data we are interested in are text, but sometimes we have + * to deal with binary data. So we cut them into chunks delimited by + * LF byte, or 64-byte sequence, whichever comes first, and hash them. * - * For each possible N-byte sequence, if the source buffer has more - * instances of it than the destination buffer, that means the - * difference are the number of bytes not copied from source to - * destination. If the counts are the same, everything was copied - * from source to destination. If the destination has more, - * everything was copied, and destination added more. + * For those chunks, if the source buffer has more instances of it + * than the destination buffer, that means the difference are the + * number of bytes not copied from source to destination. If the + * counts are the same, everything was copied from source to + * destination. If the destination has more, everything was copied, + * and destination added more. * * We are doing an approximation so we do not really have to waste * memory by actually storing the sequence. We just hash them into * somewhere around 2^16 hashbuckets and count the occurrences. - * - * The length of the sequence is arbitrarily set to 8 for now. */ /* Wild guess at the initial hash size */ From b9905fed7a028cc9749cf8ad479cbb07940c8638 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 28 Jun 2007 23:14:13 -0700 Subject: [PATCH 017/213] diffcore-delta.c: Ignore CR in CRLF for text files This ignores CR byte in CRLF sequence in text file when computing similarity of two blobs. Usually this should not matter as nobody sane would be checking in a file with CRLF line endings to the repository (they would use autocrlf so that the repository copy would have LF line endings). Signed-off-by: Junio C Hamano --- diffcore-delta.c | 14 +++++++++++--- t/t0022-crlf-rename.sh | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100755 t/t0022-crlf-rename.sh diff --git a/diffcore-delta.c b/diffcore-delta.c index 7116df0b83..a038b166c5 100644 --- a/diffcore-delta.c +++ b/diffcore-delta.c @@ -122,11 +122,14 @@ static struct spanhash_top *add_spanhash(struct spanhash_top *top, } } -static struct spanhash_top *hash_chars(unsigned char *buf, unsigned int sz) +static struct spanhash_top *hash_chars(struct diff_filespec *one) { int i, n; unsigned int accum1, accum2, hashval; struct spanhash_top *hash; + unsigned char *buf = one->data; + unsigned int sz = one->size; + int is_text = !one->is_binary; i = INITIAL_HASH_SIZE; hash = xmalloc(sizeof(*hash) + sizeof(struct spanhash) * (1<> 25); accum2 = (accum2 << 7) ^ (old_1 >> 25); accum1 += c; @@ -169,14 +177,14 @@ int diffcore_count_changes(struct diff_filespec *src, if (src_count_p) src_count = *src_count_p; if (!src_count) { - src_count = hash_chars(src->data, src->size); + src_count = hash_chars(src); if (src_count_p) *src_count_p = src_count; } if (dst_count_p) dst_count = *dst_count_p; if (!dst_count) { - dst_count = hash_chars(dst->data, dst->size); + dst_count = hash_chars(dst); if (dst_count_p) *dst_count_p = dst_count; } diff --git a/t/t0022-crlf-rename.sh b/t/t0022-crlf-rename.sh new file mode 100755 index 0000000000..430a1d1d38 --- /dev/null +++ b/t/t0022-crlf-rename.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +test_description='ignore CR in CRLF sequence while computing similiarity' + +. ./test-lib.sh + +test_expect_success setup ' + + cat ../t0022-crlf-rename.sh >sample && + git add sample && + + test_tick && + git commit -m Initial && + + sed -e "s/\$/ /" ../t0022-crlf-rename.sh >elpmas && + git add elpmas && + rm -f sample && + + test_tick && + git commit -a -m Second + +' + +test_expect_success 'diff -M' ' + + git diff-tree -M -r --name-status HEAD^ HEAD | + sed -e "s/R[0-9]*/RNUM/" >actual && + echo "RNUM sample elpmas" >expect && + diff -u expect actual + +' + +test_done From 09ccdb630517842e6ad3d9354fbd856174c70d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=97=E3=82=89=E3=81=84=E3=81=97=E3=81=AA=E3=81=AA?= =?UTF-8?q?=E3=81=93?= Date: Sun, 1 Jul 2007 14:26:08 +0900 Subject: [PATCH 018/213] Document git-stash This describes the git-stash command. I borrowed a few paragraphs from Johannes's version, and added a few examples. Signed-off-by: Nanako Shiraishi Signed-off-by: Junio C Hamano --- Documentation/cmd-list.perl | 1 + Documentation/git-stash.txt | 162 ++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 Documentation/git-stash.txt diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl index fcea1d74d5..f50f613879 100755 --- a/Documentation/cmd-list.perl +++ b/Documentation/cmd-list.perl @@ -178,6 +178,7 @@ git-show-ref plumbinginterrogators git-sh-setup purehelpers git-ssh-fetch synchingrepositories git-ssh-upload synchingrepositories +git-stash mainporcelain git-status mainporcelain git-stripspace purehelpers git-submodule mainporcelain diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt new file mode 100644 index 0000000000..17ebc83196 --- /dev/null +++ b/Documentation/git-stash.txt @@ -0,0 +1,162 @@ +git-stash(1) +============ + +NAME +---- +git-stash - Stash the changes in a dirty working directory away + +SYNOPSIS +-------- +[verse] +'git-stash' +'git-stash' [list | show [] | apply [] | clear] + +DESCRIPTION +----------- + +Use 'git-stash' when you want to record the current state of the +working directory and the index, but want to go back to a clean +working directory. The command saves your local modifications away +and reverts the working directory to match the `HEAD` commit. + +The modifications stashed away by this command can be listed with +`git-stash list`, inspected with `git-stash show`, and restored +(potentially on top of a different commit) with `git-stash apply` +commands. The default operation when called without options is to +save the changes away. + +The latest stash you created is stored in `$GIT_DIR/refs/stash`; older +stashes are found in the reflog of this refererence and can be named using +the usual reflog syntax (e.g. `stash@{1}` is the stash one previously made, +`stash@{2}` is the one before it, `stash@{2.hours.ago}` is also possible). + +OPTIONS +------- + +(no subcommand):: + + Save your local modifications to a new 'stash', and run `git-reset + --hard` to revert them. + +list:: + + List the stashes that you currently have. Each 'stash' is listed + with its name (e.g. `stash@{0}` is the latest stash, `stash@{1} is + the one before), the name of the branch that was current when the + stash was made, and a short description of the commit the stash was + based on. ++ +---------------------------------------------------------------- +stash@{0}: submit: 6ebd0e2... Add git-stash +stash@{1}: master: 9cc0589... Merge branch 'master' of gfi +---------------------------------------------------------------- + +show []:: + + Show the changes recorded in the stash. When no `` is given, + shows the latest one. By default, the command shows diffstat, but + you can add `-p` option (i.e. `git stash show -p stash@{2}`) to view + it in patch form. + +apply []:: + + Restores the changes recorded in the stash on top of the current + working tree state. When no `` is given, applies the latest + one. The working directory must match the index. When the changes + conflict, you need to resolve them by hand and mark the result with + `git add` as usual. When the changes are cleanly merged, your + earlier local changes stored in the stash becomes the differences + between the index and the working tree (i.e. `git diff`), except + that newly created files are registered in the index (i.e. `git diff + --cached` is necessary to review the newly added files). + +clear:: + Removes all the stashed states. + + +DISCUSSION +---------- + +A stash is represented as a commit whose tree records the state of the +working directory, and its first parent is the commit at `HEAD` when +the stash was created. The tree of the second parent records the +state of the index when the stash is made, and it is made a child of +the `HEAD` commit. The ancestry graph looks like this: + + .----W + / / + ...--H----I + +where `H` is the `HEAD` commit, `I` is a commit that records the state +of the index, and `W` is a commit that records the state of the working +tree. + + +EXAMPLES +-------- + +Pulling into a dirty tree:: + +When you are in the middle of something, you learn that there are +changes that possibly are relevant to what you are doing in the +upstream. When your local changes do not conflict with the changes in +the upstream, a simple `git pull` will let you move forward. ++ +However, there are cases in which your local changes do conflict with +the upstream changes, and `git pull` refuses to overwrite your +changes. In such a case, you can first stash your changes away, +perform a pull, and then unstash, like this: ++ +---------------------------------------------------------------- +$ git pull +... +file foobar not up to date, cannot merge. +$ git stash +$ git pull +$ git stash apply +---------------------------------------------------------------- + +Interrupted workflow:: + +When you are in the middle of something, your boss comes in and +demands you to fix something immediately. Traditionally, you would +make a commit to a temporary branch to store your changes away, and +come back to make the emergency fix, like this: ++ +---------------------------------------------------------------- +... hack hack hack ... +$ git checkout -b my_wip +$ git commit -a -m "WIP" +$ git checkout master +$ edit emergency fix +$ git commit -a -m "Fix in a hurry" +$ git checkout my_wip +$ git reset --soft HEAD^ +... continue hacking ... +---------------------------------------------------------------- ++ +You can use `git-stash` to simplify the above, like this: ++ +---------------------------------------------------------------- +... hack hack hack ... +$ git stash +$ edit emergency fix +$ git commit -a -m "Fix in a hurry" +$ git stash apply +... continue hacking ... +---------------------------------------------------------------- + +SEE ALSO +-------- +gitlink:git-checkout[1], +gitlink:git-commit[1], +gitlink:git-reflog[1], +gitlink:git-reset[1] + +AUTHOR +------ +Written by Nanako Shiraishi + +GIT +--- +Part of the gitlink:git[7] suite From a44c4267090366c81303b964ab64f3d51b78f885 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 30 Jun 2007 20:14:01 -0700 Subject: [PATCH 019/213] t7004: ship trustdb to avoid gpg warnings This avoids warning messages from gpg while verifying the tags; without it, the program complains that the key is not certified with a trusted signature. Signed-off-by: Junio C Hamano --- t/t7004/trustdb.gpg | Bin 0 -> 1280 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 t/t7004/trustdb.gpg diff --git a/t/t7004/trustdb.gpg b/t/t7004/trustdb.gpg new file mode 100644 index 0000000000000000000000000000000000000000..abace962b8bf84be688a6f27e4ebd0ee7052f210 GIT binary patch literal 1280 zcmZQfFGy!*W@Ke#U|?`dKkWykumMIcY@%4iM%7^n6rj+M4;MLzzlOX&pwTnxkD-}P zc^HbXN0fL!SIq1?>env3?W^3`d(OOU5YNaX{KU(k^<0;M@87ONv)_6ZxD={-= Date: Fri, 29 Jun 2007 18:32:46 +0100 Subject: [PATCH 020/213] git add: respect core.filemode with unmerged entries When a merge left unmerged entries, git add failed to pick up the file mode from the index, when core.filemode == 0. If more than one unmerged entry is there, the order of stage preference is 2, 1, 3. Noticed by Johannes Sixt. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- read-cache.c | 30 +++++++++++++++++++++++++++++- t/t3700-add.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/read-cache.c b/read-cache.c index 4362b11f47..a363f312c7 100644 --- a/read-cache.c +++ b/read-cache.c @@ -350,6 +350,34 @@ int remove_file_from_index(struct index_state *istate, const char *path) return 0; } +static int compare_name(struct cache_entry *ce, const char *path, int namelen) +{ + return namelen != ce_namelen(ce) || memcmp(path, ce->name, namelen); +} + +static int index_name_pos_also_unmerged(struct index_state *istate, + const char *path, int namelen) +{ + int pos = index_name_pos(istate, path, namelen); + struct cache_entry *ce; + + if (pos >= 0) + return pos; + + /* maybe unmerged? */ + pos = -1 - pos; + if (pos >= istate->cache_nr || + compare_name((ce = istate->cache[pos]), path, namelen)) + return -1; + + /* order of preference: stage 2, 1, 3 */ + if (ce_stage(ce) == 1 && pos + 1 < istate->cache_nr && + ce_stage((ce = istate->cache[pos + 1])) == 2 && + !compare_name(ce, path, namelen)) + pos++; + return pos; +} + int add_file_to_index(struct index_state *istate, const char *path, int verbose) { int size, namelen; @@ -380,7 +408,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose) * from it, otherwise assume unexecutable regular file. */ struct cache_entry *ent; - int pos = index_name_pos(istate, path, namelen); + int pos = index_name_pos_also_unmerged(istate, path, namelen); ent = (0 <= pos) ? istate->cache[pos] : NULL; ce->ce_mode = ce_mode_from_stat(ent, st.st_mode); diff --git a/t/t3700-add.sh b/t/t3700-add.sh index ad8cc7d4ae..0d80c6aead 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -110,4 +110,30 @@ test_expect_success 'check correct prefix detection' ' git add 1/2/a 1/3/b 1/2/c ' +test_expect_success 'git add and filemode=0 with unmerged entries' ' + echo 1 > stage1 && + echo 2 > stage2 && + echo 3 > stage3 && + for s in 1 2 3 + do + echo "100755 $(git hash-object -w stage$s) $s file" + done | git update-index --index-info && + git config core.filemode 0 && + echo new > file && + git add file && + git ls-files --stage | grep "^100755 .* 0 file$" +' + +test_expect_success 'git add and filemode=0 prefers stage 2 over stage 1' ' + git rm --cached -f file && + ( + echo "100644 $(git hash-object -w stage1) 1 file" + echo "100755 $(git hash-object -w stage2) 2 file" + ) | git update-index --index-info && + git config core.filemode 0 && + echo new > file && + git add file && + git ls-files --stage | grep "^100755 .* 0 file$" +' + test_done From 9a3c6f7ba7c567e277da58a45ac6fa50461297e3 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Sun, 1 Jul 2007 11:48:54 -0400 Subject: [PATCH 021/213] Fix t5516-fetch for systems where `wc -l` outputs whitespace. When wc outputs whitespace, the test "$(command | wc -l)" = 1 is broken because " 1" != "1". Let the shell eat the whitespace by using test 1 = $(command | wc -l) instead. Signed-off-by: Brian Gernhardt Signed-off-by: Junio C Hamano --- t/t5516-fetch-push.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 08d58e1c8c..c0fa2ba404 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -226,7 +226,7 @@ test_expect_success 'push with colon-less refspec (3)' ' git branch -f frotz master && git push testrepo frotz && check_push_result $the_commit heads/frotz && - test "$( cd testrepo && git show-ref | wc -l )" = 1 + test 1 = $( cd testrepo && git show-ref | wc -l ) ' test_expect_success 'push with colon-less refspec (4)' ' @@ -239,7 +239,7 @@ test_expect_success 'push with colon-less refspec (4)' ' git tag -f frotz && git push testrepo frotz && check_push_result $the_commit tags/frotz && - test "$( cd testrepo && git show-ref | wc -l )" = 1 + test 1 = $( cd testrepo && git show-ref | wc -l ) ' From 9488e875862de4e3c9b022ecd9d0845bc28d1996 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 1 Jul 2007 15:29:01 -0700 Subject: [PATCH 022/213] git-stash: require "save" to be explicit and update documentation Signed-off-by: Junio C Hamano --- Documentation/git-stash.txt | 57 ++++++++++++++++++------------------- git-stash.sh | 4 +-- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 17ebc83196..4815965efd 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -8,32 +8,32 @@ git-stash - Stash the changes in a dirty working directory away SYNOPSIS -------- [verse] -'git-stash' -'git-stash' [list | show [] | apply [] | clear] +'git-stash' (save | list | show [] | apply [] | clear) DESCRIPTION ----------- -Use 'git-stash' when you want to record the current state of the +Use 'git-stash save' when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the `HEAD` commit. The modifications stashed away by this command can be listed with `git-stash list`, inspected with `git-stash show`, and restored -(potentially on top of a different commit) with `git-stash apply` -commands. The default operation when called without options is to -save the changes away. +(potentially on top of a different commit) with `git-stash apply`. +The default operation when called without options is to save the +changes away. The latest stash you created is stored in `$GIT_DIR/refs/stash`; older -stashes are found in the reflog of this refererence and can be named using -the usual reflog syntax (e.g. `stash@{1}` is the stash one previously made, -`stash@{2}` is the one before it, `stash@{2.hours.ago}` is also possible). +stashes are found in the reflog of this reference and can be named using +the usual reflog syntax (e.g. `stash@{1}` is the most recently +created stash, `stash@{2}` is the one before it, `stash@{2.hours.ago}` +is also possible). OPTIONS ------- -(no subcommand):: +save:: Save your local modifications to a new 'stash', and run `git-reset --hard` to revert them. @@ -42,7 +42,7 @@ list:: List the stashes that you currently have. Each 'stash' is listed with its name (e.g. `stash@{0}` is the latest stash, `stash@{1} is - the one before), the name of the branch that was current when the + the one before, etc.), the name of the branch that was current when the stash was made, and a short description of the commit the stash was based on. + @@ -53,25 +53,24 @@ stash@{1}: master: 9cc0589... Merge branch 'master' of gfi show []:: - Show the changes recorded in the stash. When no `` is given, - shows the latest one. By default, the command shows diffstat, but - you can add `-p` option (i.e. `git stash show -p stash@{2}`) to view - it in patch form. + Show the changes recorded in the stash as a diff between the the + stashed state and its original parent. When no `` is given, + shows the latest one. By default, the command shows the diffstat, but + it will accept any format known to `git-diff` (e.g., `git-stash show + -p stash@{2}` to view the second most recent stash in patch form). apply []:: - Restores the changes recorded in the stash on top of the current + Restore the changes recorded in the stash on top of the current working tree state. When no `` is given, applies the latest - one. The working directory must match the index. When the changes - conflict, you need to resolve them by hand and mark the result with - `git add` as usual. When the changes are cleanly merged, your - earlier local changes stored in the stash becomes the differences - between the index and the working tree (i.e. `git diff`), except - that newly created files are registered in the index (i.e. `git diff - --cached` is necessary to review the newly added files). + one. The working directory must match the index. ++ +This operation can fail with conflicts; you need to resolve them +by hand in the working tree. clear:: - Removes all the stashed states. + Remove all the stashed states. Note that those states will then + be subject to pruning, and may be difficult or impossible to recover. DISCUSSION @@ -98,13 +97,13 @@ EXAMPLES Pulling into a dirty tree:: When you are in the middle of something, you learn that there are -changes that possibly are relevant to what you are doing in the -upstream. When your local changes do not conflict with the changes in +upstream changes that are possibly relevant to what you are +doing. When your local changes do not conflict with the changes in the upstream, a simple `git pull` will let you move forward. + However, there are cases in which your local changes do conflict with the upstream changes, and `git pull` refuses to overwrite your -changes. In such a case, you can first stash your changes away, +changes. In such a case, you can stash your changes away, perform a pull, and then unstash, like this: + ---------------------------------------------------------------- @@ -119,9 +118,9 @@ $ git stash apply Interrupted workflow:: When you are in the middle of something, your boss comes in and -demands you to fix something immediately. Traditionally, you would +demands that you fix something immediately. Traditionally, you would make a commit to a temporary branch to store your changes away, and -come back to make the emergency fix, like this: +return to your original branch to make the emergency fix, like this: + ---------------------------------------------------------------- ... hack hack hack ... diff --git a/git-stash.sh b/git-stash.sh index c8c5c5648e..ec18ef6d46 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -132,7 +132,7 @@ apply_stash () { # Main command set case "$1" in -list) +list | '') shift if test $# = 0 then @@ -152,7 +152,7 @@ apply) clear) clear_stash ;; -'') +save) save_stash && git-reset --hard ;; *) From aaca4914e9074f5f5b51c8966688a75e7fe132d7 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 2 Jul 2007 00:20:06 -0400 Subject: [PATCH 023/213] git-stash: fix "no arguments" case in documentation Commit 9488e875 changed this from 'save' to 'list', but missed this spot in the documentation. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-stash.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 4815965efd..4dc344dfe7 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -21,8 +21,8 @@ and reverts the working directory to match the `HEAD` commit. The modifications stashed away by this command can be listed with `git-stash list`, inspected with `git-stash show`, and restored (potentially on top of a different commit) with `git-stash apply`. -The default operation when called without options is to save the -changes away. +Calling git-stash without any arguments is equivalent to `git-stash +list`. The latest stash you created is stored in `$GIT_DIR/refs/stash`; older stashes are found in the reflog of this reference and can be named using From 006a86646434e5212defdea59092059fe41387b0 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 2 Jul 2007 00:20:34 -0400 Subject: [PATCH 024/213] git-stash: fix "can't shift that many" with no arguments Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-stash.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-stash.sh b/git-stash.sh index ec18ef6d46..7644bd5a23 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -133,7 +133,7 @@ apply_stash () { # Main command set case "$1" in list | '') - shift + test $# -gt 0 && shift if test $# = 0 then set x -n 10 From 401de4057ac83d473f8bead9b11d00b6371bd6a0 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 2 Jul 2007 00:21:24 -0400 Subject: [PATCH 025/213] git-stash: don't complain when listing in a repo with no stash Previously, the git-log invocation would complain if a repo had not had any stashes created in it yet: $ git-init $ git-stash fatal: ambiguous argument 'refs/stash': unknown revision or path not in the working tree. Use '--' to separate paths from revisions Instead, we only call git-log if we actually have a refs/stash. We could alternatively create the ref when any stash command is called, but it's better for the 'list' command to not require write access to the repo. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-stash.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/git-stash.sh b/git-stash.sh index 7644bd5a23..18d3322ab5 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -76,7 +76,12 @@ save_stash () { printf >&2 'Saved WIP on %s\n' "$msg" } +have_stash () { + git-rev-parse --verify $ref_stash >/dev/null 2>&1 +} + list_stash () { + have_stash || return 0 git-log --pretty=oneline -g "$@" $ref_stash | sed -n -e 's/^[.0-9a-f]* refs\///p' } From 9a5391cf1836fa1b66f3c89ce9b38f8249bb0521 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 2 Jul 2007 01:24:59 -0400 Subject: [PATCH 026/213] Documentation: quote {non-attributes} for asciidoc Asciidoc treats {foo} as an attribute to be substituted; if 'foo' doesn't exist as an attribute, then the entire line gets dropped. When the literal {foo} is desired, \{foo} is required. The exceptions to this rule are: - inside literal blocks - if the 'foo' contains non-alphanumeric characters (e.g., {foo|bar} is assumed not to be an attribute) Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-stash.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 4dc344dfe7..b7d263d650 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -26,8 +26,8 @@ list`. The latest stash you created is stored in `$GIT_DIR/refs/stash`; older stashes are found in the reflog of this reference and can be named using -the usual reflog syntax (e.g. `stash@{1}` is the most recently -created stash, `stash@{2}` is the one before it, `stash@{2.hours.ago}` +the usual reflog syntax (e.g. `stash@\{1}` is the most recently +created stash, `stash@\{2}` is the one before it, `stash@\{2.hours.ago}` is also possible). OPTIONS @@ -41,7 +41,7 @@ save:: list:: List the stashes that you currently have. Each 'stash' is listed - with its name (e.g. `stash@{0}` is the latest stash, `stash@{1} is + with its name (e.g. `stash@\{0}` is the latest stash, `stash@\{1} is the one before, etc.), the name of the branch that was current when the stash was made, and a short description of the commit the stash was based on. @@ -57,7 +57,7 @@ show []:: stashed state and its original parent. When no `` is given, shows the latest one. By default, the command shows the diffstat, but it will accept any format known to `git-diff` (e.g., `git-stash show - -p stash@{2}` to view the second most recent stash in patch form). + -p stash@\{2}` to view the second most recent stash in patch form). apply []:: From 444649e5a833c6ed24e0e92364923324d9ffb386 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 2 Jul 2007 01:14:00 -0700 Subject: [PATCH 027/213] Update public documentation links for 1.5.2.3 Signed-off-by: Junio C Hamano --- Documentation/git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/git.txt b/Documentation/git.txt index 2cc0b214d2..10c7bb3f45 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -42,9 +42,10 @@ unreleased) version of git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.5.2.2/git.html[documentation for release 1.5.2.2] +* link:v1.5.2.3/git.html[documentation for release 1.5.2.3] * release notes for + link:RelNotes-1.5.2.3.txt[1.5.2.3], link:RelNotes-1.5.2.2.txt[1.5.2.2], link:RelNotes-1.5.2.1.txt[1.5.2.1], link:RelNotes-1.5.2.txt[1.5.2]. From ecda072380e54084d5160d7b6a9cdb23369da804 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sun, 24 Jun 2007 23:06:07 +0200 Subject: [PATCH 028/213] git-submodule: provide easy way of adding new submodules To make a submodule effectively usable, the path and a URL where the submodule can be cloned need to be stored in .gitmodules. This subcommand takes care of setting this information after cloning the new submodule. Only the index is updated, so, if needed, the user may still change the URL or switch to a different branch of the submodule before committing. Signed-off-by: Sven Verdoolaege Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 11 ++++ git-submodule.sh | 102 ++++++++++++++++++++++++++++++-- 2 files changed, 107 insertions(+), 6 deletions(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index f8fb80f18b..7f0904e293 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -8,11 +8,19 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- +'git-submodule' [--quiet] [-b branch] add [] 'git-submodule' [--quiet] [--cached] [status|init|update] [--] [...] COMMANDS -------- +add:: + Add the given repository as a submodule at the given path + to the changeset to be committed next. In particular, the + repository is cloned at the specified path, added to the + changeset and registered in .gitmodules. If no path is + specified, the path is deduced from the repository specification. + status:: Show the status of the submodules. This will print the SHA-1 of the currently checked out commit for each submodule, along with the @@ -39,6 +47,9 @@ OPTIONS -q, --quiet:: Only print error messages. +-b, --branch:: + Branch of repository to add as submodule. + --cached:: Display the SHA-1 stored in the index, not the SHA-1 of the currently checked out submodule commit. This option is only valid for the diff --git a/git-submodule.sh b/git-submodule.sh index 89a3885350..67c78f2d3d 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -1,13 +1,15 @@ #!/bin/sh # -# git-submodules.sh: init, update or list git submodules +# git-submodules.sh: add, init, update or list git submodules # # Copyright (c) 2007 Lars Hjemli -USAGE='[--quiet] [--cached] [status|init|update] [--] [...]' +USAGE='[--quiet] [--cached] [add [-b branch]|status|init|update] [--] [...]' . git-sh-setup require_work_tree +add= +branch= init= update= status= @@ -25,6 +27,18 @@ say() fi } +# NEEDSWORK: identical function exists in get_repo_base in clone.sh +get_repo_base() { + ( + cd "`/bin/pwd`" && + cd "$1" || cd "$1.git" && + { + cd .git + pwd + } + ) 2>/dev/null +} + # # Map submodule path to submodule name # @@ -42,6 +56,11 @@ module_name() # # Clone a submodule # +# Prior to calling, modules_update checks that a possibly existing +# path is not a git repository. +# Likewise, module_add checks that path does not exist at all, +# since it is the location of a new submodule. +# module_clone() { path=$1 @@ -65,6 +84,53 @@ module_clone() die "Clone of '$url' into submodule path '$path' failed" } +# +# Add a new submodule to the working tree, .gitmodules and the index +# +# $@ = repo [path] +# +# optional branch is stored in global branch variable +# +module_add() +{ + repo=$1 + path=$2 + + if test -z "$repo"; then + usage + fi + + # Turn the source into an absolute path if + # it is local + if base=$(get_repo_base "$repo"); then + repo="$base" + fi + + # Guess path from repo if not specified or strip trailing slashes + if test -z "$path"; then + path=$(echo "$repo" | sed -e 's|/*$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g') + else + path=$(echo "$path" | sed -e 's|/*$||') + fi + + test -e "$path" && + die "'$path' already exists" + + git-ls-files --error-unmatch "$path" > /dev/null 2>&1 && + die "'$path' already exists in the index" + + module_clone "$path" "$repo" || exit + (unset GIT_DIR && cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) || + die "Unable to checkout submodule '$path'" + git add "$path" || + die "Failed to add submodule '$path'" + + GIT_CONFIG=.gitmodules git config submodule."$path".path "$path" && + GIT_CONFIG=.gitmodules git config submodule."$path".url "$repo" && + git add .gitmodules || + die "Failed to register submodule '$path'" +} + # # Register submodules in .git/config # @@ -173,6 +239,9 @@ modules_list() while case "$#" in 0) break ;; esac do case "$1" in + add) + add=1 + ;; init) init=1 ;; @@ -185,6 +254,14 @@ do -q|--quiet) quiet=1 ;; + -b|--branch) + case "$2" in + '') + usage + ;; + esac + branch="$2"; shift + ;; --cached) cached=1 ;; @@ -201,14 +278,27 @@ do shift done -case "$init,$update,$status,$cached" in -1,,,) +case "$add,$branch" in +1,*) + ;; +,) + ;; +,*) + usage + ;; +esac + +case "$add,$init,$update,$status,$cached" in +1,,,,) + module_add "$@" + ;; +,1,,,) modules_init "$@" ;; -,1,,) +,,1,,) modules_update "$@" ;; -,,*,*) +,,,1,*) modules_list "$@" ;; *) From bffe71f4cd44b8050e7561b9f9245febb8b21f0a Mon Sep 17 00:00:00 2001 From: Emil Medve Date: Tue, 26 Jun 2007 18:40:58 -0500 Subject: [PATCH 029/213] git-submodule: Instead of using only annotated tags, use any tags. Some repositories might not use/have annotated tags (for example the ones created with git-cvsimport) and git-submodule status might fail because git-describe might fail to find a tag. This change allows the status of a submodule to be described/displayed relative to lightweight tags as well. Signed-off-by: Emil Medve Signed-off-by: Junio C Hamano --- git-submodule.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index 67c78f2d3d..c29e2c3c9d 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -199,6 +199,18 @@ modules_update() done } +set_name_rev () { + revname=$( ( + unset GIT_DIR && + cd "$1" && { + git-describe "$2" 2>/dev/null || + git-describe --tags "$2" 2>/dev/null || + git-describe --contains --tags "$2" + } + ) ) + test -z "$revname" || revname=" ($revname)" +} + # # List all submodules, prefixed with: # - submodule not initialized @@ -221,17 +233,18 @@ modules_list() say "-$sha1 $path" continue; fi - revname=$(unset GIT_DIR && cd "$path" && git-describe $sha1) + revname=$(unset GIT_DIR && cd "$path" && git-describe --tags $sha1) + set_name_rev "$path" $"sha1" if git diff-files --quiet -- "$path" then - say " $sha1 $path ($revname)" + say " $sha1 $path$revname" else if test -z "$cached" then sha1=$(unset GIT_DIR && cd "$path" && git-rev-parse --verify HEAD) - revname=$(unset GIT_DIR && cd "$path" && git-describe $sha1) + set_name_rev "$path" $"sha1" fi - say "+$sha1 $path ($revname)" + say "+$sha1 $path$revname" fi done } From 59c93929c8b98b7be00496d61fae8979bab1841d Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 29 Jun 2007 10:31:08 +0200 Subject: [PATCH 030/213] git-clone: fetch possibly detached HEAD over dumb http git-clone supports cloning from a repo with detached HEAD, but if this HEAD is not behind any branch tip then it would not have been fetched over dumb http, resulting in a fatal: Not a valid object name HEAD Since 928c210a, this would also happen on a http repo with a HEAD that is a symbolic link where someone has forgotton to run update-server-info. Signed-off-by: Sven Verdoolaege Signed-off-by: Junio C Hamano --- git-clone.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/git-clone.sh b/git-clone.sh index bd44ce1c84..4cbf60f554 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -72,6 +72,17 @@ Perhaps git-update-server-info needs to be run there?" rm -fr "$clone_tmp" http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" || rm -f "$GIT_DIR/REMOTE_HEAD" + if test -f "$GIT_DIR/REMOTE_HEAD"; then + head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"` + case "$head_sha1" in + 'ref: refs/'*) + ;; + *) + git-http-fetch $v -a "$head_sha1" "$1" || + rm -f "$GIT_DIR/REMOTE_HEAD" + ;; + esac + fi } quiet= From 7627943a1bb0cda6f37b66381a62facf9e200285 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Thu, 28 Jun 2007 16:15:25 +0200 Subject: [PATCH 031/213] getenv/setenv: use constants if available There were places using "GIT_DIR" instead of GIT_DIR_ENVIRONMENT and "GIT_CONFIG" instead of CONFIG_ENVIRONMENT. This makes it easier to find all places touching an environment variable using git grep or similar tools. Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- builtin-config.c | 4 ++-- path.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builtin-config.c b/builtin-config.c index 3f7cab16d5..7d2063c1d2 100644 --- a/builtin-config.c +++ b/builtin-config.c @@ -178,14 +178,14 @@ int cmd_config(int argc, const char **argv, const char *prefix) char *home = getenv("HOME"); if (home) { char *user_config = xstrdup(mkpath("%s/.gitconfig", home)); - setenv("GIT_CONFIG", user_config, 1); + setenv(CONFIG_ENVIRONMENT, user_config, 1); free(user_config); } else { die("$HOME not set"); } } else if (!strcmp(argv[1], "--system")) - setenv("GIT_CONFIG", ETC_GITCONFIG, 1); + setenv(CONFIG_ENVIRONMENT, ETC_GITCONFIG, 1); else if (!strcmp(argv[1], "--null") || !strcmp(argv[1], "-z")) { term = '\0'; delim = '\n'; diff --git a/path.c b/path.c index 6395cf2309..c4ce96236a 100644 --- a/path.c +++ b/path.c @@ -252,7 +252,7 @@ char *enter_repo(char *path, int strict) if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 && validate_headref("HEAD") == 0) { - setenv("GIT_DIR", ".", 1); + setenv(GIT_DIR_ENVIRONMENT, ".", 1); check_repository_format(); return path; } From a2f8028d3d661b314d5a784764f2f5f9e4c2dde0 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 1 Jul 2007 22:51:58 +0100 Subject: [PATCH 032/213] Make '!' aliases more useful When an alias starts with an exclamation mark, the rest is interpreted as a shell command. However, all arguments passed to git used to be ignored. Now you can have an alias like $ git config alias.e '!echo' and $ git e Hello World does what you expect it to do. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/git.c b/git.c index 696a97edca..727aabcbbe 100644 --- a/git.c +++ b/git.c @@ -181,6 +181,21 @@ static int handle_alias(int *argcp, const char ***argv) git_config(git_alias_config); if (alias_string) { if (alias_string[0] == '!') { + if (*argcp > 1) { + int i, sz = PATH_MAX; + char *s = xmalloc(sz), *new_alias = s; + + add_to_string(&s, &sz, alias_string, 0); + free(alias_string); + alias_string = new_alias; + for (i = 1; i < *argcp && + !add_to_string(&s, &sz, " ", 0) && + !add_to_string(&s, &sz, (*argv)[i], 1) + ; i++) + ; /* do nothing */ + if (!sz) + die("Too many or long arguments"); + } trace_printf("trace: alias to shell cmd: %s => %s\n", alias_command, alias_string + 1); ret = system(alias_string + 1); From 967506bbbdc38e75263d6e6a90e3b8dbba6cec0f Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 2 Jul 2007 01:24:59 -0400 Subject: [PATCH 033/213] Documentation: quote {non-attributes} for asciidoc Asciidoc treats {foo} as an attribute to be substituted; if 'foo' doesn't exist as an attribute, then the entire line gets dropped. When the literal {foo} is desired, \{foo} is required. The exceptions to this rule are: - inside literal blocks - if the 'foo' contains non-alphanumeric characters (e.g., {foo|bar} is assumed not to be an attribute) Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-branch.txt | 2 +- Documentation/git-checkout.txt | 2 +- Documentation/git-receive-pack.txt | 10 +++++----- Documentation/git-rev-list.txt | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index 8d72bb9368..9713f906bf 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -56,7 +56,7 @@ OPTIONS -l:: Create the branch's ref log. This activates recording of all changes to made the branch ref, enabling use of date - based sha1 expressions such as "@{yesterday}". + based sha1 expressions such as "@\{yesterday}". -f:: Force the creation of a new branch even if it means deleting diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index ea26da8e21..a6571d2d8d 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -64,7 +64,7 @@ OPTIONS -l:: Create the new branch's ref log. This activates recording of all changes to made the branch ref, enabling use of date - based sha1 expressions such as "@{yesterday}". + based sha1 expressions such as "@\{yesterday}". -m:: If you have local modifications to one or more files that diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt index 6914aa59c3..4ef1840472 100644 --- a/Documentation/git-receive-pack.txt +++ b/Documentation/git-receive-pack.txt @@ -48,8 +48,8 @@ standard input of the hook will be one line per ref to be updated: The refname value is relative to $GIT_DIR; e.g. for the master head this is "refs/heads/master". The two sha1 values before each refname are the object names for the refname before and after -the update. Refs to be created will have sha1-old equal to 0{40}, -while refs to be deleted will have sha1-new equal to 0{40}, otherwise +the update. Refs to be created will have sha1-old equal to 0\{40}, +while refs to be deleted will have sha1-new equal to 0\{40}, otherwise sha1-old and sha1-new should be valid objects in the repository. This hook is called before any refname is updated and before any @@ -71,7 +71,7 @@ The refname parameter is relative to $GIT_DIR; e.g. for the master head this is "refs/heads/master". The two sha1 arguments are the object names for the refname before and after the update. Note that the hook is called before the refname is updated, -so either sha1-old is 0{40} (meaning there is no such ref yet), +so either sha1-old is 0\{40} (meaning there is no such ref yet), or it should match what is recorded in refname. The hook should exit with non-zero status if it wants to disallow @@ -96,8 +96,8 @@ The refname value is relative to $GIT_DIR; e.g. for the master head this is "refs/heads/master". The two sha1 values before each refname are the object names for the refname before and after the update. Refs that were created will have sha1-old equal to -0{40}, while refs that were deleted will have sha1-new equal to -0{40}, otherwise sha1-old and sha1-new should be valid objects in +0\{40}, while refs that were deleted will have sha1-new equal to +0\{40}, otherwise sha1-old and sha1-new should be valid objects in the repository. Using this hook, it is easy to generate mails describing the updates diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index 32cb13faec..20dcac6252 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -284,9 +284,9 @@ excluded from the output. + With '\--pretty' format other than oneline (for obvious reasons), this causes the output to have two extra lines of information -taken from the reflog. By default, 'commit@{Nth}' notation is +taken from the reflog. By default, 'commit@\{Nth}' notation is used in the output. When the starting commit is specified as -'commit@{now}', output also uses 'commit@{timestamp}' notation +'commit@{now}', output also uses 'commit@\{timestamp}' notation instead. Under '\--pretty=oneline', the commit message is prefixed with this information on the same line. From 792d2370f975f032a708cb35044193b5b5310840 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 2 Jul 2007 01:28:20 -0400 Subject: [PATCH 034/213] Documentation: minor cleanups to branch/checkout wording Change "to made" to "made to", which is a typo. Use "reflog" instead of "ref log", which is used elsewhere throughout the documentation. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-branch.txt | 6 +++--- Documentation/git-checkout.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index 9713f906bf..bb6b57dc2d 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -41,7 +41,7 @@ to happen. With a `-d` or `-D` option, `` will be deleted. You may specify more than one branch for deletion. If the branch currently -has a ref log then the ref log will also be deleted. Use -r together with -d +has a reflog then the reflog will also be deleted. Use -r together with -d to delete remote-tracking branches. @@ -54,8 +54,8 @@ OPTIONS Delete a branch irrespective of its index status. -l:: - Create the branch's ref log. This activates recording of - all changes to made the branch ref, enabling use of date + Create the branch's reflog. This activates recording of + all changes made to the branch ref, enabling use of date based sha1 expressions such as "@\{yesterday}". -f:: diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index a6571d2d8d..818b720b91 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -62,8 +62,8 @@ OPTIONS configuration variable. -l:: - Create the new branch's ref log. This activates recording of - all changes to made the branch ref, enabling use of date + Create the new branch's reflog. This activates recording of + all changes made to the branch ref, enabling use of date based sha1 expressions such as "@\{yesterday}". -m:: From 098e711e6c0d123dff2f38d6b804ec632ad7dd78 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 1 Jul 2007 19:00:08 -0700 Subject: [PATCH 035/213] "git-push $URL" without refspecs pushes only matching branches When "git push" is run without any refspec (neither on the command line nor in the config), we used to push "matching refs" in the sense that anything under refs/ hierarchy that exist on both ends were updated. This used to be a sane default for publishing your repository to another back when we did not have refs/remotes/ hierarchy, but it does not make much sense these days. This changes the semantics to push only "matching branches". Signed-off-by: Junio C Hamano --- remote.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/remote.c b/remote.c index 500ca4d968..cf98a44367 100644 --- a/remote.c +++ b/remote.c @@ -544,6 +544,13 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, if (!pat) continue; } + else if (prefixcmp(src->name, "refs/heads/")) + /* + * "matching refs"; traditionally we pushed everything + * including refs outside refs/heads/ hierarchy, but + * that does not make much sense these days. + */ + continue; if (pat) { const char *dst_side = pat->dst ? pat->dst : pat->src; From 05dcd69891632101d347b2f8a6bc37a08878aa1a Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Mon, 2 Jul 2007 13:28:42 +0200 Subject: [PATCH 036/213] Test 'git add' for unmerged entries when core.symlinks=false. In 20314271679e169f324c118c69c8d9e0399feec9 git add was fixed if unmerged entries are in the index and core.filemode=false. core.symlinks=false is a similar case, which touches the same code path. Here is a test that makes sure that the symlink property in the index is preserved, too. Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- t/t3700-add.sh | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 0d80c6aead..e6466d74a0 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -110,30 +110,37 @@ test_expect_success 'check correct prefix detection' ' git add 1/2/a 1/3/b 1/2/c ' -test_expect_success 'git add and filemode=0 with unmerged entries' ' - echo 1 > stage1 && - echo 2 > stage2 && - echo 3 > stage3 && +test_expect_success 'git add with filemode=0, symlinks=0, and unmerged entries' ' for s in 1 2 3 do + echo $s > stage$s echo "100755 $(git hash-object -w stage$s) $s file" + echo "120000 $(printf $s | git hash-object -w -t blob --stdin) $s symlink" done | git update-index --index-info && git config core.filemode 0 && + git config core.symlinks 0 && echo new > file && - git add file && - git ls-files --stage | grep "^100755 .* 0 file$" + echo new > symlink && + git add file symlink && + git ls-files --stage | grep "^100755 .* 0 file$" && + git ls-files --stage | grep "^120000 .* 0 symlink$" ' -test_expect_success 'git add and filemode=0 prefers stage 2 over stage 1' ' - git rm --cached -f file && +test_expect_success 'git add with filemode=0, symlinks=0 prefers stage 2 over stage 1' ' + git rm --cached -f file symlink && ( echo "100644 $(git hash-object -w stage1) 1 file" echo "100755 $(git hash-object -w stage2) 2 file" + echo "100644 $(printf $s | git hash-object -w -t blob --stdin) 1 symlink" + echo "120000 $(printf $s | git hash-object -w -t blob --stdin) 2 symlink" ) | git update-index --index-info && git config core.filemode 0 && + git config core.symlinks 0 && echo new > file && - git add file && - git ls-files --stage | grep "^100755 .* 0 file$" + echo new > symlink && + git add file symlink && + git ls-files --stage | grep "^100755 .* 0 file$" && + git ls-files --stage | grep "^120000 .* 0 symlink$" ' test_done From dbd21447361364d646f3972738a475a92f711513 Mon Sep 17 00:00:00 2001 From: Adam Roben Date: Sun, 1 Jul 2007 17:48:59 -0700 Subject: [PATCH 037/213] format-patch: Add format.subjectprefix config option This change lets you use the format.subjectprefix config option to override the default subject prefix. Signed-off-by: Adam Roben Signed-off-by: Junio C Hamano --- Documentation/git-format-patch.txt | 5 +- builtin-log.c | 9 +++ revision.c | 1 - t/t4013-diff-various.sh | 2 + ...nfig_format.subjectprefix_DIFFERENT_PREFIX | 2 + ...-patch_--inline_--stdout_initial..master^^ | 60 +++++++++++++++++++ 6 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 t/t4013/diff.config_format.subjectprefix_DIFFERENT_PREFIX create mode 100644 t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 647de90361..e5638102ec 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -126,12 +126,13 @@ not add any suffix. CONFIGURATION ------------- You can specify extra mail header lines to be added to each -message in the repository configuration. Also you can specify -the default suffix different from the built-in one: +message in the repository configuration. You can also specify +new defaults for the subject prefix and file suffix. ------------ [format] headers = "Organization: git-foo\n" + subjectprefix = CHANGE suffix = .txt ------------ diff --git a/builtin-log.c b/builtin-log.c index a4186eac8e..5dc2c1c230 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -265,6 +265,7 @@ static int istitlechar(char c) static char *extra_headers = NULL; static int extra_headers_size = 0; +static const char *fmt_patch_subject_prefix = "PATCH"; static const char *fmt_patch_suffix = ".patch"; static int git_format_config(const char *var, const char *value) @@ -290,6 +291,13 @@ static int git_format_config(const char *var, const char *value) if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) { return 0; } + if (!strcmp(var, "format.subjectprefix")) { + if (!value) + die("format.subjectprefix without value"); + fmt_patch_subject_prefix = xstrdup(value); + return 0; + } + return git_log_config(var, value); } @@ -459,6 +467,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.diffopt.msg_sep = ""; rev.diffopt.recursive = 1; + rev.subject_prefix = fmt_patch_subject_prefix; rev.extra_headers = extra_headers; /* diff --git a/revision.c b/revision.c index 7834bb108e..5184716bf0 100644 --- a/revision.c +++ b/revision.c @@ -667,7 +667,6 @@ void init_revisions(struct rev_info *revs, const char *prefix) revs->min_age = -1; revs->skip_count = -1; revs->max_count = -1; - revs->subject_prefix = "PATCH"; revs->prune_fn = NULL; revs->prune_data = NULL; diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 8f4c29a6b5..b453b42af7 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -242,6 +242,8 @@ format-patch --inline --stdout initial..side format-patch --inline --stdout initial..master^ format-patch --inline --stdout initial..master format-patch --inline --stdout --subject-prefix=TESTCASE initial..master +config format.subjectprefix DIFFERENT_PREFIX +format-patch --inline --stdout initial..master^^ diff --abbrev initial..side diff -r initial..side diff --git a/t/t4013/diff.config_format.subjectprefix_DIFFERENT_PREFIX b/t/t4013/diff.config_format.subjectprefix_DIFFERENT_PREFIX new file mode 100644 index 0000000000..78f8970e2b --- /dev/null +++ b/t/t4013/diff.config_format.subjectprefix_DIFFERENT_PREFIX @@ -0,0 +1,2 @@ +$ git config format.subjectprefix DIFFERENT_PREFIX +$ diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ new file mode 100644 index 0000000000..b8e81e1552 --- /dev/null +++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ @@ -0,0 +1,60 @@ +$ git format-patch --inline --stdout initial..master^^ +From 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 Mon Sep 17 00:00:00 2001 +From: A U Thor +Date: Mon, 26 Jun 2006 00:01:00 +0000 +Subject: [DIFFERENT_PREFIX] Second +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------g-i-t--v-e-r-s-i-o-n" + +This is a multi-part message in MIME format. +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +This is the second commit. +--- + dir/sub | 2 ++ + file0 | 3 +++ + file2 | 3 --- + 3 files changed, 5 insertions(+), 3 deletions(-) + delete mode 100644 file2 +--------------g-i-t--v-e-r-s-i-o-n +Content-Type: text/x-patch; name="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename="1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44.diff" + +diff --git a/dir/sub b/dir/sub +index 35d242b..8422d40 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++C ++D +diff --git a/file0 b/file0 +index 01e79c3..b414108 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++4 ++5 ++6 +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 + +--------------g-i-t--v-e-r-s-i-o-n-- + + +$ From 68f6c019fd8d49fbaa72f1aeeb21eb921b6a16bf Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 3 Jul 2007 01:33:54 +0100 Subject: [PATCH 038/213] git-fsck: add --lost-found option With this option, dangling objects are not only reported, but also written to .git/lost-found/commit/ or .git/lost-found/other/. This option implies '--full' and '--no-reflogs'. 'git fsck --lost-found' is meant as a replacement for git-lost-found. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-fsck.txt | 6 +++++- builtin-fsck.c | 22 ++++++++++++++++++++++ t/t1420-lost-found.sh | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100755 t/t1420-lost-found.sh diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt index 234c22f57f..08512e0b8f 100644 --- a/Documentation/git-fsck.txt +++ b/Documentation/git-fsck.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git-fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs] - [--full] [--strict] [--verbose] [*] + [--full] [--strict] [--verbose] [--lost-found] [*] DESCRIPTION ----------- @@ -64,6 +64,10 @@ index file and all SHA1 references in .git/refs/* as heads. --verbose:: Be chatty. +--lost-found:: + Write dangling refs into .git/commit/ or .git/other/, depending + on type. + It tests SHA1 and general object sanity, and it does full tracking of the resulting reachability and everything else. It prints out any corruption it finds (missing or bad objects), and if you use the diff --git a/builtin-fsck.c b/builtin-fsck.c index 944a496650..a6ef65ea32 100644 --- a/builtin-fsck.c +++ b/builtin-fsck.c @@ -20,6 +20,7 @@ static int check_strict; static int keep_cache_objects; static unsigned char head_sha1[20]; static int errors_found; +static int write_lost_and_found; static int verbose; #define ERROR_OBJECT 01 #define ERROR_REACHABLE 02 @@ -138,6 +139,21 @@ static void check_unreachable_object(struct object *obj) if (!obj->used) { printf("dangling %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1)); + if (write_lost_and_found) { + char *filename = git_path("lost-found/%s/%s", + obj->type == OBJ_COMMIT ? "commit" : "other", + sha1_to_hex(obj->sha1)); + FILE *f; + + if (safe_create_leading_directories(filename)) { + error("Could not create lost-found"); + return; + } + if (!(f = fopen(filename, "w"))) + die("Could not open %s", filename); + fprintf(f, "%s\n", sha1_to_hex(obj->sha1)); + fclose(f); + } return; } @@ -685,6 +701,12 @@ int cmd_fsck(int argc, char **argv, const char *prefix) verbose = 1; continue; } + if (!strcmp(arg, "--lost-found")) { + check_full = 1; + include_reflogs = 0; + write_lost_and_found = 1; + continue; + } if (*arg == '-') usage(fsck_usage); } diff --git a/t/t1420-lost-found.sh b/t/t1420-lost-found.sh new file mode 100755 index 0000000000..dc9e402c55 --- /dev/null +++ b/t/t1420-lost-found.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='Test fsck --lost-found' +. ./test-lib.sh + +test_expect_success setup ' + git config core.logAllRefUpdates 0 && + : > file1 && + git add file1 && + test_tick && + git commit -m initial && + echo 1 > file1 && + echo 2 > file2 && + git add file1 file2 && + test_tick && + git commit -m second && + echo 3 > file3 && + git add file3 +' + +test_expect_success 'lost and found something' ' + git rev-parse HEAD > lost-commit && + git rev-parse :file3 > lost-other && + test_tick && + git reset --hard HEAD^ && + git fsck --lost-found && + test 2 = $(ls .git/lost-found/*/* | wc -l) && + test -f .git/lost-found/commit/$(cat lost-commit) && + test -f .git/lost-found/other/$(cat lost-other) +' + +test_done From 36e5e70e0f40cf7ca4351b8159d68f8560a2805f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 30 Jun 2007 11:49:17 -0700 Subject: [PATCH 039/213] Start deprecating "git-command" in favor of "git command" I realize that a lot of people use the "git-xyzzy" format, and we have various historical reasons for it, but I also think that most people have long since started thinking of the git command as a single command with various subcommands, and we've long had the documentation talk about it that way. Slowly migrating away from the git-xyzzy format would allow us to eventually no longer install hundreds of binaries (even if most of them are symlinks or hardlinks) in users $PATH, and the _original_ reasons for it (implementation issues and bash completion) are really long long gone. Using "git xyzzy" also has some fundamental advantages, like the ability to specify things like paging ("git -p xyzzy") and making the whole notion of aliases act like other git commands (which they already do, but they do *not* have a "git-xyzzy" form!) Anyway, while actually removing the "git-xyzzy" things is not practical right now, we can certainly start slowly to deprecate it internally inside git itself - in the shell scripts we use, and the test vectors. This patch adds a "remove-dashes" makefile target, which does that. It isn't particularly efficient or smart, but it *does* successfully rewrite a lot of our shell scripts to use the "git xyzzy" form for all built-in commands. (For non-builtins, the "git xyzzy" format implies an extra execve(), so this script leaves those alone). So apply this patch, and then run make remove-dashes make test git commit -a to generate a much larger patch that actually starts this transformation. (The only half-way subtle thing about this is that it also fixes up git-filter-branch.sh for the new world order by adding quoting around the use of "git-commit-tree" as an argument. It doesn't need it in that format, but when changed into "git commit-tree" it is no longer a single word, and the quoting maintains the old behaviour). NOTE! This does not yet mean that you can actually stop installing the "git-xyzzy" binaries for the builtins. There are some remaining places that want to use the old form, this just removes the most obvious ones that can easily be done automatically. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- Makefile | 3 ++- fixup-builtins | 16 ++++++++++++++++ git-filter-branch.sh | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100755 fixup-builtins diff --git a/Makefile b/Makefile index 90597edfc7..5b30e5c864 100644 --- a/Makefile +++ b/Makefile @@ -988,7 +988,8 @@ check-sha1:: test-sha1$X check: common-cmds.h for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; done - +remove-dashes: + ./fixup-builtins $(BUILT_INS) ### Installation rules diff --git a/fixup-builtins b/fixup-builtins new file mode 100755 index 0000000000..49e861d2ac --- /dev/null +++ b/fixup-builtins @@ -0,0 +1,16 @@ +#!/bin/sh +while [ "$1" ] +do + old="$1" + new=$(echo "$1" | sed 's/git-/git /') + echo "Converting '$old' to '$new'" + git ls-files '*.sh' | while read file + do + sed "s/\\<$old\\>/$new/g" < $file > $file.new + chmod --reference=$file $file.new + mv $file.new $file + done + shift +done +git update-index --refresh >& /dev/null +exit 0 diff --git a/git-filter-branch.sh b/git-filter-branch.sh index a2fcebc1c6..e9907598e5 100644 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -384,7 +384,7 @@ while read commit parents; do sed -e '1,/^$/d' <../commit | \ eval "$filter_msg" | \ - sh -c "$filter_commit" git-commit-tree $(git-write-tree) $parentstr | \ + sh -c "$filter_commit" "git-commit-tree" $(git-write-tree) $parentstr | \ tee ../map/$commit done <../revs From 5be60078c935ed08ee8eb5a32680bdfb6bb5bdf3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 2 Jul 2007 22:52:14 -0700 Subject: [PATCH 040/213] Rewrite "git-frotz" to "git frotz" This uses the remove-dashes target to replace "git-frotz" to "git frotz". Signed-off-by: Junio C Hamano --- Documentation/install-doc-quick.sh | 8 +- contrib/examples/git-gc.sh | 8 +- contrib/examples/git-resolve.sh | 34 ++--- contrib/remotes2config.sh | 4 +- git-am.sh | 40 +++--- git-bisect.sh | 34 ++--- git-checkout.sh | 40 +++--- git-clean.sh | 4 +- git-clone.sh | 26 ++-- git-commit.sh | 50 +++---- git-fetch.sh | 36 ++--- git-filter-branch.sh | 50 +++---- git-lost-found.sh | 4 +- git-ls-remote.sh | 2 +- git-merge-octopus.sh | 14 +- git-merge-one-file.sh | 22 ++-- git-merge-ours.sh | 2 +- git-merge-resolve.sh | 6 +- git-merge-stupid.sh | 10 +- git-merge.sh | 72 +++++----- git-mergetool.sh | 16 +-- git-parse-remote.sh | 24 ++-- git-pull.sh | 16 +-- git-quiltimport.sh | 12 +- git-rebase.sh | 38 +++--- git-repack.sh | 4 +- git-request-pull.sh | 4 +- git-reset.sh | 16 +-- git-sh-setup.sh | 12 +- git-stash.sh | 54 ++++---- git-submodule.sh | 26 ++-- git-tag.sh | 18 +-- git-verify-tag.sh | 6 +- t/lib-read-tree-m-3way.sh | 58 ++++----- t/t0000-basic.sh | 104 +++++++-------- t/t0030-stripspace.sh | 188 +++++++++++++-------------- t/t1000-read-tree-m-3way.sh | 172 ++++++++++++------------ t/t1001-read-tree-m-2way.sh | 176 ++++++++++++------------- t/t1002-read-tree-m-u-2way.sh | 174 ++++++++++++------------- t/t1003-read-tree-prefix.sh | 10 +- t/t1004-read-tree-m-u-wf.sh | 2 +- t/t1020-subdirectory.sh | 36 ++--- t/t1100-commit-tree-options.sh | 10 +- t/t1200-tutorial.sh | 24 ++-- t/t1300-repo-config.sh | 152 +++++++++++----------- t/t1400-update-ref.sh | 74 +++++------ t/t2000-checkout-cache-clash.sh | 18 +-- t/t2001-checkout-cache-clash.sh | 34 ++--- t/t2002-checkout-cache-u.sh | 26 ++-- t/t2003-checkout-cache-mkdir.sh | 18 +-- t/t2004-checkout-cache-temp.sh | 48 +++---- t/t2005-checkout-index-symlinks.sh | 10 +- t/t2100-update-cache-badpath.sh | 12 +- t/t2101-update-index-reupdate.sh | 28 ++-- t/t2102-update-index-symlinks.sh | 14 +- t/t2200-add-update.sh | 14 +- t/t3000-ls-files-others.sh | 18 +-- t/t3001-ls-files-others-exclude.sh | 16 +-- t/t3002-ls-files-dashpath.sh | 24 ++-- t/t3010-ls-files-killed-modified.sh | 20 +-- t/t3020-ls-files-error-unmatch.sh | 14 +- t/t3100-ls-tree-restrict.sh | 32 ++--- t/t3101-ls-tree-dirname.sh | 24 ++-- t/t3200-branch.sh | 162 +++++++++++------------ t/t3210-pack-refs.sh | 86 ++++++------ t/t3300-funny-names.sh | 76 +++++------ t/t3400-rebase.sh | 6 +- t/t3401-rebase-partial.sh | 18 +-- t/t3403-rebase-skip.sh | 2 +- t/t3500-cherry.sh | 22 ++-- t/t3600-rm.sh | 48 +++---- t/t3700-add.sh | 70 +++++----- t/t3800-mktag.sh | 4 +- t/t3900-i18n-commit.sh | 32 ++--- t/t3901-i18n-patch.sh | 34 ++--- t/t4000-diff-format.sh | 8 +- t/t4001-diff-rename.sh | 10 +- t/t4002-diff-basic.sh | 70 +++++----- t/t4003-diff-rename-1.sh | 18 +-- t/t4004-diff-rename-symlink.sh | 8 +- t/t4005-diff-rename-2.sh | 16 +-- t/t4006-diff-mode.sh | 16 +-- t/t4007-rename-3.sh | 16 +-- t/t4008-diff-break-rewrite.sh | 38 +++--- t/t4009-diff-rename-4.sh | 16 +-- t/t4010-diff-pathspec.sh | 16 +-- t/t4011-diff-symlink.sh | 20 +-- t/t4012-diff-binary.sh | 26 ++-- t/t4015-diff-whitespace.sh | 16 +-- t/t4100-apply-stat.sh | 16 +-- t/t4101-apply-nonl.sh | 4 +- t/t4102-apply-rename.sh | 10 +- t/t4103-apply-binary.sh | 52 ++++---- t/t4104-apply-boundary.sh | 2 +- t/t4109-apply-multifrag.sh | 14 +- t/t4110-apply-scan.sh | 6 +- t/t4112-apply-renames.sh | 8 +- t/t4113-apply-ending.sh | 10 +- t/t4114-apply-typechange.sh | 2 +- t/t4115-apply-symlink.sh | 2 +- t/t4116-apply-reverse.sh | 2 +- t/t4117-apply-reject.sh | 2 +- t/t4118-apply-empty-context.sh | 2 +- t/t4119-apply-config.sh | 2 +- t/t4120-apply-popt.sh | 2 +- t/t4121-apply-diffs.sh | 2 +- t/t4200-rerere.sh | 2 +- t/t4201-shortlog.sh | 2 +- t/t5000-tar-tree.sh | 50 +++---- t/t5100-mailinfo.sh | 6 +- t/t5300-pack-object.sh | 72 +++++----- t/t5301-sliding-window.sh | 40 +++--- t/t5302-pack-index.sh | 56 ++++---- t/t5400-send-pack.sh | 36 ++--- t/t5401-update-hooks.sh | 26 ++-- t/t5500-fetch-pack.sh | 30 ++--- t/t6000lib.sh | 4 +- t/t6002-rev-list-bisect.sh | 38 +++--- t/t6003-rev-list-topo-order.sh | 76 +++++------ t/t6004-rev-list-path-optim.sh | 8 +- t/t6005-rev-list-count.sh | 44 +++---- t/t6006-rev-list-format.sh | 10 +- t/t6010-merge-base.sh | 24 ++-- t/t6023-merge-file.sh | 10 +- t/t6024-recursive-merge.sh | 8 +- t/t6025-merge-symlinks.sh | 14 +- t/t6101-rev-parse-parents.sh | 28 ++-- t/t6120-describe.sh | 22 ++-- t/t7001-mv.sh | 32 ++--- t/t7003-filter-branch.sh | 14 +- t/t7004-tag.sh | 22 ++-- t/t7101-reset.sh | 10 +- t/t7300-clean.sh | 6 +- t/t7400-submodule-basic.sh | 32 ++--- t/t8001-annotate.sh | 2 +- t/t8002-blame.sh | 2 +- t/t9100-git-svn-basic.sh | 12 +- t/t9104-git-svn-follow-parent.sh | 30 ++--- t/t9107-git-svn-migrate.sh | 26 ++-- t/t9110-git-svn-use-svm-props.sh | 20 +-- t/t9111-git-svn-use-svnsync-props.sh | 20 +-- t/t9300-fast-import.sh | 100 +++++++------- 142 files changed, 2094 insertions(+), 2094 deletions(-) diff --git a/Documentation/install-doc-quick.sh b/Documentation/install-doc-quick.sh index a64054948a..e6601bdd82 100755 --- a/Documentation/install-doc-quick.sh +++ b/Documentation/install-doc-quick.sh @@ -10,7 +10,7 @@ USAGE=' ' export GIT_DIR test -z "$mandir" && usage -if ! git-rev-parse --verify "$head^0" >/dev/null; then +if ! git rev-parse --verify "$head^0" >/dev/null; then echo >&2 "head: $head does not exist in the current repository" usage fi @@ -18,12 +18,12 @@ fi GIT_INDEX_FILE=`pwd`/.quick-doc.index export GIT_INDEX_FILE rm -f "$GIT_INDEX_FILE" -git-read-tree $head -git-checkout-index -a -f --prefix="$mandir"/ +git read-tree $head +git checkout-index -a -f --prefix="$mandir"/ if test -n "$GZ"; then cd "$mandir" - for i in `git-ls-tree -r --name-only $head` + for i in `git ls-tree -r --name-only $head` do gzip < $i > $i.gz && rm $i done diff --git a/contrib/examples/git-gc.sh b/contrib/examples/git-gc.sh index 436d7caff5..2ae235b081 100755 --- a/contrib/examples/git-gc.sh +++ b/contrib/examples/git-gc.sh @@ -30,8 +30,8 @@ notbare|"") esac test "true" != "$pack_refs" || -git-pack-refs --prune && -git-reflog expire --all && +git pack-refs --prune && +git reflog expire --all && git-repack -a -d -l && -$no_prune git-prune && -git-rerere gc || exit +$no_prune git prune && +git rerere gc || exit diff --git a/contrib/examples/git-resolve.sh b/contrib/examples/git-resolve.sh index 36b90e3849..0ee1bd898e 100755 --- a/contrib/examples/git-resolve.sh +++ b/contrib/examples/git-resolve.sh @@ -17,8 +17,8 @@ dropheads() { "$GIT_DIR/LAST_MERGE" || exit 1 } -head=$(git-rev-parse --verify "$1"^0) && -merge=$(git-rev-parse --verify "$2"^0) && +head=$(git rev-parse --verify "$1"^0) && +merge=$(git rev-parse --verify "$2"^0) && merge_name="$2" && merge_msg="$3" || usage @@ -34,7 +34,7 @@ dropheads echo $head > "$GIT_DIR"/ORIG_HEAD echo $merge > "$GIT_DIR"/LAST_MERGE -common=$(git-merge-base $head $merge) +common=$(git merge-base $head $merge) if [ -z "$common" ]; then die "Unable to find common commit between" $merge $head fi @@ -46,11 +46,11 @@ case "$common" in exit 0 ;; "$head") - echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $merge)" - git-read-tree -u -m $head $merge || exit 1 - git-update-ref -m "resolve $merge_name: Fast forward" \ + echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $merge)" + git read-tree -u -m $head $merge || exit 1 + git update-ref -m "resolve $merge_name: Fast forward" \ HEAD "$merge" "$head" - git-diff-tree -p $head $merge | git-apply --stat + git diff-tree -p $head $merge | git apply --stat dropheads exit 0 ;; @@ -62,7 +62,7 @@ git var GIT_COMMITTER_IDENT >/dev/null || exit # Find an optimum merge base if there are more than one candidates. LF=' ' -common=$(git-merge-base -a $head $merge) +common=$(git merge-base -a $head $merge) case "$common" in ?*"$LF"?*) echo "Trying to find the optimum merge base." @@ -72,10 +72,10 @@ case "$common" in for c in $common do rm -f $G - GIT_INDEX_FILE=$G git-read-tree -m $c $head $merge \ + GIT_INDEX_FILE=$G git read-tree -m $c $head $merge \ 2>/dev/null || continue # Count the paths that are unmerged. - cnt=`GIT_INDEX_FILE=$G git-ls-files --unmerged | wc -l` + cnt=`GIT_INDEX_FILE=$G git ls-files --unmerged | wc -l` if test $best_cnt -le 0 -o $cnt -le $best_cnt then best=$c @@ -92,9 +92,9 @@ case "$common" in esac echo "Trying to merge $merge into $head using $common." -git-update-index --refresh 2>/dev/null -git-read-tree -u -m $common $head $merge || exit 1 -result_tree=$(git-write-tree 2> /dev/null) +git update-index --refresh 2>/dev/null +git read-tree -u -m $common $head $merge || exit 1 +result_tree=$(git write-tree 2> /dev/null) if [ $? -ne 0 ]; then echo "Simple merge failed, trying Automatic merge" git-merge-index -o git-merge-one-file -a @@ -102,11 +102,11 @@ if [ $? -ne 0 ]; then echo $merge > "$GIT_DIR"/MERGE_HEAD die "Automatic merge failed, fix up by hand" fi - result_tree=$(git-write-tree) || exit 1 + result_tree=$(git write-tree) || exit 1 fi -result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge) +result_commit=$(echo "$merge_msg" | git commit-tree $result_tree -p $head -p $merge) echo "Committed merge $result_commit" -git-update-ref -m "resolve $merge_name: In-index merge" \ +git update-ref -m "resolve $merge_name: In-index merge" \ HEAD "$result_commit" "$head" -git-diff-tree -p $head $result_commit | git-apply --stat +git diff-tree -p $head $result_commit | git apply --stat dropheads diff --git a/contrib/remotes2config.sh b/contrib/remotes2config.sh index 0c8b954490..5838b3ab05 100644 --- a/contrib/remotes2config.sh +++ b/contrib/remotes2config.sh @@ -26,8 +26,8 @@ if [ -d "$GIT_DIR"/remotes ]; then mv "$GIT_DIR"/remotes "$GIT_DIR"/remotes.old fi ;; *) - echo "git-config $key "$value" $regex" - git-config $key "$value" $regex || error=1 ;; + echo "git config $key "$value" $regex" + git config $key "$value" $regex || error=1 ;; esac done fi diff --git a/git-am.sh b/git-am.sh index 8b5712968e..d57a3e2d09 100755 --- a/git-am.sh +++ b/git-am.sh @@ -60,17 +60,17 @@ fall_back_3way () { mkdir "$dotest/patch-merge-tmp-dir" # First see if the patch records the index info that we can use. - git-apply -z --index-info "$dotest/patch" \ + git apply -z --index-info "$dotest/patch" \ >"$dotest/patch-merge-index-info" && GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git-update-index -z --index-info <"$dotest/patch-merge-index-info" && + git update-index -z --index-info <"$dotest/patch-merge-index-info" && GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git-write-tree >"$dotest/patch-merge-base+" || + git write-tree >"$dotest/patch-merge-base+" || cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge." echo Using index info to reconstruct a base tree... if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git-apply $binary --cached <"$dotest/patch" + git apply $binary --cached <"$dotest/patch" then mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base" mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index" @@ -80,7 +80,7 @@ It does not apply to blobs recorded in its index." fi test -f "$dotest/patch-merge-index" && - his_tree=$(GIT_INDEX_FILE="$dotest/patch-merge-index" git-write-tree) && + his_tree=$(GIT_INDEX_FILE="$dotest/patch-merge-index" git write-tree) && orig_tree=$(cat "$dotest/patch-merge-base") && rm -fr "$dotest"/patch-merge-* || exit 1 @@ -97,7 +97,7 @@ It does not apply to blobs recorded in its index." git-merge-recursive $orig_tree -- HEAD $his_tree || { if test -d "$GIT_DIR/rr-cache" then - git-rerere + git rerere fi echo Failed to merge in the changes. exit 1 @@ -198,7 +198,7 @@ else # Start afresh. mkdir -p "$dotest" || exit - git-mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || { + git mailsplit -d"$prec" -o"$dotest" -b -- "$@" > "$dotest/last" || { rm -fr "$dotest" exit 1 } @@ -216,7 +216,7 @@ fi case "$resolved" in '') - files=$(git-diff-index --cached --name-only HEAD) || exit + files=$(git diff-index --cached --name-only HEAD) || exit if [ "$files" ]; then echo "Dirty index: cannot apply patches (dirty: $files)" >&2 exit 1 @@ -254,7 +254,7 @@ if test "$skip" = t then if test -d "$GIT_DIR/rr-cache" then - git-rerere clear + git rerere clear fi this=`expr "$this" + 1` resume= @@ -287,14 +287,14 @@ do # by the user, or the user can tell us to do so by --resolved flag. case "$resume" in '') - git-mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \ + git mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \ <"$dotest/$msgnum" >"$dotest/info" || stop_here $this test -s $dotest/patch || { echo "Patch is empty. Was it split wrong?" stop_here $this } - git-stripspace < "$dotest/msg" > "$dotest/msg-clean" + git stripspace < "$dotest/msg" > "$dotest/msg-clean" ;; esac @@ -347,7 +347,7 @@ do case "$resolved$interactive" in tt) # This is used only for interactive view option. - git-diff-index -p --cached HEAD >"$dotest/patch" + git diff-index -p --cached HEAD >"$dotest/patch" ;; esac esac @@ -399,7 +399,7 @@ do case "$resolved" in '') - git-apply $git_apply_opt $binary --index "$dotest/patch" + git apply $git_apply_opt $binary --index "$dotest/patch" apply_status=$? ;; t) @@ -408,11 +408,11 @@ do # trust what the user has in the index file and the # working tree. resolved= - git-diff-index --quiet --cached HEAD && { + git diff-index --quiet --cached HEAD && { echo "No changes - did you forget to use 'git add'?" stop_here_user_resolve $this } - unmerged=$(git-ls-files -u) + unmerged=$(git ls-files -u) if test -n "$unmerged" then echo "You still have unmerged paths in your index" @@ -433,7 +433,7 @@ do then # Applying the patch to an earlier tree and merging the # result may have produced the same tree as ours. - git-diff-index --quiet --cached HEAD && { + git diff-index --quiet --cached HEAD && { echo No changes -- Patch already applied. go_next continue @@ -453,12 +453,12 @@ do "$GIT_DIR"/hooks/pre-applypatch || stop_here $this fi - tree=$(git-write-tree) && + tree=$(git write-tree) && echo Wrote tree $tree && - parent=$(git-rev-parse --verify HEAD) && - commit=$(git-commit-tree $tree -p $parent <"$dotest/final-commit") && + parent=$(git rev-parse --verify HEAD) && + commit=$(git commit-tree $tree -p $parent <"$dotest/final-commit") && echo Committed: $commit && - git-update-ref -m "$GIT_REFLOG_ACTION: $SUBJECT" HEAD $commit $parent || + git update-ref -m "$GIT_REFLOG_ACTION: $SUBJECT" HEAD $commit $parent || stop_here $this if test -x "$GIT_DIR"/hooks/post-applypatch diff --git a/git-bisect.sh b/git-bisect.sh index 1cd456173d..388887a556 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -56,7 +56,7 @@ bisect_start() { # Verify HEAD. If we were bisecting before this, reset to the # top-of-line master first! # - head=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD) || + head=$(GIT_DIR="$GIT_DIR" git symbolic-ref HEAD) || die "Bad HEAD - I need a symbolic ref" case "$head" in refs/heads/bisect) @@ -99,7 +99,7 @@ bisect_start() { break ;; *) - rev=$(git-rev-parse --verify "$arg^{commit}" 2>/dev/null) || { + rev=$(git rev-parse --verify "$arg^{commit}" 2>/dev/null) || { test $has_double_dash -eq 1 && die "'$arg' does not appear to be a valid revision" break @@ -124,9 +124,9 @@ bisect_bad() { bisect_autostart case "$#" in 0) - rev=$(git-rev-parse --verify HEAD) ;; + rev=$(git rev-parse --verify HEAD) ;; 1) - rev=$(git-rev-parse --verify "$1^{commit}") ;; + rev=$(git rev-parse --verify "$1^{commit}") ;; *) usage ;; esac || exit @@ -138,19 +138,19 @@ bisect_bad() { bisect_write_bad() { rev="$1" echo "$rev" >"$GIT_DIR/refs/bisect/bad" - echo "# bad: "$(git-show-branch $rev) >>"$GIT_DIR/BISECT_LOG" + echo "# bad: "$(git show-branch $rev) >>"$GIT_DIR/BISECT_LOG" } bisect_good() { bisect_autostart case "$#" in - 0) revs=$(git-rev-parse --verify HEAD) || exit ;; - *) revs=$(git-rev-parse --revs-only --no-flags "$@") && + 0) revs=$(git rev-parse --verify HEAD) || exit ;; + *) revs=$(git rev-parse --revs-only --no-flags "$@") && test '' != "$revs" || die "Bad rev input: $@" ;; esac for rev in $revs do - rev=$(git-rev-parse --verify "$rev^{commit}") || exit + rev=$(git rev-parse --verify "$rev^{commit}") || exit bisect_write_good "$rev" echo "git-bisect good $rev" >>"$GIT_DIR/BISECT_LOG" @@ -161,7 +161,7 @@ bisect_good() { bisect_write_good() { rev="$1" echo "$rev" >"$GIT_DIR/refs/bisect/good-$rev" - echo "# good: "$(git-show-branch $rev) >>"$GIT_DIR/BISECT_LOG" + echo "# good: "$(git show-branch $rev) >>"$GIT_DIR/BISECT_LOG" } bisect_next_check() { @@ -211,10 +211,10 @@ bisect_next() { bisect_autostart bisect_next_check good - bad=$(git-rev-parse --verify refs/bisect/bad) && + bad=$(git rev-parse --verify refs/bisect/bad) && good=$(git for-each-ref --format='^%(objectname)' \ "refs/bisect/good-*" | tr '[\012]' ' ') && - eval="git-rev-list --bisect-vars $good $bad --" && + eval="git rev-list --bisect-vars $good $bad --" && eval="$eval $(cat "$GIT_DIR/BISECT_NAMES")" && eval=$(eval "$eval") && eval "$eval" || exit @@ -225,7 +225,7 @@ bisect_next() { fi if [ "$bisect_rev" = "$bad" ]; then echo "$bisect_rev is first bad commit" - git-diff-tree --pretty $bisect_rev + git diff-tree --pretty $bisect_rev exit 0 fi @@ -233,8 +233,8 @@ bisect_next() { echo "$bisect_rev" >"$GIT_DIR/refs/heads/new-bisect" git checkout -q new-bisect || exit mv "$GIT_DIR/refs/heads/new-bisect" "$GIT_DIR/refs/heads/bisect" && - GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD refs/heads/bisect - git-show-branch "$bisect_rev" + GIT_DIR="$GIT_DIR" git symbolic-ref HEAD refs/heads/bisect + git show-branch "$bisect_rev" } bisect_visualize() { @@ -250,7 +250,7 @@ bisect_reset() { else branch=master fi ;; - 1) git-show-ref --verify --quiet -- "refs/heads/$1" || { + 1) git show-ref --verify --quiet -- "refs/heads/$1" || { echo >&2 "$1 does not seem to be a valid branch" exit 1 } @@ -288,12 +288,12 @@ bisect_replay () { ;; good) echo "$rev" >"$GIT_DIR/refs/bisect/good-$rev" - echo "# good: "$(git-show-branch $rev) >>"$GIT_DIR/BISECT_LOG" + echo "# good: "$(git show-branch $rev) >>"$GIT_DIR/BISECT_LOG" echo "git-bisect good $rev" >>"$GIT_DIR/BISECT_LOG" ;; bad) echo "$rev" >"$GIT_DIR/refs/bisect/bad" - echo "# bad: "$(git-show-branch $rev) >>"$GIT_DIR/BISECT_LOG" + echo "# bad: "$(git show-branch $rev) >>"$GIT_DIR/BISECT_LOG" echo "git-bisect bad $rev" >>"$GIT_DIR/BISECT_LOG" ;; *) diff --git a/git-checkout.sh b/git-checkout.sh index 33f1e87c0c..e00b697fef 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -6,8 +6,8 @@ SUBDIRECTORY_OK=Sometimes require_work_tree old_name=HEAD -old=$(git-rev-parse --verify $old_name 2>/dev/null) -oldbranch=$(git-symbolic-ref $old_name 2>/dev/null) +old=$(git rev-parse --verify $old_name 2>/dev/null) +oldbranch=$(git symbolic-ref $old_name 2>/dev/null) new= new_name= force= @@ -29,9 +29,9 @@ while [ "$#" != "0" ]; do shift [ -z "$newbranch" ] && die "git checkout: -b needs a branch name" - git-show-ref --verify --quiet -- "refs/heads/$newbranch" && + git show-ref --verify --quiet -- "refs/heads/$newbranch" && die "git checkout: branch $newbranch already exists" - git-check-ref-format "heads/$newbranch" || + git check-ref-format "heads/$newbranch" || die "git checkout: we do not like '$newbranch' as a branch name." ;; "-l") @@ -57,20 +57,20 @@ while [ "$#" != "0" ]; do usage ;; *) - if rev=$(git-rev-parse --verify "$arg^0" 2>/dev/null) + if rev=$(git rev-parse --verify "$arg^0" 2>/dev/null) then if [ -z "$rev" ]; then echo "unknown flag $arg" exit 1 fi new_name="$arg" - if git-show-ref --verify --quiet -- "refs/heads/$arg" + if git show-ref --verify --quiet -- "refs/heads/$arg" then - rev=$(git-rev-parse --verify "refs/heads/$arg^0") + rev=$(git rev-parse --verify "refs/heads/$arg^0") branch="$arg" fi new="$rev" - elif rev=$(git-rev-parse --verify "$arg^{tree}" 2>/dev/null) + elif rev=$(git rev-parse --verify "$arg^{tree}" 2>/dev/null) then # checking out selected paths from a tree-ish. new="$rev" @@ -129,14 +129,14 @@ Did you intend to checkout '$@' which can not be resolved as commit?" # from a specific tree-ish; note that this is for # rescuing paths and is never meant to remove what # is not in the named tree-ish. - git-ls-tree --full-name -r "$new" "$@" | - git-update-index --index-info || exit $? + git ls-tree --full-name -r "$new" "$@" | + git update-index --index-info || exit $? fi # Make sure the request is about existing paths. - git-ls-files --error-unmatch -- "$@" >/dev/null || exit - git-ls-files -- "$@" | - git-checkout-index -f -u --stdin + git ls-files --error-unmatch -- "$@" >/dev/null || exit + git ls-files -- "$@" | + git checkout-index -f -u --stdin exit $? else # Make sure we did not fall back on $arg^{tree} codepath @@ -144,7 +144,7 @@ else # but switching branches. if test '' != "$new" then - git-rev-parse --verify "$new^{commit}" >/dev/null 2>&1 || + git rev-parse --verify "$new^{commit}" >/dev/null 2>&1 || die "Cannot switch branch to a non-commit." fi fi @@ -200,10 +200,10 @@ fi if [ "$force" ] then - git-read-tree $v --reset -u $new + git read-tree $v --reset -u $new else - git-update-index --refresh >/dev/null - merge_error=$(git-read-tree -m -u --exclude-per-directory=.gitignore $old $new 2>&1) || ( + git update-index --refresh >/dev/null + merge_error=$(git read-tree -m -u --exclude-per-directory=.gitignore $old $new 2>&1) || ( case "$merge" in '') echo >&2 "$merge_error" @@ -254,12 +254,12 @@ fi # if [ "$?" -eq 0 ]; then if [ "$newbranch" ]; then - git-branch $track $newbranch_log "$newbranch" "$new_name" || exit + git branch $track $newbranch_log "$newbranch" "$new_name" || exit branch="$newbranch" fi if test -n "$branch" then - GIT_DIR="$GIT_DIR" git-symbolic-ref -m "checkout: moving to $branch" HEAD "refs/heads/$branch" + GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving to $branch" HEAD "refs/heads/$branch" if test -n "$quiet" then true # nothing @@ -271,7 +271,7 @@ if [ "$?" -eq 0 ]; then fi elif test -n "$detached" then - git-update-ref --no-deref -m "checkout: moving to $arg" HEAD "$detached" || + git update-ref --no-deref -m "checkout: moving to $arg" HEAD "$detached" || die "Cannot detach HEAD" if test -n "$detach_warn" then diff --git a/git-clean.sh b/git-clean.sh index 299309d971..a5cfd9f07a 100755 --- a/git-clean.sh +++ b/git-clean.sh @@ -20,7 +20,7 @@ require_work_tree ignored= ignoredonly= cleandir= -disabled="`git-config --bool clean.requireForce`" +disabled="`git config --bool clean.requireForce`" rmf="rm -f --" rmrf="rm -rf --" rm_refuse="echo Not removing" @@ -83,7 +83,7 @@ if [ -z "$ignored" ]; then fi fi -git-ls-files --others --directory $excl ${excl_info:+"$excl_info"} -- "$@" | +git ls-files --others --directory $excl ${excl_info:+"$excl_info"} -- "$@" | while read -r file; do if [ -d "$file" -a ! -L "$file" ]; then if [ -z "$cleandir" ]; then diff --git a/git-clone.sh b/git-clone.sh index 262508683d..48dafa21cf 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -43,7 +43,7 @@ clone_dumb_http () { clone_tmp="$GIT_DIR/clone-tmp" && mkdir -p "$clone_tmp" || exit 1 if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git-config --bool http.noEPSV`" = true ]; then + "`git config --bool http.noEPSV`" = true ]; then curl_extra_args="${curl_extra_args} --disable-epsv" fi http_fetch "$1/info/refs" "$clone_tmp/refs" || @@ -132,7 +132,7 @@ while */*) die "'$2' is not suitable for an origin name" esac - git-check-ref-format "heads/$2" || + git check-ref-format "heads/$2" || die "'$2' is not suitable for a branch name" test -z "$origin_override" || die "Do not give more than one --origin options." @@ -195,7 +195,7 @@ yes) GIT_DIR="$D" ;; *) GIT_DIR="$D/.git" ;; -esac && export GIT_DIR && git-init $quiet ${template+"$template"} || usage +esac && export GIT_DIR && git init $quiet ${template+"$template"} || usage if test -n "$reference" then @@ -345,7 +345,7 @@ then *) continue ;; esac - git-update-ref -m "clone: from $repo" "$destname" "$sha1" "" + git update-ref -m "clone: from $repo" "$destname" "$sha1" "" done < "$GIT_DIR/CLONE_HEAD" fi @@ -389,31 +389,31 @@ then ) # Upstream URL - git-config remote."$origin".url "$repo" && + git config remote."$origin".url "$repo" && # Set up the mappings to track the remote branches. - git-config remote."$origin".fetch \ + git config remote."$origin".fetch \ "+refs/heads/*:$remote_top/*" '^$' && # Write out remote.$origin config, and update our "$head_points_at". case "$head_points_at" in ?*) # Local default branch - git-symbolic-ref HEAD "refs/heads/$head_points_at" && + git symbolic-ref HEAD "refs/heads/$head_points_at" && # Tracking branch for the primary branch at the remote. - git-update-ref HEAD "$head_sha1" && + git update-ref HEAD "$head_sha1" && rm -f "refs/remotes/$origin/HEAD" - git-symbolic-ref "refs/remotes/$origin/HEAD" \ + git symbolic-ref "refs/remotes/$origin/HEAD" \ "refs/remotes/$origin/$head_points_at" && - git-config branch."$head_points_at".remote "$origin" && - git-config branch."$head_points_at".merge "refs/heads/$head_points_at" + git config branch."$head_points_at".remote "$origin" && + git config branch."$head_points_at".merge "refs/heads/$head_points_at" ;; '') # Source had detached HEAD pointing nowhere - git-update-ref --no-deref HEAD "$head_sha1" && + git update-ref --no-deref HEAD "$head_sha1" && rm -f "refs/remotes/$origin/HEAD" ;; esac @@ -421,7 +421,7 @@ then case "$no_checkout" in '') test "z$quiet" = z -a "z$no_progress" = z && v=-v || v= - git-read-tree -m -u $v HEAD HEAD + git read-tree -m -u $v HEAD HEAD esac fi rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD" diff --git a/git-commit.sh b/git-commit.sh index d43bdd87c0..f866f957c4 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -8,7 +8,7 @@ SUBDIRECTORY_OK=Yes . git-sh-setup require_work_tree -git-rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t +git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t case "$0" in *status) @@ -53,7 +53,7 @@ run_status () { t) color= ;; *) color=--nocolor ;; esac - git-runstatus ${color} \ + git runstatus ${color} \ ${verbose:+--verbose} \ ${amend:+--amend} \ ${untracked_files:+--untracked} @@ -335,20 +335,20 @@ t,) cd_to_toplevel && GIT_INDEX_FILE="$NEXT_INDEX" && export GIT_INDEX_FILE && - git-diff-files --name-only -z | - git-update-index --remove -z --stdin + git diff-files --name-only -z | + git update-index --remove -z --stdin ) || exit ;; ,t) save_index && - git-ls-files --error-unmatch -- "$@" >/dev/null || exit + git ls-files --error-unmatch -- "$@" >/dev/null || exit - git-diff-files --name-only -z -- "$@" | + git diff-files --name-only -z -- "$@" | ( cd_to_toplevel && GIT_INDEX_FILE="$NEXT_INDEX" && export GIT_INDEX_FILE && - git-update-index --remove -z --stdin + git update-index --remove -z --stdin ) || exit ;; ,) @@ -364,28 +364,28 @@ t,) refuse_partial "Cannot do a partial commit during a merge." fi TMP_INDEX="$GIT_DIR/tmp-index$$" - commit_only=`git-ls-files --error-unmatch -- "$@"` || exit + commit_only=`git ls-files --error-unmatch -- "$@"` || exit # Build a temporary index and update the real index # the same way. if test -z "$initial_commit" then GIT_INDEX_FILE="$THIS_INDEX" \ - git-read-tree --index-output="$TMP_INDEX" -i -m HEAD + git read-tree --index-output="$TMP_INDEX" -i -m HEAD else rm -f "$TMP_INDEX" fi || exit printf '%s\n' "$commit_only" | GIT_INDEX_FILE="$TMP_INDEX" \ - git-update-index --add --remove --stdin && + git update-index --add --remove --stdin && save_index && printf '%s\n' "$commit_only" | ( GIT_INDEX_FILE="$NEXT_INDEX" export GIT_INDEX_FILE - git-update-index --remove --stdin + git update-index --remove --stdin ) || exit ;; esac @@ -408,12 +408,12 @@ case "$status_only" in t) # This will silently fail in a read-only repository, which is # what we want. - GIT_INDEX_FILE="$USE_INDEX" git-update-index -q --unmerged --refresh + GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh run_status exit $? ;; '') - GIT_INDEX_FILE="$USE_INDEX" git-update-index -q --refresh || exit + GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit ;; esac @@ -454,7 +454,7 @@ then elif test -f "$GIT_DIR/SQUASH_MSG" then cat "$GIT_DIR/SQUASH_MSG" -fi | git-stripspace >"$GIT_DIR"/COMMIT_EDITMSG +fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG case "$signoff" in t) @@ -505,12 +505,12 @@ then PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"` elif test -n "$amend"; then rloga='commit (amend)' - PARENTS=$(git-cat-file commit HEAD | + PARENTS=$(git cat-file commit HEAD | sed -n -e '/^$/q' -e 's/^parent /-p /p') fi - current="$(git-rev-parse --verify HEAD)" + current="$(git rev-parse --verify HEAD)" else - if [ -z "$(git-ls-files)" ]; then + if [ -z "$(git ls-files)" ]; then echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)' exit 1 fi @@ -577,23 +577,23 @@ then else cat "$GIT_DIR"/COMMIT_EDITMSG fi | -git-stripspace >"$GIT_DIR"/COMMIT_MSG +git stripspace >"$GIT_DIR"/COMMIT_MSG if cnt=`grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG | - git-stripspace | + git stripspace | wc -l` && test 0 -lt $cnt then if test -z "$TMP_INDEX" then - tree=$(GIT_INDEX_FILE="$USE_INDEX" git-write-tree) + tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree) else - tree=$(GIT_INDEX_FILE="$TMP_INDEX" git-write-tree) && + tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) && rm -f "$TMP_INDEX" fi && - commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) && + commit=$(cat "$GIT_DIR"/COMMIT_MSG | git commit-tree $tree $PARENTS) && rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) && - git-update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" && + git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" && rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" && if test -f "$NEXT_INDEX" then @@ -612,7 +612,7 @@ cd_to_toplevel if test -d "$GIT_DIR/rr-cache" then - git-rerere + git rerere fi if test "$ret" = 0 @@ -623,7 +623,7 @@ then fi if test -z "$quiet" then - commit=`git-diff-tree --always --shortstat --pretty="format:%h: %s"\ + commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\ --summary --root HEAD --` echo "Created${initial_commit:+ initial} commit $commit" fi diff --git a/git-fetch.sh b/git-fetch.sh index 6d3a3468b3..c3a200120d 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -117,20 +117,20 @@ append_fetch_head () { test -n "$verbose" && flags="$flags$LF-v" test -n "$force$single_force" && flags="$flags$LF-f" GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \ - git-fetch--tool $flags append-fetch-head "$@" + git fetch--tool $flags append-fetch-head "$@" } # updating the current HEAD with git-fetch in a bare # repository is always fine. if test -z "$update_head_ok" && test $(is_bare_repository) = false then - orig_head=$(git-rev-parse --verify HEAD 2>/dev/null) + orig_head=$(git rev-parse --verify HEAD 2>/dev/null) fi # Allow --notags from remote.$1.tagopt case "$tags$no_tags" in '') - case "$(git-config --get "remote.$1.tagopt")" in + case "$(git config --get "remote.$1.tagopt")" in --no-tags) no_tags=t ;; esac @@ -146,7 +146,7 @@ if test "$tags" then taglist=`IFS=' ' && echo "$ls_remote_result" | - git-show-ref --exclude-existing=refs/tags/ | + git show-ref --exclude-existing=refs/tags/ | while read sha1 name do echo ".${name}:${name}" @@ -163,18 +163,18 @@ fi fetch_all_at_once () { - eval=$(echo "$1" | git-fetch--tool parse-reflist "-") + eval=$(echo "$1" | git fetch--tool parse-reflist "-") eval "$eval" ( : subshell because we muck with IFS IFS=" $LF" ( if test "$remote" = . ; then - git-show-ref $rref || echo failed "$remote" + git show-ref $rref || echo failed "$remote" elif test -f "$remote" ; then test -n "$shallow_depth" && die "shallow clone with bundle is not supported" - git-bundle unbundle "$remote" $rref || + git bundle unbundle "$remote" $rref || echo failed "$remote" else if test -d "$remote" && @@ -190,16 +190,16 @@ fetch_all_at_once () { # connected to our repository's tips, in which # case we do not have to do any fetch. theirs=$(echo "$ls_remote_result" | \ - git-fetch--tool -s pick-rref "$rref" "-") && + git fetch--tool -s pick-rref "$rref" "-") && # This will barf when $theirs reach an object that # we do not have in our repository. Otherwise, # we already have everything the fetch would bring in. - git-rev-list --objects $theirs --not --all \ + git rev-list --objects $theirs --not --all \ >/dev/null 2>/dev/null then echo "$ls_remote_result" | \ - git-fetch--tool pick-rref "$rref" "-" + git fetch--tool pick-rref "$rref" "-" else flags= case $verbose in @@ -218,7 +218,7 @@ fetch_all_at_once () { test -n "$verbose" && flags="$flags -v" test -n "$force" && flags="$flags -f" GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \ - git-fetch--tool $flags native-store \ + git fetch--tool $flags native-store \ "$remote" "$remote_nick" "$refs" ) ) || exit @@ -265,13 +265,13 @@ fetch_per_ref () { curl_extra_args="-k" fi if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git-config --bool http.noEPSV`" = true ]; then + "`git config --bool http.noEPSV`" = true ]; then noepsv_opt="--disable-epsv" fi # Find $remote_name from ls-remote output. head=$(echo "$ls_remote_result" | \ - git-fetch--tool -s pick-rref "$remote_name" "-") + git fetch--tool -s pick-rref "$remote_name" "-") expr "z$head" : "z$_x40\$" >/dev/null || die "No such ref $remote_name at $remote" echo >&2 "Fetching $remote_name from $remote using $proto" @@ -283,7 +283,7 @@ fetch_per_ref () { die "shallow clone with rsync not supported" TMP_HEAD="$GIT_DIR/TMP_HEAD" rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1 - head=$(git-rev-parse --verify TMP_HEAD) + head=$(git rev-parse --verify TMP_HEAD) rm -f "$TMP_HEAD" case "$quiet" in '') v=-v ;; *) v= ;; esac test "$rsync_slurped_objects" || { @@ -342,10 +342,10 @@ case "$no_tags$tags" in # using local tracking branch. taglist=$(IFS=' ' && echo "$ls_remote_result" | - git-show-ref --exclude-existing=refs/tags/ | + git show-ref --exclude-existing=refs/tags/ | while read sha1 name do - git-cat-file -t "$sha1" >/dev/null 2>&1 || continue + git cat-file -t "$sha1" >/dev/null 2>&1 || continue echo >&2 "Auto-following $name" echo ".${name}:${name}" done) @@ -365,10 +365,10 @@ case "$orig_head" in '') ;; ?*) - curr_head=$(git-rev-parse --verify HEAD 2>/dev/null) + curr_head=$(git rev-parse --verify HEAD 2>/dev/null) if test "$curr_head" != "$orig_head" then - git-update-ref \ + git update-ref \ -m "$GIT_REFLOG_ACTION: Undoing incorrectly fetched HEAD." \ HEAD "$orig_head" die "Cannot fetch into the current branch." diff --git a/git-filter-branch.sh b/git-filter-branch.sh index e9907598e5..3772951aa7 100644 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -81,7 +81,7 @@ # This is the filter for rewriting the commit's parent list. # It will receive the parent string on stdin and shall output # the new parent string on stdout. The parent string is in -# format accepted by `git-commit-tree`: empty for initial +# format accepted by `git commit-tree`: empty for initial # commit, "-p parent" for a normal commit and "-p parent1 # -p parent2 -p parent3 ..." for a merge commit. # @@ -93,7 +93,7 @@ # # --commit-filter COMMAND:: The filter for performing the commit # If this filter is passed, it will be called instead of the -# `git-commit-tree` command, with those arguments: +# `git commit-tree` command, with those arguments: # # TREE_ID [-p PARENT_COMMIT_ID]... # @@ -132,7 +132,7 @@ # # A significantly faster version: # -# git-filter-branch --index-filter 'git-update-index --remove filename' newbranch +# git-filter-branch --index-filter 'git update-index --remove filename' newbranch # # Now, you will get the rewritten history saved in the branch 'newbranch' # (your current branch is left untouched). @@ -151,7 +151,7 @@ # # To remove commits authored by "Darl McBribe" from the history: # -# git-filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ]; then shift; while [ -n "$1" ]; do shift; echo "$1"; shift; done; else git-commit-tree "$@"; fi' newbranch +# git-filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ]; then shift; while [ -n "$1" ]; do shift; echo "$1"; shift; done; else git commit-tree "$@"; fi' newbranch # # (the shift magic first throws away the tree id and then the -p # parameters). Note that this handles merges properly! In case Darl @@ -182,9 +182,9 @@ # To move the whole tree into a subdirectory, or remove it from there: # # git-filter-branch --index-filter \ -# 'git-ls-files -s | sed "s-\t-&newsubdir/-" | +# 'git ls-files -s | sed "s-\t-&newsubdir/-" | # GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ -# git-update-index --index-info && +# git update-index --index-info && # mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' directorymoved # Testsuite: TODO @@ -240,7 +240,7 @@ filter_tree= filter_index= filter_parent= filter_msg=cat -filter_commit='git-commit-tree "$@"' +filter_commit='git commit-tree "$@"' filter_tag_name= filter_subdir= while case "$#" in 0) usage;; esac @@ -300,7 +300,7 @@ done dstbranch="$1" shift test -n "$dstbranch" || die "missing branch name" -git-show-ref "refs/heads/$dstbranch" 2> /dev/null && +git show-ref "refs/heads/$dstbranch" 2> /dev/null && die "branch $dstbranch already exists" test ! -e "$tempdir" || die "$tempdir already exists, please remove it" @@ -318,7 +318,7 @@ esac export GIT_DIR GIT_WORK_TREE=. export GIT_INDEX_FILE="$(pwd)/../index" -git-read-tree # seed the index file +git read-tree # seed the index file ret=0 @@ -327,11 +327,11 @@ mkdir ../map # map old->new commit ids for rewriting parents case "$filter_subdir" in "") - git-rev-list --reverse --topo-order --default HEAD \ + git rev-list --reverse --topo-order --default HEAD \ --parents "$@" ;; *) - git-rev-list --reverse --topo-order --default HEAD \ + git rev-list --reverse --topo-order --default HEAD \ --parents --full-history "$@" -- "$filter_subdir" esac > ../revs commits=$(cat ../revs | wc -l | tr -d " ") @@ -345,29 +345,29 @@ while read commit parents; do case "$filter_subdir" in "") - git-read-tree -i -m $commit + git read-tree -i -m $commit ;; *) - git-read-tree -i -m $commit:"$filter_subdir" + git read-tree -i -m $commit:"$filter_subdir" esac export GIT_COMMIT=$commit - git-cat-file commit "$commit" >../commit + git cat-file commit "$commit" >../commit eval "$(set_ident AUTHOR <../commit)" eval "$(set_ident COMMITTER <../commit)" eval "$filter_env" < /dev/null if [ "$filter_tree" ]; then - git-checkout-index -f -u -a + git checkout-index -f -u -a # files that $commit removed are now still in the working tree; # remove them, else they would be added again - git-ls-files -z --others | xargs -0 rm -f + git ls-files -z --others | xargs -0 rm -f eval "$filter_tree" < /dev/null - git-diff-index -r $commit | cut -f 2- | tr '\n' '\0' | \ - xargs -0 git-update-index --add --replace --remove - git-ls-files -z --others | \ - xargs -0 git-update-index --add --replace --remove + git diff-index -r $commit | cut -f 2- | tr '\n' '\0' | \ + xargs -0 git update-index --add --replace --remove + git ls-files -z --others | \ + xargs -0 git update-index --add --replace --remove fi eval "$filter_index" < /dev/null @@ -384,7 +384,7 @@ while read commit parents; do sed -e '1,/^$/d' <../commit | \ eval "$filter_msg" | \ - sh -c "$filter_commit" "git-commit-tree" $(git-write-tree) $parentstr | \ + sh -c "$filter_commit" "git commit-tree" $(git write-tree) $parentstr | \ tee ../map/$commit done <../revs @@ -395,7 +395,7 @@ case "$target_head" in echo Nothing rewritten ;; *) - git-update-ref refs/heads/"$dstbranch" $target_head + git update-ref refs/heads/"$dstbranch" $target_head if [ $(cat ../map/$src_head | wc -l) -gt 1 ]; then echo "WARNING: Your commit filter caused the head commit to expand to several rewritten commits. Only the first such commit was recorded as the current $dstbranch head but you will need to resolve the situation now (probably by manually merging the other commits). These are all the commits:" >&2 sed 's/^/ /' ../map/$src_head >&2 @@ -405,7 +405,7 @@ case "$target_head" in esac if [ "$filter_tag_name" ]; then - git-for-each-ref --format='%(objectname) %(objecttype) %(refname)' refs/tags | + git for-each-ref --format='%(objectname) %(objecttype) %(refname)' refs/tags | while read sha1 type ref; do ref="${ref#refs/tags/}" # XXX: Rewrite tagged trees as well? @@ -416,7 +416,7 @@ if [ "$filter_tag_name" ]; then if [ "$type" = "tag" ]; then # Dereference to a commit sha1t="$sha1" - sha1="$(git-rev-parse "$sha1"^{commit} 2>/dev/null)" || continue + sha1="$(git rev-parse "$sha1"^{commit} 2>/dev/null)" || continue fi [ -f "../map/$sha1" ] || continue @@ -431,7 +431,7 @@ if [ "$filter_tag_name" ]; then warn "unreferencing tag object $sha1t" fi - git-update-ref "refs/tags/$new_ref" "$new_sha1" + git update-ref "refs/tags/$new_ref" "$new_sha1" done fi diff --git a/git-lost-found.sh b/git-lost-found.sh index 58570dff13..c0b00e0fd1 100755 --- a/git-lost-found.sh +++ b/git-lost-found.sh @@ -17,10 +17,10 @@ while read dangling type sha1 do case "$dangling" in dangling) - if git-rev-parse --verify "$sha1^0" >/dev/null 2>/dev/null + if git rev-parse --verify "$sha1^0" >/dev/null 2>/dev/null then dir="$laf/commit" - git-show-branch "$sha1" + git show-branch "$sha1" else dir="$laf/other" fi diff --git a/git-ls-remote.sh b/git-ls-remote.sh index a6ed99a7c5..3671f3433e 100755 --- a/git-ls-remote.sh +++ b/git-ls-remote.sh @@ -58,7 +58,7 @@ http://* | https://* | ftp://* ) curl_extra_args="-k" fi if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git-config --bool http.noEPSV`" = true ]; then + "`git config --bool http.noEPSV`" = true ]; then curl_extra_args="${curl_extra_args} --disable-epsv" fi curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" || diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index eb3f473d5a..645e1147dc 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -45,7 +45,7 @@ esac # MRT is the current "merge result tree" MRC=$head MSG= PARENT="-p $head" -MRT=$(git-write-tree) +MRT=$(git write-tree) CNT=1 ;# counting our head NON_FF_MERGE=0 OCTOPUS_FAILURE=0 @@ -61,7 +61,7 @@ do exit 2 esac - common=$(git-merge-base --all $MRC $SHA1) || + common=$(git merge-base --all $MRC $SHA1) || die "Unable to find common commit with $SHA1" case "$LF$common$LF" in @@ -82,22 +82,22 @@ do # We still need to count this as part of the parent set. echo "Fast forwarding to: $SHA1" - git-read-tree -u -m $head $SHA1 || exit - MRC=$SHA1 MRT=$(git-write-tree) + git read-tree -u -m $head $SHA1 || exit + MRC=$SHA1 MRT=$(git write-tree) continue fi NON_FF_MERGE=1 echo "Trying simple merge with $SHA1" - git-read-tree -u -m --aggressive $common $MRT $SHA1 || exit 2 - next=$(git-write-tree 2>/dev/null) + git read-tree -u -m --aggressive $common $MRT $SHA1 || exit 2 + next=$(git write-tree 2>/dev/null) if test $? -ne 0 then echo "Simple merge did not work, trying automatic merge." git-merge-index -o git-merge-one-file -a || OCTOPUS_FAILURE=1 - next=$(git-write-tree 2>/dev/null) + next=$(git write-tree 2>/dev/null) fi # We have merged the other branch successfully. Ideally diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh index 254d210bdc..ebbb575965 100755 --- a/git-merge-one-file.sh +++ b/git-merge-one-file.sh @@ -13,7 +13,7 @@ # $7 - file in branch2 mode (or empty) # # Handle some trivial cases.. The _really_ trivial cases have -# been handled already by git-read-tree, but that one doesn't +# been handled already by git read-tree, but that one doesn't # do any merges that might change the tree layout. case "${1:-.}${2:-.}${3:-.}" in @@ -34,7 +34,7 @@ case "${1:-.}${2:-.}${3:-.}" in rm -f -- "$4" && rmdir -p "$(expr "z$4" : 'z\(.*\)/')" 2>/dev/null || : fi && - exec git-update-index --remove -- "$4" + exec git update-index --remove -- "$4" ;; # @@ -50,8 +50,8 @@ case "${1:-.}${2:-.}${3:-.}" in echo "ERROR: untracked $4 is overwritten by the merge." exit 1 } - git-update-index --add --cacheinfo "$6$7" "$2$3" "$4" && - exec git-checkout-index -u -f -- "$4" + git update-index --add --cacheinfo "$6$7" "$2$3" "$4" && + exec git checkout-index -u -f -- "$4" ;; # @@ -64,8 +64,8 @@ case "${1:-.}${2:-.}${3:-.}" in exit 1 fi echo "Adding $4" - git-update-index --add --cacheinfo "$6" "$2" "$4" && - exec git-checkout-index -u -f -- "$4" + git update-index --add --cacheinfo "$6" "$2" "$4" && + exec git checkout-index -u -f -- "$4" ;; # @@ -84,11 +84,11 @@ case "${1:-.}${2:-.}${3:-.}" in case "$1" in '') echo "Added $4 in both, but differently." - # This extracts OUR file in $orig, and uses git-apply to + # This extracts OUR file in $orig, and uses git apply to # remove lines that are unique to ours. orig=`git-unpack-file $2` sz0=`wc -c <"$orig"` - diff -u -La/$orig -Lb/$orig $orig $src2 | git-apply --no-add + diff -u -La/$orig -Lb/$orig $orig $src2 | git apply --no-add sz1=`wc -c <"$orig"` # If we do not have enough common material, it is not @@ -104,12 +104,12 @@ case "${1:-.}${2:-.}${3:-.}" in # Be careful for funny filename such as "-L" in "$4", which # would confuse "merge" greatly. src1=`git-unpack-file $2` - git-merge-file "$src1" "$orig" "$src2" + git merge-file "$src1" "$orig" "$src2" ret=$? # Create the working tree file, using "our tree" version from the # index, and then store the result of the merge. - git-checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" + git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" rm -f -- "$orig" "$src1" "$src2" if [ "$6" != "$7" ]; then @@ -124,7 +124,7 @@ case "${1:-.}${2:-.}${3:-.}" in echo "ERROR: Merge conflict in $4" exit 1 fi - exec git-update-index -- "$4" + exec git update-index -- "$4" ;; *) diff --git a/git-merge-ours.sh b/git-merge-ours.sh index 2b6a5c0d10..c81a790aa6 100755 --- a/git-merge-ours.sh +++ b/git-merge-ours.sh @@ -9,6 +9,6 @@ # because the current index is what we will be committing as the # merge result. -git-diff-index --quiet --cached HEAD || exit 2 +git diff-index --quiet --cached HEAD || exit 2 exit 0 diff --git a/git-merge-resolve.sh b/git-merge-resolve.sh index 75e1de49ac..bb19da2cc1 100755 --- a/git-merge-resolve.sh +++ b/git-merge-resolve.sh @@ -37,10 +37,10 @@ then exit 2 fi -git-update-index --refresh 2>/dev/null -git-read-tree -u -m --aggressive $bases $head $remotes || exit 2 +git update-index --refresh 2>/dev/null +git read-tree -u -m --aggressive $bases $head $remotes || exit 2 echo "Trying simple merge." -if result_tree=$(git-write-tree 2>/dev/null) +if result_tree=$(git write-tree 2>/dev/null) then exit 0 else diff --git a/git-merge-stupid.sh b/git-merge-stupid.sh index 4faecb933d..4b1e595363 100755 --- a/git-merge-stupid.sh +++ b/git-merge-stupid.sh @@ -40,10 +40,10 @@ case "$bases" in for c in $bases do rm -f $G - GIT_INDEX_FILE=$G git-read-tree -m $c $head $remotes \ + GIT_INDEX_FILE=$G git read-tree -m $c $head $remotes \ 2>/dev/null || continue # Count the paths that are unmerged. - cnt=`GIT_INDEX_FILE=$G git-ls-files --unmerged | wc -l` + cnt=`GIT_INDEX_FILE=$G git ls-files --unmerged | wc -l` if test $best_cnt -le 0 -o $cnt -le $best_cnt then best=$c @@ -63,10 +63,10 @@ case "$bases" in ;; esac -git-update-index --refresh 2>/dev/null -git-read-tree -u -m $common $head $remotes || exit 2 +git update-index --refresh 2>/dev/null +git read-tree -u -m $common $head $remotes || exit 2 echo "Trying simple merge." -if result_tree=$(git-write-tree 2>/dev/null) +if result_tree=$(git write-tree 2>/dev/null) then exit 0 else diff --git a/git-merge.sh b/git-merge.sh index 981d69d35f..485253032a 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -31,7 +31,7 @@ dropsave() { savestate() { # Stash away any local modifications. - git-diff-index -z --name-only $head | + git diff-index -z --name-only $head | cpio -0 -o >"$GIT_DIR/MERGE_SAVE" } @@ -40,7 +40,7 @@ restorestate() { then git reset --hard $head >/dev/null cpio -iuv <"$GIT_DIR/MERGE_SAVE" - git-update-index --refresh >/dev/null + git update-index --refresh >/dev/null fi } @@ -57,7 +57,7 @@ finish_up_to_date () { squash_message () { echo Squashed commit of the following: echo - git-log --no-merges ^"$head" $remote + git log --no-merges ^"$head" $remote } finish () { @@ -79,7 +79,7 @@ finish () { echo "No merge message -- not updating HEAD" ;; *) - git-update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1 + git update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1 ;; esac ;; @@ -91,7 +91,7 @@ finish () { if test "$show_diffstat" = t then # We want color (if set), but no pager - GIT_PAGER='' git-diff --stat --summary -M "$head" "$1" + GIT_PAGER='' git diff --stat --summary -M "$head" "$1" fi ;; esac @@ -99,13 +99,13 @@ finish () { merge_name () { remote="$1" - rh=$(git-rev-parse --verify "$remote^0" 2>/dev/null) || return - bh=$(git-show-ref -s --verify "refs/heads/$remote" 2>/dev/null) + rh=$(git rev-parse --verify "$remote^0" 2>/dev/null) || return + bh=$(git show-ref -s --verify "refs/heads/$remote" 2>/dev/null) if test "$rh" = "$bh" then echo "$rh branch '$remote' of ." elif truname=$(expr "$remote" : '\(.*\)~[1-9][0-9]*$') && - git-show-ref -q --verify "refs/heads/$truname" 2>/dev/null + git show-ref -q --verify "refs/heads/$truname" 2>/dev/null then echo "$rh branch '$truname' (early part) of ." elif test "$remote" = "FETCH_HEAD" -a -r "$GIT_DIR/FETCH_HEAD" @@ -170,7 +170,7 @@ do done if test -z "$show_diffstat"; then - test "$(git-config --bool merge.diffstat)" = false && show_diffstat=false + test "$(git config --bool merge.diffstat)" = false && show_diffstat=false test -z "$show_diffstat" && show_diffstat=t fi @@ -181,15 +181,15 @@ fi # have "-m" so it is an additional safety measure to check for it. if test -z "$have_message" && - second_token=$(git-rev-parse --verify "$2^0" 2>/dev/null) && - head_commit=$(git-rev-parse --verify "HEAD" 2>/dev/null) && + second_token=$(git rev-parse --verify "$2^0" 2>/dev/null) && + head_commit=$(git rev-parse --verify "HEAD" 2>/dev/null) && test "$second_token" = "$head_commit" then merge_msg="$1" shift head_arg="$1" shift -elif ! git-rev-parse --verify HEAD >/dev/null 2>&1 +elif ! git rev-parse --verify HEAD >/dev/null 2>&1 then # If the merged head is a valid one there is no reason to # forbid "git merge" into a branch yet to be born. We do @@ -203,8 +203,8 @@ then rh=$(git rev-parse --verify "$1^0") || die "$1 - not something we can merge" - git-update-ref -m "initial pull" HEAD "$rh" "" && - git-read-tree --reset -u HEAD + git update-ref -m "initial pull" HEAD "$rh" "" && + git read-tree --reset -u HEAD exit else @@ -219,11 +219,11 @@ else merge_name=$(for remote do merge_name "$remote" - done | git-fmt-merge-msg + done | git fmt-merge-msg ) merge_msg="${merge_msg:+$merge_msg$LF$LF}$merge_name" fi -head=$(git-rev-parse --verify "$head_arg"^0) || usage +head=$(git rev-parse --verify "$head_arg"^0) || usage # All the rest are remote heads test "$#" = 0 && usage ;# we need at least one remote head. @@ -232,7 +232,7 @@ set_reflog_action "merge $*" remoteheads= for remote do - remotehead=$(git-rev-parse --verify "$remote"^0 2>/dev/null) || + remotehead=$(git rev-parse --verify "$remote"^0 2>/dev/null) || die "$remote - not something we can merge" remoteheads="${remoteheads}$remotehead " eval GITHEAD_$remotehead='"$remote"' @@ -244,7 +244,7 @@ case "$use_strategies" in '') case "$#" in 1) - var="`git-config --get pull.twohead`" + var="`git config --get pull.twohead`" if test -n "$var" then use_strategies="$var" @@ -252,7 +252,7 @@ case "$use_strategies" in use_strategies="$default_twohead_strategies" fi ;; *) - var="`git-config --get pull.octopus`" + var="`git config --get pull.octopus`" if test -n "$var" then use_strategies="$var" @@ -278,10 +278,10 @@ done case "$#" in 1) - common=$(git-merge-base --all $head "$@") + common=$(git merge-base --all $head "$@") ;; *) - common=$(git-show-branch --merge-base $head "$@") + common=$(git show-branch --merge-base $head "$@") ;; esac echo "$head" >"$GIT_DIR/ORIG_HEAD" @@ -301,15 +301,15 @@ f,*) ;; ?,1,"$head",*) # Again the most common case of merging one remote. - echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $1)" - git-update-index --refresh 2>/dev/null + echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)" + git update-index --refresh 2>/dev/null msg="Fast forward" if test -n "$have_message" then msg="$msg (no commit created; -m option ignored)" fi - new_head=$(git-rev-parse --verify "$1^0") && - git-read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" && + new_head=$(git rev-parse --verify "$1^0") && + git read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" && finish "$new_head" "$msg" || exit dropsave exit 0 @@ -321,7 +321,7 @@ f,*) ?,1,*,) # We are not doing octopus, not fast forward, and have only # one common. - git-update-index --refresh 2>/dev/null + git update-index --refresh 2>/dev/null case " $use_strategies " in *' recursive '*|*' recur '*) : run merge later @@ -330,13 +330,13 @@ f,*) # See if it is really trivial. git var GIT_COMMITTER_IDENT >/dev/null || exit echo "Trying really trivial in-index merge..." - if git-read-tree --trivial -m -u -v $common $head "$1" && - result_tree=$(git-write-tree) + if git read-tree --trivial -m -u -v $common $head "$1" && + result_tree=$(git write-tree) then echo "Wonderful." result_commit=$( printf '%s\n' "$merge_msg" | - git-commit-tree $result_tree -p HEAD -p "$1" + git commit-tree $result_tree -p HEAD -p "$1" ) || exit finish "$result_commit" "In-index merge" dropsave @@ -350,7 +350,7 @@ f,*) up_to_date=t for remote do - common_one=$(git-merge-base --all $head $remote) + common_one=$(git merge-base --all $head $remote) if test "$common_one" != "$remote" then up_to_date=f @@ -419,8 +419,8 @@ do if test "$exit" -eq 1 then cnt=`{ - git-diff-files --name-only - git-ls-files --unmerged + git diff-files --name-only + git ls-files --unmerged } | wc -l` if test $best_cnt -le 0 -o $cnt -le $best_cnt then @@ -432,15 +432,15 @@ do } # Automerge succeeded. - result_tree=$(git-write-tree) && break + result_tree=$(git write-tree) && break done # If we have a resulting tree, that means the strategy module # auto resolved the merge cleanly. if test '' != "$result_tree" then - parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /') - result_commit=$(printf '%s\n' "$merge_msg" | git-commit-tree $result_tree $parents) || exit + parents=$(git show-branch --independent "$head" "$@" | sed -e 's/^/-p /') + result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree $result_tree $parents) || exit finish "$result_commit" "Merge made by $wt_strategy." dropsave exit 0 @@ -498,7 +498,7 @@ Conflicts: } >>"$GIT_DIR/MERGE_MSG" if test -d "$GIT_DIR/rr-cache" then - git-rerere + git rerere fi die "Automatic merge failed; fix conflicts and then commit the result." fi diff --git a/git-mergetool.sh b/git-mergetool.sh index 7b66309193..47a80553ad 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -65,14 +65,14 @@ resolve_symlink_merge () { read ans case "$ans" in [lL]*) - git-checkout-index -f --stage=2 -- "$path" - git-add -- "$path" + git checkout-index -f --stage=2 -- "$path" + git add -- "$path" cleanup_temp_files --save-backup return ;; [rR]*) - git-checkout-index -f --stage=3 -- "$path" - git-add -- "$path" + git checkout-index -f --stage=3 -- "$path" + git add -- "$path" cleanup_temp_files --save-backup return ;; @@ -93,12 +93,12 @@ resolve_deleted_merge () { read ans case "$ans" in [mMcC]*) - git-add -- "$path" + git add -- "$path" cleanup_temp_files --save-backup return ;; [dD]*) - git-rm -- "$path" > /dev/null + git rm -- "$path" > /dev/null cleanup_temp_files return ;; @@ -140,7 +140,7 @@ remove_backup () { merge_file () { path="$1" - f=`git-ls-files -u -- "$path"` + f=`git ls-files -u -- "$path"` if test -z "$f" ; then if test ! -f "$path" ; then echo "$path: file not found" @@ -297,7 +297,7 @@ do done if test -z "$merge_tool"; then - merge_tool=`git-config merge.tool` + merge_tool=`git config merge.tool` case "$merge_tool" in kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | "") ;; # happy diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 0506b12cb2..695a4094bb 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -2,7 +2,7 @@ # git-ls-remote could be called from outside a git managed repository; # this would fail in that case and would issue an error message. -GIT_DIR=$(git-rev-parse --git-dir 2>/dev/null) || :; +GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) || :; get_data_source () { case "$1" in @@ -13,7 +13,7 @@ get_data_source () { echo self ;; *) - if test "$(git-config --get "remote.$1.url")" + if test "$(git config --get "remote.$1.url")" then echo config elif test -f "$GIT_DIR/remotes/$1" @@ -38,7 +38,7 @@ get_remote_url () { echo "$1" ;; config) - git-config --get "remote.$1.url" + git config --get "remote.$1.url" ;; remotes) sed -ne '/^URL: */{ @@ -55,8 +55,8 @@ get_remote_url () { } get_default_remote () { - curr_branch=$(git-symbolic-ref -q HEAD | sed -e 's|^refs/heads/||') - origin=$(git-config --get "branch.$curr_branch.remote") + curr_branch=$(git symbolic-ref -q HEAD | sed -e 's|^refs/heads/||') + origin=$(git config --get "branch.$curr_branch.remote") echo ${origin:-origin} } @@ -66,7 +66,7 @@ get_remote_default_refs_for_push () { '' | branches | self) ;; # no default push mapping, just send matching refs. config) - git-config --get-all "remote.$1.push" ;; + git config --get-all "remote.$1.push" ;; remotes) sed -ne '/^Push: */{ s///p @@ -107,9 +107,9 @@ canon_refs_list_for_fetch () { shift if test "$remote" = "$(get_default_remote)" then - curr_branch=$(git-symbolic-ref -q HEAD | \ + curr_branch=$(git symbolic-ref -q HEAD | \ sed -e 's|^refs/heads/||') - merge_branches=$(git-config \ + merge_branches=$(git config \ --get-all "branch.${curr_branch}.merge") fi if test -z "$merge_branches" && test $is_explicit != explicit @@ -156,7 +156,7 @@ canon_refs_list_for_fetch () { if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)') then - git-check-ref-format "$local_ref_name" || + git check-ref-format "$local_ref_name" || die "* refusing to create funny ref '$local_ref_name' locally" fi echo "${dot_prefix}${force}${remote}:${local}" @@ -171,11 +171,11 @@ get_remote_default_refs_for_fetch () { echo "HEAD:" ;; self) canon_refs_list_for_fetch -d "$1" \ - $(git-for-each-ref --format='%(refname):') + $(git for-each-ref --format='%(refname):') ;; config) canon_refs_list_for_fetch -d "$1" \ - $(git-config --get-all "remote.$1.fetch") ;; + $(git config --get-all "remote.$1.fetch") ;; branches) remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1") case "$remote_branch" in '') remote_branch=master ;; esac @@ -254,7 +254,7 @@ get_uploadpack () { data_source=$(get_data_source "$1") case "$data_source" in config) - uplp=$(git-config --get "remote.$1.uploadpack") + uplp=$(git config --get "remote.$1.uploadpack") echo ${uplp:-git-upload-pack} ;; *) diff --git a/git-pull.sh b/git-pull.sh index ba0ca079e2..5e96d1f228 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -54,10 +54,10 @@ do shift done -orig_head=$(git-rev-parse --verify HEAD 2>/dev/null) +orig_head=$(git rev-parse --verify HEAD 2>/dev/null) git-fetch --update-head-ok "$@" || exit 1 -curr_head=$(git-rev-parse --verify HEAD 2>/dev/null) +curr_head=$(git rev-parse --verify HEAD 2>/dev/null) if test "$curr_head" != "$orig_head" then # The fetch involved updating the current branch. @@ -69,8 +69,8 @@ then echo >&2 "Warning: fetch updated the current branch head." echo >&2 "Warning: fast forwarding your working tree from" echo >&2 "Warning: commit $orig_head." - git-update-index --refresh 2>/dev/null - git-read-tree -u -m "$orig_head" "$curr_head" || + git update-index --refresh 2>/dev/null + git read-tree -u -m "$orig_head" "$curr_head" || die 'Cannot fast-forward your working tree. After making sure that you saved anything precious from $ git diff '$orig_head' @@ -86,7 +86,7 @@ merge_head=$(sed -e '/ not-for-merge /d' \ case "$merge_head" in '') - curr_branch=$(git-symbolic-ref -q HEAD) + curr_branch=$(git symbolic-ref -q HEAD) case $? in 0) ;; 1) echo >&2 "You are not currently on a branch; you must explicitly" @@ -113,11 +113,11 @@ esac if test -z "$orig_head" then - git-update-ref -m "initial pull" HEAD $merge_head "" && - git-read-tree --reset -u HEAD || exit 1 + git update-ref -m "initial pull" HEAD $merge_head "" && + git read-tree --reset -u HEAD || exit 1 exit fi -merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit +merge_name=$(git fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit exec git-merge $no_summary $no_commit $squash $strategy_args \ "$merge_name" HEAD $merge_head diff --git a/git-quiltimport.sh b/git-quiltimport.sh index a7a6757dd8..2124df9e4a 100755 --- a/git-quiltimport.sh +++ b/git-quiltimport.sh @@ -67,12 +67,12 @@ tmp_info="$tmp_dir/info" # Find the intial commit -commit=$(git-rev-parse HEAD) +commit=$(git rev-parse HEAD) mkdir $tmp_dir || exit 2 for patch_name in $(cat "$QUILT_PATCHES/series" | grep -v '^#'); do echo $patch_name - (cat $QUILT_PATCHES/$patch_name | git-mailinfo "$tmp_msg" "$tmp_patch" > "$tmp_info") || exit 3 + (cat $QUILT_PATCHES/$patch_name | git mailinfo "$tmp_msg" "$tmp_patch" > "$tmp_info") || exit 3 test -s .dotest/patch || { echo "Patch is empty. Was it split wrong?" exit 1 @@ -113,10 +113,10 @@ for patch_name in $(cat "$QUILT_PATCHES/series" | grep -v '^#'); do fi if [ -z "$dry_run" ] ; then - git-apply --index -C1 "$tmp_patch" && - tree=$(git-write-tree) && - commit=$( (echo "$SUBJECT"; echo; cat "$tmp_msg") | git-commit-tree $tree -p $commit) && - git-update-ref -m "quiltimport: $patch_name" HEAD $commit || exit 4 + git apply --index -C1 "$tmp_patch" && + tree=$(git write-tree) && + commit=$( (echo "$SUBJECT"; echo; cat "$tmp_msg") | git commit-tree $tree -p $commit) && + git update-ref -m "quiltimport: $patch_name" HEAD $commit || exit 4 fi done rm -rf $tmp_dir || exit 5 diff --git a/git-rebase.sh b/git-rebase.sh index 388752661f..c590661179 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -51,7 +51,7 @@ continue_merge () { test -n "$prev_head" || die "prev_head must be defined" test -d "$dotest" || die "$dotest directory does not exist" - unmerged=$(git-ls-files -u) + unmerged=$(git ls-files -u) if test -n "$unmerged" then echo "You still have unmerged paths in your index" @@ -59,7 +59,7 @@ continue_merge () { die "$RESOLVEMSG" fi - if ! git-diff-index --quiet HEAD + if ! git diff-index --quiet HEAD then if ! git-commit -C "`cat $dotest/current`" then @@ -71,10 +71,10 @@ continue_merge () { else printf "Already applied: %0${prec}d" $msgnum fi - echo ' '`git-rev-list --pretty=oneline -1 HEAD | \ + echo ' '`git rev-list --pretty=oneline -1 HEAD | \ sed 's/^[a-f0-9]\+ //'` - prev_head=`git-rev-parse HEAD^0` + prev_head=`git rev-parse HEAD^0` # save the resulting commit so we can read-tree on it later echo "$prev_head" > "$dotest/prev_head" @@ -86,8 +86,8 @@ continue_merge () { call_merge () { cmt="$(cat $dotest/cmt.$1)" echo "$cmt" > "$dotest/current" - hd=$(git-rev-parse --verify HEAD) - cmt_name=$(git-symbolic-ref HEAD) + hd=$(git rev-parse --verify HEAD) + cmt_name=$(git symbolic-ref HEAD) msgnum=$(cat $dotest/msgnum) end=$(cat $dotest/end) eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"' @@ -101,7 +101,7 @@ call_merge () { return ;; 1) - test -d "$GIT_DIR/rr-cache" && git-rerere + test -d "$GIT_DIR/rr-cache" && git rerere die "$RESOLVEMSG" ;; 2) @@ -134,7 +134,7 @@ while case "$#" in 0) break ;; esac do case "$1" in --continue) - git-diff-files --quiet || { + git diff-files --quiet || { echo "You must edit all merge conflicts and then" echo "mark them as resolved using git add" exit 1 @@ -162,7 +162,7 @@ do then if test -d "$GIT_DIR/rr-cache" then - git-rerere clear + git rerere clear fi prev_head="`cat $dotest/prev_head`" end="`cat $dotest/end`" @@ -183,7 +183,7 @@ do --abort) if test -d "$GIT_DIR/rr-cache" then - git-rerere clear + git rerere clear fi if test -d "$dotest" then @@ -259,8 +259,8 @@ else fi # The tree must be really really clean. -git-update-index --refresh || exit -diff=$(git-diff-index --cached --name-status -r HEAD) +git update-index --refresh || exit +diff=$(git diff-index --cached --name-status -r HEAD) case "$diff" in ?*) echo "cannot rebase: your index is not up-to-date" echo "$diff" @@ -275,7 +275,7 @@ upstream=`git rev-parse --verify "${upstream_name}^0"` || # Make sure the branch to rebase onto is valid. onto_name=${newbase-"$upstream_name"} -onto=$(git-rev-parse --verify "${onto_name}^0") || exit +onto=$(git rev-parse --verify "${onto_name}^0") || exit # If a hook exists, give it a chance to interrupt if test -x "$GIT_DIR/hooks/pre-rebase" @@ -301,13 +301,13 @@ case "$#" in fi ;; esac -branch=$(git-rev-parse --verify "${branch_name}^0") || exit +branch=$(git rev-parse --verify "${branch_name}^0") || exit # Now we are rebasing commits $upstream..$branch on top of $onto # Check if we are already based on $onto, but this should be # done only when upstream and onto are the same. -mb=$(git-merge-base "$onto" "$branch") +mb=$(git merge-base "$onto" "$branch") if test "$upstream" = "$onto" && test "$mb" = "$onto" then echo >&2 "Current branch $branch_name is up to date." @@ -318,7 +318,7 @@ if test -n "$verbose" then echo "Changes from $mb to $onto:" # We want color (if set), but no pager - GIT_PAGER='' git-diff --stat --summary "$mb" "$onto" + GIT_PAGER='' git diff --stat --summary "$mb" "$onto" fi # Rewind the head to "$onto"; this saves our current head in ORIG_HEAD. @@ -335,7 +335,7 @@ fi if test -z "$do_merge" then - git-format-patch -k --stdout --full-index --ignore-if-in-upstream "$upstream"..ORIG_HEAD | + git format-patch -k --stdout --full-index --ignore-if-in-upstream "$upstream"..ORIG_HEAD | git am $git_am_opt --binary -3 -k --resolvemsg="$RESOLVEMSG" exit $? fi @@ -346,11 +346,11 @@ fi mkdir -p "$dotest" echo "$onto" > "$dotest/onto" echo "$onto_name" > "$dotest/onto_name" -prev_head=`git-rev-parse HEAD^0` +prev_head=`git rev-parse HEAD^0` echo "$prev_head" > "$dotest/prev_head" msgnum=0 -for cmt in `git-rev-list --reverse --no-merges "$upstream"..ORIG_HEAD` +for cmt in `git rev-list --reverse --no-merges "$upstream"..ORIG_HEAD` do msgnum=$(($msgnum + 1)) echo "$cmt" > "$dotest/cmt.$msgnum" diff --git a/git-repack.sh b/git-repack.sh index 8c32724be7..3644a5a4d2 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -63,7 +63,7 @@ case ",$all_into_one," in esac args="$args $local $quiet $no_reuse$extra" -names=$(git-pack-objects --non-empty --all --reflog $args /dev/null) +if orig=$(git rev-parse --verify HEAD 2>/dev/null) then echo "$orig" >"$GIT_DIR/ORIG_HEAD" else rm -f "$GIT_DIR/ORIG_HEAD" fi -git-update-ref -m "$GIT_REFLOG_ACTION" HEAD "$rev" +git update-ref -m "$GIT_REFLOG_ACTION" HEAD "$rev" update_ref_status=$? case "$reset_type" in @@ -96,7 +96,7 @@ case "$reset_type" in ;; # Nothing else to do --mixed ) # Report what has not been updated. - git-update-index --refresh + git update-index --refresh ;; esac diff --git a/git-sh-setup.sh b/git-sh-setup.sh index 98959600eb..4ed07e9ddc 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -29,11 +29,11 @@ set_reflog_action() { } is_bare_repository () { - git-rev-parse --is-bare-repository + git rev-parse --is-bare-repository } cd_to_toplevel () { - cdup=$(git-rev-parse --show-cdup) + cdup=$(git rev-parse --show-cdup) if test ! -z "$cdup" then cd "$cdup" || { @@ -44,8 +44,8 @@ cd_to_toplevel () { } require_work_tree () { - test $(git-rev-parse --is-inside-work-tree) = true && - test $(git-rev-parse --is-inside-git-dir) = false || + test $(git rev-parse --is-inside-work-tree) = true && + test $(git rev-parse --is-inside-git-dir) = false || die "fatal: $0 cannot be used without a working tree." } @@ -95,12 +95,12 @@ esac if [ -z "$SUBDIRECTORY_OK" ] then : ${GIT_DIR=.git} - GIT_DIR=$(GIT_DIR="$GIT_DIR" git-rev-parse --git-dir) || { + GIT_DIR=$(GIT_DIR="$GIT_DIR" git rev-parse --git-dir) || { exit=$? echo >&2 "You need to run this command from the toplevel of the working tree." exit $exit } else - GIT_DIR=$(git-rev-parse --git-dir) || exit + GIT_DIR=$(git rev-parse --git-dir) || exit fi : ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"} diff --git a/git-stash.sh b/git-stash.sh index 18d3322ab5..777d1e1351 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -12,8 +12,8 @@ trap 'rm -f "$TMP-*"' 0 ref_stash=refs/stash no_changes () { - git-diff-index --quiet --cached HEAD && - git-diff-files --quiet + git diff-index --quiet --cached HEAD && + git diff-files --quiet } clear_stash () { @@ -32,14 +32,14 @@ save_stash () { clear_stash || die "Cannot initialize stash" # state of the base commit - if b_commit=$(git-rev-parse --verify HEAD) + if b_commit=$(git rev-parse --verify HEAD) then - head=$(git-log --abbrev-commit --pretty=oneline -n 1 HEAD) + head=$(git log --abbrev-commit --pretty=oneline -n 1 HEAD) else die "You do not have the initial commit yet" fi - if branch=$(git-symbolic-ref -q HEAD) + if branch=$(git symbolic-ref -q HEAD) then branch=${branch#refs/heads/} else @@ -48,9 +48,9 @@ save_stash () { msg=$(printf '%s: %s' "$branch" "$head") # state of the index - i_tree=$(git-write-tree) && + i_tree=$(git write-tree) && i_commit=$(printf 'index on %s' "$msg" | - git-commit-tree $i_tree -p $b_commit) || + git commit-tree $i_tree -p $b_commit) || die "Cannot save the current index state" # state of the working tree @@ -59,57 +59,57 @@ save_stash () { export GIT_INDEX_FILE && rm -f "$TMP-index" && - git-read-tree $i_tree && - git-add -u && - git-write-tree && + git read-tree $i_tree && + git add -u && + git write-tree && rm -f "$TMP-index" ) ) || die "Cannot save the current worktree state" # create the stash w_commit=$(printf 'WIP on %s' "$msg" | - git-commit-tree $w_tree -p $b_commit -p $i_commit) || + git commit-tree $w_tree -p $b_commit -p $i_commit) || die "Cannot record working tree state" - git-update-ref -m "$msg" $ref_stash $w_commit || + git update-ref -m "$msg" $ref_stash $w_commit || die "Cannot save the current status" printf >&2 'Saved WIP on %s\n' "$msg" } have_stash () { - git-rev-parse --verify $ref_stash >/dev/null 2>&1 + git rev-parse --verify $ref_stash >/dev/null 2>&1 } list_stash () { have_stash || return 0 - git-log --pretty=oneline -g "$@" $ref_stash | + git log --pretty=oneline -g "$@" $ref_stash | sed -n -e 's/^[.0-9a-f]* refs\///p' } show_stash () { - flags=$(git-rev-parse --no-revs --flags "$@") + flags=$(git rev-parse --no-revs --flags "$@") if test -z "$flags" then flags=--stat fi - s=$(git-rev-parse --revs-only --no-flags --default $ref_stash "$@") + s=$(git rev-parse --revs-only --no-flags --default $ref_stash "$@") - w_commit=$(git-rev-parse --verify "$s") && - b_commit=$(git-rev-parse --verify "$s^") && - git-diff $flags $b_commit $w_commit + w_commit=$(git rev-parse --verify "$s") && + b_commit=$(git rev-parse --verify "$s^") && + git diff $flags $b_commit $w_commit } apply_stash () { - git-diff-files --quiet || + git diff-files --quiet || die 'Cannot restore on top of a dirty state' # current index state - c_tree=$(git-write-tree) || + c_tree=$(git write-tree) || die 'Cannot apply a stash in the middle of a merge' - s=$(git-rev-parse --revs-only --no-flags --default $ref_stash "$@") && - w_tree=$(git-rev-parse --verify "$s:") && - b_tree=$(git-rev-parse --verify "$s^:") || + s=$(git rev-parse --revs-only --no-flags --default $ref_stash "$@") && + w_tree=$(git rev-parse --verify "$s:") && + b_tree=$(git rev-parse --verify "$s^:") || die "$*: no valid stashed state found" eval " @@ -123,9 +123,9 @@ apply_stash () { then # No conflict a="$TMP-added" && - git-diff --cached --name-only --diff-filter=A $c_tree >"$a" && - git-read-tree --reset $c_tree && - git-update-index --add --stdin <"$a" || + git diff --cached --name-only --diff-filter=A $c_tree >"$a" && + git read-tree --reset $c_tree && + git update-index --add --stdin <"$a" || die "Cannot unstage modified files" git-status rm -f "$a" diff --git a/git-submodule.sh b/git-submodule.sh index c29e2c3c9d..0ba016135f 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -46,7 +46,7 @@ get_repo_base() { # module_name() { - name=$(GIT_CONFIG=.gitmodules git-config --get-regexp '^submodule\..*\.path$' "$1" | + name=$(GIT_CONFIG=.gitmodules git config --get-regexp '^submodule\..*\.path$' "$1" | sed -nre 's/^submodule\.(.+)\.path .+$/\1/p') test -z "$name" && die "No submodule mapping found in .gitmodules for path '$path'" @@ -116,7 +116,7 @@ module_add() test -e "$path" && die "'$path' already exists" - git-ls-files --error-unmatch "$path" > /dev/null 2>&1 && + git ls-files --error-unmatch "$path" > /dev/null 2>&1 && die "'$path' already exists in the index" module_clone "$path" "$repo" || exit @@ -143,14 +143,14 @@ modules_init() do # Skip already registered paths name=$(module_name "$path") || exit - url=$(git-config submodule."$name".url) + url=$(git config submodule."$name".url) test -z "$url" || continue - url=$(GIT_CONFIG=.gitmodules git-config submodule."$name".url) + url=$(GIT_CONFIG=.gitmodules git config submodule."$name".url) test -z "$url" && die "No url found for submodule path '$path' in .gitmodules" - git-config submodule."$name".url "$url" || + git config submodule."$name".url "$url" || die "Failed to register url for submodule path '$path'" say "Submodule '$name' ($url) registered for path '$path'" @@ -168,7 +168,7 @@ modules_update() while read mode sha1 stage path do name=$(module_name "$path") || exit - url=$(git-config submodule."$name".url) + url=$(git config submodule."$name".url) if test -z "$url" then # Only mention uninitialized submodules when its @@ -184,7 +184,7 @@ modules_update() subsha1= else subsha1=$(unset GIT_DIR && cd "$path" && - git-rev-parse --verify HEAD) || + git rev-parse --verify HEAD) || die "Unable to find current revision in submodule path '$path'" fi @@ -203,9 +203,9 @@ set_name_rev () { revname=$( ( unset GIT_DIR && cd "$1" && { - git-describe "$2" 2>/dev/null || - git-describe --tags "$2" 2>/dev/null || - git-describe --contains --tags "$2" + git describe "$2" 2>/dev/null || + git describe --tags "$2" 2>/dev/null || + git describe --contains --tags "$2" } ) ) test -z "$revname" || revname=" ($revname)" @@ -227,13 +227,13 @@ modules_list() while read mode sha1 stage path do name=$(module_name "$path") || exit - url=$(git-config submodule."$name".url) + url=$(git config submodule."$name".url) if test -z "url" || ! test -d "$path"/.git then say "-$sha1 $path" continue; fi - revname=$(unset GIT_DIR && cd "$path" && git-describe --tags $sha1) + revname=$(unset GIT_DIR && cd "$path" && git describe --tags $sha1) set_name_rev "$path" $"sha1" if git diff-files --quiet -- "$path" then @@ -241,7 +241,7 @@ modules_list() else if test -z "$cached" then - sha1=$(unset GIT_DIR && cd "$path" && git-rev-parse --verify HEAD) + sha1=$(unset GIT_DIR && cd "$path" && git rev-parse --verify HEAD) set_name_rev "$path" $"sha1" fi say "+$sha1 $path$revname" diff --git a/git-tag.sh b/git-tag.sh index 1ff5b41e7f..1c25d88c72 100755 --- a/git-tag.sh +++ b/git-tag.sh @@ -118,12 +118,12 @@ do had_error=0 for tag do - cur=$(git-show-ref --verify --hash -- "refs/tags/$tag") || { + cur=$(git show-ref --verify --hash -- "refs/tags/$tag") || { echo >&2 "Seriously, what tag are you talking about?" had_error=1 continue } - git-update-ref -m 'tag: delete' -d "refs/tags/$tag" "$cur" || { + git update-ref -m 'tag: delete' -d "refs/tags/$tag" "$cur" || { had_error=1 continue } @@ -134,7 +134,7 @@ do -v) shift tag_name="$1" - tag=$(git-show-ref --verify --hash -- "refs/tags/$tag_name") || + tag=$(git show-ref --verify --hash -- "refs/tags/$tag_name") || die "Seriously, what tag are you talking about?" git-verify-tag -v "$tag" exit $? @@ -153,21 +153,21 @@ done name="$1" [ "$name" ] || usage prev=0000000000000000000000000000000000000000 -if git-show-ref --verify --quiet -- "refs/tags/$name" +if git show-ref --verify --quiet -- "refs/tags/$name" then test -n "$force" || die "tag '$name' already exists" prev=`git rev-parse "refs/tags/$name"` fi shift -git-check-ref-format "tags/$name" || +git check-ref-format "tags/$name" || die "we do not like '$name' as a tag name." -object=$(git-rev-parse --verify --default HEAD "$@") || exit 1 -type=$(git-cat-file -t $object) || exit 1 +object=$(git rev-parse --verify --default HEAD "$@") || exit 1 +type=$(git cat-file -t $object) || exit 1 tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1 test -n "$username" || - username=$(git-repo-config user.signingkey) || + username=$(git repo-config user.signingkey) || username=$(expr "z$tagger" : 'z\(.*>\)') trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0 @@ -183,7 +183,7 @@ if [ "$annotate" ]; then fi grep -v '^#' <"$GIT_DIR"/TAG_EDITMSG | - git-stripspace >"$GIT_DIR"/TAG_FINALMSG + git stripspace >"$GIT_DIR"/TAG_FINALMSG [ -s "$GIT_DIR"/TAG_FINALMSG -o -n "$message_given" ] || { echo >&2 "No tag message?" diff --git a/git-verify-tag.sh b/git-verify-tag.sh index 68858b694d..37b0023b27 100755 --- a/git-verify-tag.sh +++ b/git-verify-tag.sh @@ -21,7 +21,7 @@ then usage fi -type="$(git-cat-file -t "$1" 2>/dev/null)" || +type="$(git cat-file -t "$1" 2>/dev/null)" || die "$1: no such object." test "$type" = tag || @@ -29,14 +29,14 @@ test "$type" = tag || case "$verbose" in t) - git-cat-file -p "$1" | + git cat-file -p "$1" | sed -n -e '/^-----BEGIN PGP SIGNATURE-----/q' -e p ;; esac trap 'rm -f "$GIT_DIR/.tmp-vtag"' 0 -git-cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1 +git cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1 sed -n -e ' /^-----BEGIN PGP SIGNATURE-----$/q p diff --git a/t/lib-read-tree-m-3way.sh b/t/lib-read-tree-m-3way.sh index 586df2113f..168329adbc 100644 --- a/t/lib-read-tree-m-3way.sh +++ b/t/lib-read-tree-m-3way.sh @@ -10,14 +10,14 @@ do echo This is Z/$p from the original tree. >Z/$p test_expect_success \ "adding test file $p and Z/$p" \ - 'git-update-index --add $p && - git-update-index --add Z/$p' + 'git update-index --add $p && + git update-index --add Z/$p' done done echo This is SS from the original tree. >SS test_expect_success \ 'adding test file SS' \ - 'git-update-index --add SS' + 'git update-index --add SS' cat >TT <<\EOF This is a trivial merge sample text. Branch A is expected to upcase this word, here. @@ -32,10 +32,10 @@ This concludes the trivial merge sample file. EOF test_expect_success \ 'adding test file TT' \ - 'git-update-index --add TT' + 'git update-index --add TT' test_expect_success \ 'prepare initial tree' \ - 'tree_O=$(git-write-tree)' + 'tree_O=$(git write-tree)' ################################################################ # Branch A and B makes the changes according to the above matrix. @@ -47,14 +47,14 @@ to_remove=$(echo D? Z/D?) rm -f $to_remove test_expect_success \ 'change in branch A (removal)' \ - 'git-update-index --remove $to_remove' + 'git update-index --remove $to_remove' for p in M? Z/M? do echo This is modified $p in the branch A. >$p test_expect_success \ 'change in branch A (modification)' \ - "git-update-index $p" + "git update-index $p" done for p in AN AA Z/AN Z/AA @@ -62,31 +62,31 @@ do echo This is added $p in the branch A. >$p test_expect_success \ 'change in branch A (addition)' \ - "git-update-index --add $p" + "git update-index --add $p" done echo This is SS from the modified tree. >SS echo This is LL from the modified tree. >LL test_expect_success \ 'change in branch A (addition)' \ - 'git-update-index --add LL && - git-update-index SS' + 'git update-index --add LL && + git update-index SS' mv TT TT- sed -e '/Branch A/s/word/WORD/g' TT rm -f TT- test_expect_success \ 'change in branch A (edit)' \ - 'git-update-index TT' + 'git update-index TT' mkdir DF echo Branch A makes a file at DF/DF, creating a directory DF. >DF/DF test_expect_success \ 'change in branch A (change file to directory)' \ - 'git-update-index --add DF/DF' + 'git update-index --add DF/DF' test_expect_success \ 'recording branch A tree' \ - 'tree_A=$(git-write-tree)' + 'tree_A=$(git write-tree)' ################################################################ # Branch B @@ -96,21 +96,21 @@ rm -rf [NDMASLT][NDMASLT] Z DF mkdir Z test_expect_success \ 'reading original tree and checking out' \ - 'git-read-tree $tree_O && - git-checkout-index -a' + 'git read-tree $tree_O && + git checkout-index -a' to_remove=$(echo ?D Z/?D) rm -f $to_remove test_expect_success \ 'change in branch B (removal)' \ - "git-update-index --remove $to_remove" + "git update-index --remove $to_remove" for p in ?M Z/?M do echo This is modified $p in the branch B. >$p test_expect_success \ 'change in branch B (modification)' \ - "git-update-index $p" + "git update-index $p" done for p in NA AA Z/NA Z/AA @@ -118,41 +118,41 @@ do echo This is added $p in the branch B. >$p test_expect_success \ 'change in branch B (addition)' \ - "git-update-index --add $p" + "git update-index --add $p" done echo This is SS from the modified tree. >SS echo This is LL from the modified tree. >LL test_expect_success \ 'change in branch B (addition and modification)' \ - 'git-update-index --add LL && - git-update-index SS' + 'git update-index --add LL && + git update-index SS' mv TT TT- sed -e '/Branch B/s/word/WORD/g' TT rm -f TT- test_expect_success \ 'change in branch B (modification)' \ - 'git-update-index TT' + 'git update-index TT' echo Branch B makes a file at DF. >DF test_expect_success \ 'change in branch B (addition of a file to conflict with directory)' \ - 'git-update-index --add DF' + 'git update-index --add DF' test_expect_success \ 'recording branch B tree' \ - 'tree_B=$(git-write-tree)' + 'tree_B=$(git write-tree)' test_expect_success \ 'keep contents of 3 trees for easy access' \ 'rm -f .git/index && - git-read-tree $tree_O && + git read-tree $tree_O && mkdir .orig-O && - git-checkout-index --prefix=.orig-O/ -f -q -a && + git checkout-index --prefix=.orig-O/ -f -q -a && rm -f .git/index && - git-read-tree $tree_A && + git read-tree $tree_A && mkdir .orig-A && - git-checkout-index --prefix=.orig-A/ -f -q -a && + git checkout-index --prefix=.orig-A/ -f -q -a && rm -f .git/index && - git-read-tree $tree_B && + git read-tree $tree_B && mkdir .orig-B && - git-checkout-index --prefix=.orig-B/ -f -q -a' + git checkout-index --prefix=.orig-B/ -f -q -a' diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 8bfe8320ea..4bba9c0717 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -31,12 +31,12 @@ fi . ./test-lib.sh ################################################################ -# git-init has been done in an empty repository. +# git init has been done in an empty repository. # make sure it is empty. find .git/objects -type f -print >should-be-empty test_expect_success \ - '.git/objects should be empty after git-init in an empty repo.' \ + '.git/objects should be empty after git init in an empty repo.' \ 'cmp -s /dev/null should-be-empty' # also it should have 2 subdirectories; no fan-out anymore, pack, and info. @@ -51,17 +51,17 @@ test_expect_success \ # updating a new file without --add should fail. test_expect_failure \ - 'git-update-index without --add should fail adding.' \ - 'git-update-index should-be-empty' + 'git update-index without --add should fail adding.' \ + 'git update-index should-be-empty' # and with --add it should succeed, even if it is empty (it used to fail). test_expect_success \ - 'git-update-index with --add should succeed.' \ - 'git-update-index --add should-be-empty' + 'git update-index with --add should succeed.' \ + 'git update-index --add should-be-empty' test_expect_success \ - 'writing tree out with git-write-tree' \ - 'tree=$(git-write-tree)' + 'writing tree out with git write-tree' \ + 'tree=$(git write-tree)' # we know the shape and contents of the tree and know the object ID for it. test_expect_success \ @@ -71,17 +71,17 @@ test_expect_success \ # Removing paths. rm -f should-be-empty full-of-directories test_expect_failure \ - 'git-update-index without --remove should fail removing.' \ - 'git-update-index should-be-empty' + 'git update-index without --remove should fail removing.' \ + 'git update-index should-be-empty' test_expect_success \ - 'git-update-index with --remove should be able to remove.' \ - 'git-update-index --remove should-be-empty' + 'git update-index with --remove should be able to remove.' \ + 'git update-index --remove should-be-empty' # Empty tree can be written with recent write-tree. test_expect_success \ - 'git-write-tree should be able to write an empty tree.' \ - 'tree=$(git-write-tree)' + 'git write-tree should be able to write an empty tree.' \ + 'tree=$(git write-tree)' test_expect_success \ 'validate object ID of a known tree.' \ @@ -95,13 +95,13 @@ do ln -s "hello $p" ${p}sym done test_expect_success \ - 'adding various types of objects with git-update-index --add.' \ - 'find path* ! -type d -print | xargs git-update-index --add' + 'adding various types of objects with git update-index --add.' \ + 'find path* ! -type d -print | xargs git update-index --add' # Show them and see that matches what we expect. test_expect_success \ - 'showing stage with git-ls-files --stage' \ - 'git-ls-files --stage >current' + 'showing stage with git ls-files --stage' \ + 'git ls-files --stage >current' cat >expected <<\EOF 100644 f87290f8eb2cbbea7857214459a0739927eab154 0 path0 @@ -114,19 +114,19 @@ cat >expected <<\EOF 120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0 path3/subp3/file3sym EOF test_expect_success \ - 'validate git-ls-files output for a known tree.' \ + 'validate git ls-files output for a known tree.' \ 'diff current expected' test_expect_success \ - 'writing tree out with git-write-tree.' \ - 'tree=$(git-write-tree)' + 'writing tree out with git write-tree.' \ + 'tree=$(git write-tree)' test_expect_success \ 'validate object ID for a known tree.' \ 'test "$tree" = 087704a96baf1c2d1c869a8b084481e121c88b5b' test_expect_success \ - 'showing tree with git-ls-tree' \ - 'git-ls-tree $tree >current' + 'showing tree with git ls-tree' \ + 'git ls-tree $tree >current' cat >expected <<\EOF 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym @@ -134,14 +134,14 @@ cat >expected <<\EOF 040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3 EOF test_expect_success \ - 'git-ls-tree output for a known tree.' \ + 'git ls-tree output for a known tree.' \ 'diff current expected' # This changed in ls-tree pathspec change -- recursive does # not show tree nodes anymore. test_expect_success \ - 'showing tree with git-ls-tree -r' \ - 'git-ls-tree -r $tree >current' + 'showing tree with git ls-tree -r' \ + 'git ls-tree -r $tree >current' cat >expected <<\EOF 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym @@ -153,13 +153,13 @@ cat >expected <<\EOF 120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym EOF test_expect_success \ - 'git-ls-tree -r output for a known tree.' \ + 'git ls-tree -r output for a known tree.' \ 'diff current expected' # But with -r -t we can have both. test_expect_success \ - 'showing tree with git-ls-tree -r -t' \ - 'git-ls-tree -r -t $tree >current' + 'showing tree with git ls-tree -r -t' \ + 'git ls-tree -r -t $tree >current' cat >expected <<\EOF 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym @@ -174,19 +174,19 @@ cat >expected <<\EOF 120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym EOF test_expect_success \ - 'git-ls-tree -r output for a known tree.' \ + 'git ls-tree -r output for a known tree.' \ 'diff current expected' test_expect_success \ - 'writing partial tree out with git-write-tree --prefix.' \ - 'ptree=$(git-write-tree --prefix=path3)' + 'writing partial tree out with git write-tree --prefix.' \ + 'ptree=$(git write-tree --prefix=path3)' test_expect_success \ 'validate object ID for a known tree.' \ 'test "$ptree" = 21ae8269cacbe57ae09138dcc3a2887f904d02b3' test_expect_success \ - 'writing partial tree out with git-write-tree --prefix.' \ - 'ptree=$(git-write-tree --prefix=path3/subp3)' + 'writing partial tree out with git write-tree --prefix.' \ + 'ptree=$(git write-tree --prefix=path3/subp3)' test_expect_success \ 'validate object ID for a known tree.' \ 'test "$ptree" = 3c5e5399f3a333eddecce7a9b9465b63f65f51e2' @@ -202,24 +202,24 @@ EOF rm .git/index test_expect_success \ 'put invalid objects into the index.' \ - 'git-update-index --index-info < badobjects' + 'git update-index --index-info < badobjects' test_expect_failure \ 'writing this tree without --missing-ok.' \ - 'git-write-tree' + 'git write-tree' test_expect_success \ 'writing this tree with --missing-ok.' \ - 'git-write-tree --missing-ok' + 'git write-tree --missing-ok' ################################################################ rm .git/index test_expect_success \ - 'git-read-tree followed by write-tree should be idempotent.' \ - 'git-read-tree $tree && + 'git read-tree followed by write-tree should be idempotent.' \ + 'git read-tree $tree && test -f .git/index && - newtree=$(git-write-tree) && + newtree=$(git write-tree) && test "$newtree" = "$tree"' cat >expected <<\EOF @@ -233,36 +233,36 @@ cat >expected <<\EOF :120000 120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0000000000000000000000000000000000000000 M path3/subp3/file3sym EOF test_expect_success \ - 'validate git-diff-files output for a know cache/work tree state.' \ - 'git-diff-files >current && diff >/dev/null -b current expected' + 'validate git diff-files output for a know cache/work tree state.' \ + 'git diff-files >current && diff >/dev/null -b current expected' test_expect_success \ - 'git-update-index --refresh should succeed.' \ - 'git-update-index --refresh' + 'git update-index --refresh should succeed.' \ + 'git update-index --refresh' test_expect_success \ - 'no diff after checkout and git-update-index --refresh.' \ - 'git-diff-files >current && cmp -s current /dev/null' + 'no diff after checkout and git update-index --refresh.' \ + 'git diff-files >current && cmp -s current /dev/null' ################################################################ P=087704a96baf1c2d1c869a8b084481e121c88b5b test_expect_success \ - 'git-commit-tree records the correct tree in a commit.' \ - 'commit0=$(echo NO | git-commit-tree $P) && + 'git commit-tree records the correct tree in a commit.' \ + 'commit0=$(echo NO | git commit-tree $P) && tree=$(git show --pretty=raw $commit0 | sed -n -e "s/^tree //p" -e "/^author /q") && test "z$tree" = "z$P"' test_expect_success \ - 'git-commit-tree records the correct parent in a commit.' \ - 'commit1=$(echo NO | git-commit-tree $P -p $commit0) && + 'git commit-tree records the correct parent in a commit.' \ + 'commit1=$(echo NO | git commit-tree $P -p $commit0) && parent=$(git show --pretty=raw $commit1 | sed -n -e "s/^parent //p" -e "/^author /q") && test "z$commit0" = "z$parent"' test_expect_success \ - 'git-commit-tree omits duplicated parent in a commit.' \ - 'commit2=$(echo NO | git-commit-tree $P -p $commit0 -p $commit0) && + 'git commit-tree omits duplicated parent in a commit.' \ + 'commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) && parent=$(git show --pretty=raw $commit2 | sed -n -e "s/^parent //p" -e "/^author /q" | sort -u) && diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh index f4294d72d9..fdc9fdce6f 100755 --- a/t/t0030-stripspace.sh +++ b/t/t0030-stripspace.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Carlos Rica # -test_description='git-stripspace' +test_description='git stripspace' . ./test-lib.sh @@ -15,292 +15,292 @@ ttt="$t40$t40$t40$t40$t40$t40$t40$t40$t40$t40" # 400 test_expect_success \ 'long lines without spaces should be unchanged' ' echo "$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual && echo "$ttt$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual && echo "$ttt$ttt$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual && echo "$ttt$ttt$ttt$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual ' test_expect_success \ 'lines with spaces at the beginning should be unchanged' ' echo "$sss$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual && echo "$sss$sss$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual && echo "$sss$sss$sss$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual ' test_expect_success \ 'lines with intermediate spaces should be unchanged' ' echo "$ttt$sss$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual && echo "$ttt$sss$sss$ttt" >expect && - git-stripspace actual && + git stripspace actual && git diff expect actual ' test_expect_success \ 'consecutive blank lines should be unified' ' printf "$ttt\n\n$ttt\n" > expect && - printf "$ttt\n\n\n\n\n$ttt\n" | git-stripspace >actual && + printf "$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt\n\n$ttt\n" > expect && - printf "$ttt$ttt\n\n\n\n\n$ttt\n" | git-stripspace >actual && + printf "$ttt$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt$ttt\n\n$ttt\n" > expect && - printf "$ttt$ttt$ttt\n\n\n\n\n$ttt\n" | git-stripspace >actual && + printf "$ttt$ttt$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n\n$ttt\n" > expect && - printf "$ttt\n\n\n\n\n$ttt\n" | git-stripspace >actual && + printf "$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n\n$ttt$ttt\n" > expect && - printf "$ttt\n\n\n\n\n$ttt$ttt\n" | git-stripspace >actual && + printf "$ttt\n\n\n\n\n$ttt$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && - printf "$ttt\n\n\n\n\n$ttt$ttt$ttt\n" | git-stripspace >actual && + printf "$ttt\n\n\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && git diff expect actual ' test_expect_success \ 'consecutive blank lines at the beginning should be removed' ' printf "" > expect && - printf "\n" | git-stripspace >actual && + printf "\n" | git stripspace >actual && git diff expect actual && printf "" > expect && - printf "\n\n\n" | git-stripspace >actual && + printf "\n\n\n" | git stripspace >actual && git diff expect actual && printf "" > expect && - printf "$sss\n$sss\n$sss\n" | git-stripspace >actual && + printf "$sss\n$sss\n$sss\n" | git stripspace >actual && git diff expect actual && printf "" > expect && - printf "$sss$sss\n$sss\n\n" | git-stripspace >actual && + printf "$sss$sss\n$sss\n\n" | git stripspace >actual && git diff expect actual && printf "" > expect && - printf "\n$sss\n$sss$sss\n" | git-stripspace >actual && + printf "\n$sss\n$sss$sss\n" | git stripspace >actual && git diff expect actual && printf "" > expect && - printf "$sss$sss$sss$sss\n\n\n" | git-stripspace >actual && + printf "$sss$sss$sss$sss\n\n\n" | git stripspace >actual && git diff expect actual && printf "" > expect && - printf "\n$sss$sss$sss$sss\n\n" | git-stripspace >actual && + printf "\n$sss$sss$sss$sss\n\n" | git stripspace >actual && git diff expect actual && printf "" > expect && - printf "\n\n$sss$sss$sss$sss\n" | git-stripspace >actual && + printf "\n\n$sss$sss$sss$sss\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "\n$ttt\n" | git-stripspace >actual && + printf "\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "\n\n\n$ttt\n" | git-stripspace >actual && + printf "\n\n\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt\n" > expect && - printf "\n\n\n$ttt$ttt\n" | git-stripspace >actual && + printf "\n\n\n$ttt$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt$ttt\n" > expect && - printf "\n\n\n$ttt$ttt$ttt\n" | git-stripspace >actual && + printf "\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt$ttt$ttt\n" > expect && - printf "\n\n\n$ttt$ttt$ttt$ttt\n" | git-stripspace >actual && + printf "\n\n\n$ttt$ttt$ttt$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$sss\n$sss\n$sss\n$ttt\n" | git-stripspace >actual && + printf "$sss\n$sss\n$sss\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "\n$sss\n$sss$sss\n$ttt\n" | git-stripspace >actual && + printf "\n$sss\n$sss$sss\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$sss$sss\n$sss\n\n$ttt\n" | git-stripspace >actual && + printf "$sss$sss\n$sss\n\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$sss$sss$sss\n\n\n$ttt\n" | git-stripspace >actual && + printf "$sss$sss$sss\n\n\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "\n$sss$sss$sss\n\n$ttt\n" | git-stripspace >actual && + printf "\n$sss$sss$sss\n\n$ttt\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "\n\n$sss$sss$sss\n$ttt\n" | git-stripspace >actual && + printf "\n\n$sss$sss$sss\n$ttt\n" | git stripspace >actual && git diff expect actual ' test_expect_success \ 'consecutive blank lines at the end should be removed' ' printf "$ttt\n" > expect && - printf "$ttt\n\n" | git-stripspace >actual && + printf "$ttt\n\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$ttt\n\n\n\n" | git-stripspace >actual && + printf "$ttt\n\n\n\n" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt\n" > expect && - printf "$ttt$ttt\n\n\n\n" | git-stripspace >actual && + printf "$ttt$ttt\n\n\n\n" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt$ttt\n" > expect && - printf "$ttt$ttt$ttt\n\n\n\n" | git-stripspace >actual && + printf "$ttt$ttt$ttt\n\n\n\n" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt$ttt$ttt\n" > expect && - printf "$ttt$ttt$ttt$ttt\n\n\n\n" | git-stripspace >actual && + printf "$ttt$ttt$ttt$ttt\n\n\n\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$ttt\n$sss\n$sss\n$sss\n" | git-stripspace >actual && + printf "$ttt\n$sss\n$sss\n$sss\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$ttt\n\n$sss\n$sss$sss\n" | git-stripspace >actual && + printf "$ttt\n\n$sss\n$sss$sss\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$ttt\n$sss$sss\n$sss\n\n" | git-stripspace >actual && + printf "$ttt\n$sss$sss\n$sss\n\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$ttt\n$sss$sss$sss\n\n\n" | git-stripspace >actual && + printf "$ttt\n$sss$sss$sss\n\n\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$ttt\n\n$sss$sss$sss\n\n" | git-stripspace >actual && + printf "$ttt\n\n$sss$sss$sss\n\n" | git stripspace >actual && git diff expect actual && printf "$ttt\n" > expect && - printf "$ttt\n\n\n$sss$sss$sss\n" | git-stripspace >actual && + printf "$ttt\n\n\n$sss$sss$sss\n" | git stripspace >actual && git diff expect actual ' test_expect_success \ 'text without newline at end should end with newline' ' - test `printf "$ttt" | git-stripspace | wc -l` -gt 0 && - test `printf "$ttt$ttt" | git-stripspace | wc -l` -gt 0 && - test `printf "$ttt$ttt$ttt" | git-stripspace | wc -l` -gt 0 && - test `printf "$ttt$ttt$ttt$ttt" | git-stripspace | wc -l` -gt 0 + test `printf "$ttt" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$ttt" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$ttt$ttt" | git stripspace | wc -l` -gt 0 ' # text plus spaces at the end: test_expect_success \ 'text plus spaces without newline at end should end with newline' ' - test `printf "$ttt$sss" | git-stripspace | wc -l` -gt 0 && - test `printf "$ttt$ttt$sss" | git-stripspace | wc -l` -gt 0 && - test `printf "$ttt$ttt$ttt$sss" | git-stripspace | wc -l` -gt 0 - test `printf "$ttt$sss$sss" | git-stripspace | wc -l` -gt 0 && - test `printf "$ttt$ttt$sss$sss" | git-stripspace | wc -l` -gt 0 && - test `printf "$ttt$sss$sss$sss" | git-stripspace | wc -l` -gt 0 + test `printf "$ttt$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 + test `printf "$ttt$sss$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$ttt$sss$sss" | git stripspace | wc -l` -gt 0 && + test `printf "$ttt$sss$sss$sss" | git stripspace | wc -l` -gt 0 ' test_expect_failure \ 'text plus spaces without newline at end should not show spaces' ' - printf "$ttt$sss" | git-stripspace | grep -q " " || - printf "$ttt$ttt$sss" | git-stripspace | grep -q " " || - printf "$ttt$ttt$ttt$sss" | git-stripspace | grep -q " " || - printf "$ttt$sss$sss" | git-stripspace | grep -q " " || - printf "$ttt$ttt$sss$sss" | git-stripspace | grep -q " " || - printf "$ttt$sss$sss$sss" | git-stripspace | grep -q " " + printf "$ttt$sss" | git stripspace | grep -q " " || + printf "$ttt$ttt$sss" | git stripspace | grep -q " " || + printf "$ttt$ttt$ttt$sss" | git stripspace | grep -q " " || + printf "$ttt$sss$sss" | git stripspace | grep -q " " || + printf "$ttt$ttt$sss$sss" | git stripspace | grep -q " " || + printf "$ttt$sss$sss$sss" | git stripspace | grep -q " " ' test_expect_success \ 'text plus spaces without newline should show the correct lines' ' printf "$ttt\n" >expect && - printf "$ttt$sss" | git-stripspace >actual && + printf "$ttt$sss" | git stripspace >actual && git diff expect actual && printf "$ttt\n" >expect && - printf "$ttt$sss$sss" | git-stripspace >actual && + printf "$ttt$sss$sss" | git stripspace >actual && git diff expect actual && printf "$ttt\n" >expect && - printf "$ttt$sss$sss$sss" | git-stripspace >actual && + printf "$ttt$sss$sss$sss" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt\n" >expect && - printf "$ttt$ttt$sss" | git-stripspace >actual && + printf "$ttt$ttt$sss" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt\n" >expect && - printf "$ttt$ttt$sss$sss" | git-stripspace >actual && + printf "$ttt$ttt$sss$sss" | git stripspace >actual && git diff expect actual && printf "$ttt$ttt$ttt\n" >expect && - printf "$ttt$ttt$ttt$sss" | git-stripspace >actual && + printf "$ttt$ttt$ttt$sss" | git stripspace >actual && git diff expect actual ' test_expect_failure \ 'text plus spaces at end should not show spaces' ' - echo "$ttt$sss" | git-stripspace | grep -q " " || - echo "$ttt$ttt$sss" | git-stripspace | grep -q " " || - echo "$ttt$ttt$ttt$sss" | git-stripspace | grep -q " " || - echo "$ttt$sss$sss" | git-stripspace | grep -q " " || - echo "$ttt$ttt$sss$sss" | git-stripspace | grep -q " " || - echo "$ttt$sss$sss$sss" | git-stripspace | grep -q " " + echo "$ttt$sss" | git stripspace | grep -q " " || + echo "$ttt$ttt$sss" | git stripspace | grep -q " " || + echo "$ttt$ttt$ttt$sss" | git stripspace | grep -q " " || + echo "$ttt$sss$sss" | git stripspace | grep -q " " || + echo "$ttt$ttt$sss$sss" | git stripspace | grep -q " " || + echo "$ttt$sss$sss$sss" | git stripspace | grep -q " " ' test_expect_success \ 'text plus spaces at end should be cleaned and newline must remain' ' echo "$ttt" >expect && - echo "$ttt$sss" | git-stripspace >actual && + echo "$ttt$sss" | git stripspace >actual && git diff expect actual && echo "$ttt" >expect && - echo "$ttt$sss$sss" | git-stripspace >actual && + echo "$ttt$sss$sss" | git stripspace >actual && git diff expect actual && echo "$ttt" >expect && - echo "$ttt$sss$sss$sss" | git-stripspace >actual && + echo "$ttt$sss$sss$sss" | git stripspace >actual && git diff expect actual && echo "$ttt$ttt" >expect && - echo "$ttt$ttt$sss" | git-stripspace >actual && + echo "$ttt$ttt$sss" | git stripspace >actual && git diff expect actual && echo "$ttt$ttt" >expect && - echo "$ttt$ttt$sss$sss" | git-stripspace >actual && + echo "$ttt$ttt$sss$sss" | git stripspace >actual && git diff expect actual && echo "$ttt$ttt$ttt" >expect && - echo "$ttt$ttt$ttt$sss" | git-stripspace >actual && + echo "$ttt$ttt$ttt$sss" | git stripspace >actual && git diff expect actual ' @@ -310,45 +310,45 @@ test_expect_success \ 'spaces with newline at end should be replaced with empty string' ' printf "" >expect && - echo | git-stripspace >actual && + echo | git stripspace >actual && git diff expect actual && - echo "$sss" | git-stripspace >actual && + echo "$sss" | git stripspace >actual && git diff expect actual && - echo "$sss$sss" | git-stripspace >actual && + echo "$sss$sss" | git stripspace >actual && git diff expect actual && - echo "$sss$sss$sss" | git-stripspace >actual && + echo "$sss$sss$sss" | git stripspace >actual && git diff expect actual && - echo "$sss$sss$sss$sss" | git-stripspace >actual && + echo "$sss$sss$sss$sss" | git stripspace >actual && git diff expect actual ' test_expect_failure \ 'spaces without newline at end should not show spaces' ' - printf "" | git-stripspace | grep -q " " || - printf "$sss" | git-stripspace | grep -q " " || - printf "$sss$sss" | git-stripspace | grep -q " " || - printf "$sss$sss$sss" | git-stripspace | grep -q " " || - printf "$sss$sss$sss$sss" | git-stripspace | grep -q " " + printf "" | git stripspace | grep -q " " || + printf "$sss" | git stripspace | grep -q " " || + printf "$sss$sss" | git stripspace | grep -q " " || + printf "$sss$sss$sss" | git stripspace | grep -q " " || + printf "$sss$sss$sss$sss" | git stripspace | grep -q " " ' test_expect_success \ 'spaces without newline at end should be replaced with empty string' ' printf "" >expect && - printf "" | git-stripspace >actual && + printf "" | git stripspace >actual && git diff expect actual - printf "$sss$sss" | git-stripspace >actual && + printf "$sss$sss" | git stripspace >actual && git diff expect actual - printf "$sss$sss$sss" | git-stripspace >actual && + printf "$sss$sss$sss" | git stripspace >actual && git diff expect actual - printf "$sss$sss$sss$sss" | git-stripspace >actual && + printf "$sss$sss$sss$sss" | git stripspace >actual && git diff expect actual ' diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh index de4e5eb61f..37add1b504 100755 --- a/t/t1000-read-tree-m-3way.sh +++ b/t/t1000-read-tree-m-3way.sh @@ -130,28 +130,28 @@ _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" check_result () { - git-ls-files --stage | sed -e 's/ '"$_x40"' / X /' >current && + git ls-files --stage | sed -e 's/ '"$_x40"' / X /' >current && git diff expected current } # This is done on an empty work directory, which is the normal # merge person behaviour. test_expect_success \ - '3-way merge with git-read-tree -m, empty cache' \ + '3-way merge with git read-tree -m, empty cache' \ "rm -fr [NDMALTS][NDMALTSF] Z && rm .git/index && - git-read-tree -m $tree_O $tree_A $tree_B && + git read-tree -m $tree_O $tree_A $tree_B && check_result" # This starts out with the first head, which is the normal # patch submitter behaviour. test_expect_success \ - '3-way merge with git-read-tree -m, match H' \ + '3-way merge with git read-tree -m, match H' \ "rm -fr [NDMALTS][NDMALTSF] Z && rm .git/index && - git-read-tree $tree_A && - git-checkout-index -f -u -a && - git-read-tree -m $tree_O $tree_A $tree_B && + git read-tree $tree_A && + git checkout-index -f -u -a && + git read-tree -m $tree_O $tree_A $tree_B && check_result" : <<\END_OF_CASE_TABLE @@ -160,7 +160,7 @@ We have so far tested only empty index and clean-and-matching-A index case which are trivial. Make sure index requirements are also checked. -"git-read-tree -m O A B" +"git read-tree -m O A B" O A B result index requirements ------------------------------------------------------------------- @@ -214,87 +214,87 @@ test_expect_failure \ '1 - must not have an entry not in A.' \ "rm -f .git/index XX && echo XX >XX && - git-update-index --add XX && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add XX && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '2 - must match B in !O && !A && B case.' \ "rm -f .git/index NA && cp .orig-B/NA NA && - git-update-index --add NA && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add NA && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '2 - matching B alone is OK in !O && !A && B case.' \ "rm -f .git/index NA && cp .orig-B/NA NA && - git-update-index --add NA && + git update-index --add NA && echo extra >>NA && - git-read-tree -m $tree_O $tree_A $tree_B" + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '3 - must match A in !O && A && !B case.' \ "rm -f .git/index AN && cp .orig-A/AN AN && - git-update-index --add AN && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add AN && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_success \ '3 - matching A alone is OK in !O && A && !B case.' \ "rm -f .git/index AN && cp .orig-A/AN AN && - git-update-index --add AN && + git update-index --add AN && echo extra >>AN && - git-read-tree -m $tree_O $tree_A $tree_B" + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '3 (fail) - must match A in !O && A && !B case.' \ "rm -f .git/index AN && cp .orig-A/AN AN && echo extra >>AN && - git-update-index --add AN && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add AN && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '4 - must match and be up-to-date in !O && A && B && A!=B case.' \ "rm -f .git/index AA && cp .orig-A/AA AA && - git-update-index --add AA && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add AA && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_failure \ '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' \ "rm -f .git/index AA && cp .orig-A/AA AA && - git-update-index --add AA && + git update-index --add AA && echo extra >>AA && - git-read-tree -m $tree_O $tree_A $tree_B" + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '4 (fail) - must match and be up-to-date in !O && A && B && A!=B case.' \ "rm -f .git/index AA && cp .orig-A/AA AA && echo extra >>AA && - git-update-index --add AA && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add AA && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '5 - must match in !O && A && B && A==B case.' \ "rm -f .git/index LL && cp .orig-A/LL LL && - git-update-index --add LL && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add LL && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_success \ '5 - must match in !O && A && B && A==B case.' \ "rm -f .git/index LL && cp .orig-A/LL LL && - git-update-index --add LL && + git update-index --add LL && echo extra >>LL && - git-read-tree -m $tree_O $tree_A $tree_B && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_failure \ @@ -302,117 +302,117 @@ test_expect_failure \ "rm -f .git/index LL && cp .orig-A/LL LL && echo extra >>LL && - git-update-index --add LL && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add LL && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '6 - must not exist in O && !A && !B case' \ "rm -f .git/index DD && echo DD >DD - git-update-index --add DD && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add DD && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '7 - must not exist in O && !A && B && O!=B case' \ "rm -f .git/index DM && cp .orig-B/DM DM && - git-update-index --add DM && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add DM && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '8 - must not exist in O && !A && B && O==B case' \ "rm -f .git/index DN && cp .orig-B/DN DN && - git-update-index --add DN && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add DN && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '9 - must match and be up-to-date in O && A && !B && O!=A case' \ "rm -f .git/index MD && cp .orig-A/MD MD && - git-update-index --add MD && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add MD && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_failure \ '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' \ "rm -f .git/index MD && cp .orig-A/MD MD && - git-update-index --add MD && + git update-index --add MD && echo extra >>MD && - git-read-tree -m $tree_O $tree_A $tree_B" + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '9 (fail) - must match and be up-to-date in O && A && !B && O!=A case' \ "rm -f .git/index MD && cp .orig-A/MD MD && echo extra >>MD && - git-update-index --add MD && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add MD && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '10 - must match and be up-to-date in O && A && !B && O==A case' \ "rm -f .git/index ND && cp .orig-A/ND ND && - git-update-index --add ND && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add ND && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_failure \ '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' \ "rm -f .git/index ND && cp .orig-A/ND ND && - git-update-index --add ND && + git update-index --add ND && echo extra >>ND && - git-read-tree -m $tree_O $tree_A $tree_B" + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '10 (fail) - must match and be up-to-date in O && A && !B && O==A case' \ "rm -f .git/index ND && cp .orig-A/ND ND && echo extra >>ND && - git-update-index --add ND && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add ND && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '11 - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \ "rm -f .git/index MM && cp .orig-A/MM MM && - git-update-index --add MM && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add MM && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_failure \ '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \ "rm -f .git/index MM && cp .orig-A/MM MM && - git-update-index --add MM && + git update-index --add MM && echo extra >>MM && - git-read-tree -m $tree_O $tree_A $tree_B" + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '11 (fail) - must match and be up-to-date in O && A && B && O!=A && O!=B && A!=B case' \ "rm -f .git/index MM && cp .orig-A/MM MM && echo extra >>MM && - git-update-index --add MM && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add MM && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '12 - must match A in O && A && B && O!=A && A==B case' \ "rm -f .git/index SS && cp .orig-A/SS SS && - git-update-index --add SS && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add SS && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_success \ '12 - must match A in O && A && B && O!=A && A==B case' \ "rm -f .git/index SS && cp .orig-A/SS SS && - git-update-index --add SS && + git update-index --add SS && echo extra >>SS && - git-read-tree -m $tree_O $tree_A $tree_B && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_failure \ @@ -420,74 +420,74 @@ test_expect_failure \ "rm -f .git/index SS && cp .orig-A/SS SS && echo extra >>SS && - git-update-index --add SS && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add SS && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '13 - must match A in O && A && B && O!=A && O==B case' \ "rm -f .git/index MN && cp .orig-A/MN MN && - git-update-index --add MN && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add MN && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_success \ '13 - must match A in O && A && B && O!=A && O==B case' \ "rm -f .git/index MN && cp .orig-A/MN MN && - git-update-index --add MN && + git update-index --add MN && echo extra >>MN && - git-read-tree -m $tree_O $tree_A $tree_B && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_success \ '14 - must match and be up-to-date in O && A && B && O==A && O!=B case' \ "rm -f .git/index NM && cp .orig-A/NM NM && - git-update-index --add NM && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add NM && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_success \ '14 - may match B in O && A && B && O==A && O!=B case' \ "rm -f .git/index NM && cp .orig-B/NM NM && - git-update-index --add NM && + git update-index --add NM && echo extra >>NM && - git-read-tree -m $tree_O $tree_A $tree_B && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_failure \ '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' \ "rm -f .git/index NM && cp .orig-A/NM NM && - git-update-index --add NM && + git update-index --add NM && echo extra >>NM && - git-read-tree -m $tree_O $tree_A $tree_B" + git read-tree -m $tree_O $tree_A $tree_B" test_expect_failure \ '14 (fail) - must match and be up-to-date in O && A && B && O==A && O!=B case' \ "rm -f .git/index NM && cp .orig-A/NM NM && echo extra >>NM && - git-update-index --add NM && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add NM && + git read-tree -m $tree_O $tree_A $tree_B" test_expect_success \ '15 - must match A in O && A && B && O==A && O==B case' \ "rm -f .git/index NN && cp .orig-A/NN NN && - git-update-index --add NN && - git-read-tree -m $tree_O $tree_A $tree_B && + git update-index --add NN && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_success \ '15 - must match A in O && A && B && O==A && O==B case' \ "rm -f .git/index NN && cp .orig-A/NN NN && - git-update-index --add NN && + git update-index --add NN && echo extra >>NN && - git-read-tree -m $tree_O $tree_A $tree_B && + git read-tree -m $tree_O $tree_A $tree_B && check_result" test_expect_failure \ @@ -495,20 +495,20 @@ test_expect_failure \ "rm -f .git/index NN && cp .orig-A/NN NN && echo extra >>NN && - git-update-index --add NN && - git-read-tree -m $tree_O $tree_A $tree_B" + git update-index --add NN && + git read-tree -m $tree_O $tree_A $tree_B" # #16 test_expect_success \ '16 - A matches in one and B matches in another.' \ 'rm -f .git/index F16 && echo F16 >F16 && - git-update-index --add F16 && - tree0=`git-write-tree` && + git update-index --add F16 && + tree0=`git write-tree` && echo E16 >F16 && - git-update-index F16 && - tree1=`git-write-tree` && - git-read-tree -m $tree0 $tree1 $tree1 $tree0 && - git-ls-files --stage' + git update-index F16 && + tree1=`git write-tree` && + git read-tree -m $tree0 $tree1 $tree1 $tree0 && + git ls-files --stage' test_done diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 030226bbfb..b01b0037a0 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -11,7 +11,7 @@ There is the head (called H) and another commit (called M), which is simply ahead of H. The index and the work tree contains a state that is derived from H, but may also have local changes. This test checks all the combinations described in the two-tree merge "carry forward" -rules, found in . +rules, found in . In the test, these paths are used: bozbar - in H, stays in M, modified from bozbar to gnusto @@ -23,7 +23,7 @@ In the test, these paths are used: . ./test-lib.sh read_tree_twoway () { - git-read-tree -m "$1" "$2" && git-ls-files --stage + git read-tree -m "$1" "$2" && git ls-files --stage } _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' @@ -37,7 +37,7 @@ compare_change () { } check_cache_at () { - clean_if_empty=`git-diff-files -- "$1"` + clean_if_empty=`git diff-files -- "$1"` case "$clean_if_empty" in '') echo "$1: clean" ;; ?*) echo "$1: dirty" ;; @@ -68,24 +68,24 @@ test_expect_success \ cat bozbar-old >bozbar && echo rezrov >rezrov && echo yomin >yomin && - git-update-index --add nitfol bozbar rezrov && - treeH=`git-write-tree` && + git update-index --add nitfol bozbar rezrov && + treeH=`git write-tree` && echo treeH $treeH && - git-ls-tree $treeH && + git ls-tree $treeH && cat bozbar-new >bozbar && - git-update-index --add frotz bozbar --force-remove rezrov && - git-ls-files --stage >M.out && - treeM=`git-write-tree` && + git update-index --add frotz bozbar --force-remove rezrov && + git ls-files --stage >M.out && + treeM=`git write-tree` && echo treeM $treeM && - git-ls-tree $treeM && - git-diff-tree $treeH $treeM' + git ls-tree $treeM && + git diff-tree $treeH $treeM' test_expect_success \ '1, 2, 3 - no carry forward' \ 'rm -f .git/index && read_tree_twoway $treeH $treeM && - git-ls-files --stage >1-3.out && + git ls-files --stage >1-3.out && git diff M.out 1-3.out && check_cache_at bozbar dirty && check_cache_at frotz dirty && @@ -96,11 +96,11 @@ echo '+100644 X 0 yomin' >expected test_expect_success \ '4 - carry forward local addition.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && - git-update-index --add yomin && + git read-tree $treeH && + git checkout-index -u -f -q -a && + git update-index --add yomin && read_tree_twoway $treeH $treeM && - git-ls-files --stage >4.out || return 1 + git ls-files --stage >4.out || return 1 git diff M.out 4.out >4diff.out compare_change 4diff.out expected && check_cache_at yomin clean' @@ -108,13 +108,13 @@ test_expect_success \ test_expect_success \ '5 - carry forward local addition.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo yomin >yomin && - git-update-index --add yomin && + git update-index --add yomin && echo yomin yomin >yomin && read_tree_twoway $treeH $treeM && - git-ls-files --stage >5.out || return 1 + git ls-files --stage >5.out || return 1 git diff M.out 5.out >5diff.out compare_change 5diff.out expected && check_cache_at yomin dirty' @@ -122,83 +122,83 @@ test_expect_success \ test_expect_success \ '6 - local addition already has the same.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && - git-update-index --add frotz && + git read-tree $treeH && + git checkout-index -u -f -q -a && + git update-index --add frotz && read_tree_twoway $treeH $treeM && - git-ls-files --stage >6.out && + git ls-files --stage >6.out && git diff M.out 6.out && check_cache_at frotz clean' test_expect_success \ '7 - local addition already has the same.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo frotz >frotz && - git-update-index --add frotz && + git update-index --add frotz && echo frotz frotz >frotz && read_tree_twoway $treeH $treeM && - git-ls-files --stage >7.out && + git ls-files --stage >7.out && git diff M.out 7.out && check_cache_at frotz dirty' test_expect_success \ '8 - conflicting addition.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo frotz frotz >frotz && - git-update-index --add frotz && + git update-index --add frotz && if read_tree_twoway $treeH $treeM; then false; else :; fi' test_expect_success \ '9 - conflicting addition.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo frotz frotz >frotz && - git-update-index --add frotz && + git update-index --add frotz && echo frotz >frotz && if read_tree_twoway $treeH $treeM; then false; else :; fi' test_expect_success \ '10 - path removed.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo rezrov >rezrov && - git-update-index --add rezrov && + git update-index --add rezrov && read_tree_twoway $treeH $treeM && - git-ls-files --stage >10.out && + git ls-files --stage >10.out && git diff M.out 10.out' test_expect_success \ '11 - dirty path removed.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo rezrov >rezrov && - git-update-index --add rezrov && + git update-index --add rezrov && echo rezrov rezrov >rezrov && if read_tree_twoway $treeH $treeM; then false; else :; fi' test_expect_success \ '12 - unmatching local changes being removed.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo rezrov rezrov >rezrov && - git-update-index --add rezrov && + git update-index --add rezrov && if read_tree_twoway $treeH $treeM; then false; else :; fi' test_expect_success \ '13 - unmatching local changes being removed.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo rezrov rezrov >rezrov && - git-update-index --add rezrov && + git update-index --add rezrov && echo rezrov >rezrov && if read_tree_twoway $treeH $treeM; then false; else :; fi' @@ -210,12 +210,12 @@ EOF test_expect_success \ '14 - unchanged in two heads.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo nitfol nitfol >nitfol && - git-update-index --add nitfol && + git update-index --add nitfol && read_tree_twoway $treeH $treeM && - git-ls-files --stage >14.out || return 1 + git ls-files --stage >14.out || return 1 git diff M.out 14.out >14diff.out compare_change 14diff.out expected && check_cache_at nitfol clean' @@ -223,13 +223,13 @@ test_expect_success \ test_expect_success \ '15 - unchanged in two heads.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo nitfol nitfol >nitfol && - git-update-index --add nitfol && + git update-index --add nitfol && echo nitfol nitfol nitfol >nitfol && read_tree_twoway $treeH $treeM && - git-ls-files --stage >15.out || return 1 + git ls-files --stage >15.out || return 1 git diff M.out 15.out >15diff.out compare_change 15diff.out expected && check_cache_at nitfol dirty' @@ -237,66 +237,66 @@ test_expect_success \ test_expect_success \ '16 - conflicting local change.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo bozbar bozbar >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && if read_tree_twoway $treeH $treeM; then false; else :; fi' test_expect_success \ '17 - conflicting local change.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && echo bozbar bozbar >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && echo bozbar bozbar bozbar >bozbar && if read_tree_twoway $treeH $treeM; then false; else :; fi' test_expect_success \ '18 - local change already having a good result.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && cat bozbar-new >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && read_tree_twoway $treeH $treeM && - git-ls-files --stage >18.out && + git ls-files --stage >18.out && git diff M.out 18.out && check_cache_at bozbar clean' test_expect_success \ '19 - local change already having a good result, further modified.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && cat bozbar-new >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && echo gnusto gnusto >bozbar && read_tree_twoway $treeH $treeM && - git-ls-files --stage >19.out && + git ls-files --stage >19.out && git diff M.out 19.out && check_cache_at bozbar dirty' test_expect_success \ '20 - no local change, use new tree.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && cat bozbar-old >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && read_tree_twoway $treeH $treeM && - git-ls-files --stage >20.out && + git ls-files --stage >20.out && git diff M.out 20.out && check_cache_at bozbar dirty' test_expect_success \ '21 - no local change, dirty cache.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && cat bozbar-old >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && echo gnusto gnusto >bozbar && if read_tree_twoway $treeH $treeM; then false; else :; fi' @@ -304,10 +304,10 @@ test_expect_success \ test_expect_success \ '22 - local change cache updated.' \ 'rm -f .git/index && - git-read-tree $treeH && - git-checkout-index -u -f -q -a && + git read-tree $treeH && + git checkout-index -u -f -q -a && sed -e "s/such as/SUCH AS/" bozbar-old >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && if read_tree_twoway $treeH $treeM; then false; else :; fi' # Also make sure we did not break DF vs DF/DF case. @@ -315,28 +315,28 @@ test_expect_success \ 'DF vs DF/DF case setup.' \ 'rm -f .git/index && echo DF >DF && - git-update-index --add DF && - treeDF=`git-write-tree` && + git update-index --add DF && + treeDF=`git write-tree` && echo treeDF $treeDF && - git-ls-tree $treeDF && + git ls-tree $treeDF && rm -f DF && mkdir DF && echo DF/DF >DF/DF && - git-update-index --add --remove DF DF/DF && - treeDFDF=`git-write-tree` && + git update-index --add --remove DF DF/DF && + treeDFDF=`git write-tree` && echo treeDFDF $treeDFDF && - git-ls-tree $treeDFDF && - git-ls-files --stage >DFDF.out' + git ls-tree $treeDFDF && + git ls-files --stage >DFDF.out' test_expect_success \ 'DF vs DF/DF case test.' \ 'rm -f .git/index && rm -fr DF && echo DF >DF && - git-update-index --add DF && + git update-index --add DF && read_tree_twoway $treeDF $treeDFDF && - git-ls-files --stage >DFDFcheck.out && + git ls-files --stage >DFDFcheck.out && git diff DFDF.out DFDFcheck.out && check_cache_at DF/DF dirty && :' diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh index 87fe993f59..42e5cf8181 100755 --- a/t/t1002-read-tree-m-u-2way.sh +++ b/t/t1002-read-tree-m-u-2way.sh @@ -20,7 +20,7 @@ compare_change () { } check_cache_at () { - clean_if_empty=`git-diff-files -- "$1"` + clean_if_empty=`git diff-files -- "$1"` case "$clean_if_empty" in '') echo "$1: clean" ;; ?*) echo "$1: dirty" ;; @@ -39,26 +39,26 @@ test_expect_success \ echo nitfol >nitfol && echo bozbar >bozbar && echo rezrov >rezrov && - git-update-index --add nitfol bozbar rezrov && - treeH=`git-write-tree` && + git update-index --add nitfol bozbar rezrov && + treeH=`git write-tree` && echo treeH $treeH && - git-ls-tree $treeH && + git ls-tree $treeH && echo gnusto >bozbar && - git-update-index --add frotz bozbar --force-remove rezrov && - git-ls-files --stage >M.out && - treeM=`git-write-tree` && + git update-index --add frotz bozbar --force-remove rezrov && + git ls-files --stage >M.out && + treeM=`git write-tree` && echo treeM $treeM && - git-ls-tree $treeM && + git ls-tree $treeM && sum bozbar frotz nitfol >M.sum && - git-diff-tree $treeH $treeM' + git diff-tree $treeH $treeM' test_expect_success \ '1, 2, 3 - no carry forward' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >1-3.out && + git read-tree --reset -u $treeH && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >1-3.out && cmp M.out 1-3.out && sum bozbar frotz nitfol >actual3.sum && cmp M.sum actual3.sum && @@ -69,12 +69,12 @@ test_expect_success \ test_expect_success \ '4 - carry forward local addition.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo "+100644 X 0 yomin" >expected && echo yomin >yomin && - git-update-index --add yomin && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >4.out || return 1 + git update-index --add yomin && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >4.out || return 1 diff -U0 M.out 4.out >4diff.out compare_change 4diff.out expected && check_cache_at yomin clean && @@ -87,13 +87,13 @@ test_expect_success \ test_expect_success \ '5 - carry forward local addition.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && - git-read-tree -m -u $treeH && + git read-tree --reset -u $treeH && + git read-tree -m -u $treeH && echo yomin >yomin && - git-update-index --add yomin && + git update-index --add yomin && echo yomin yomin >yomin && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >5.out || return 1 + git read-tree -m -u $treeH $treeM && + git ls-files --stage >5.out || return 1 diff -U0 M.out 5.out >5diff.out compare_change 5diff.out expected && check_cache_at yomin dirty && @@ -107,11 +107,11 @@ test_expect_success \ test_expect_success \ '6 - local addition already has the same.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo frotz >frotz && - git-update-index --add frotz && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >6.out && + git update-index --add frotz && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >6.out && diff -U0 M.out 6.out && check_cache_at frotz clean && sum bozbar frotz nitfol >actual3.sum && @@ -123,12 +123,12 @@ test_expect_success \ test_expect_success \ '7 - local addition already has the same.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo frotz >frotz && - git-update-index --add frotz && + git update-index --add frotz && echo frotz frotz >frotz && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >7.out && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >7.out && diff -U0 M.out 7.out && check_cache_at frotz dirty && sum bozbar frotz nitfol >actual7.sum && @@ -141,28 +141,28 @@ test_expect_success \ test_expect_success \ '8 - conflicting addition.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo frotz frotz >frotz && - git-update-index --add frotz && - if git-read-tree -m -u $treeH $treeM; then false; else :; fi' + git update-index --add frotz && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' test_expect_success \ '9 - conflicting addition.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo frotz frotz >frotz && - git-update-index --add frotz && + git update-index --add frotz && echo frotz >frotz && - if git-read-tree -m -u $treeH $treeM; then false; else :; fi' + if git read-tree -m -u $treeH $treeM; then false; else :; fi' test_expect_success \ '10 - path removed.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo rezrov >rezrov && - git-update-index --add rezrov && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >10.out && + git update-index --add rezrov && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >10.out && cmp M.out 10.out && sum bozbar frotz nitfol >actual10.sum && cmp M.sum actual10.sum' @@ -170,28 +170,28 @@ test_expect_success \ test_expect_success \ '11 - dirty path removed.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo rezrov >rezrov && - git-update-index --add rezrov && + git update-index --add rezrov && echo rezrov rezrov >rezrov && - if git-read-tree -m -u $treeH $treeM; then false; else :; fi' + if git read-tree -m -u $treeH $treeM; then false; else :; fi' test_expect_success \ '12 - unmatching local changes being removed.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo rezrov rezrov >rezrov && - git-update-index --add rezrov && - if git-read-tree -m -u $treeH $treeM; then false; else :; fi' + git update-index --add rezrov && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' test_expect_success \ '13 - unmatching local changes being removed.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo rezrov rezrov >rezrov && - git-update-index --add rezrov && + git update-index --add rezrov && echo rezrov >rezrov && - if git-read-tree -m -u $treeH $treeM; then false; else :; fi' + if git read-tree -m -u $treeH $treeM; then false; else :; fi' cat >expected <nitfol && - git-update-index --add nitfol && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >14.out || return 1 + git update-index --add nitfol && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >14.out || return 1 diff -U0 M.out 14.out >14diff.out compare_change 14diff.out expected && sum bozbar frotz >actual14.sum && @@ -221,12 +221,12 @@ test_expect_success \ test_expect_success \ '15 - unchanged in two heads.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo nitfol nitfol >nitfol && - git-update-index --add nitfol && + git update-index --add nitfol && echo nitfol nitfol nitfol >nitfol && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >15.out || return 1 + git read-tree -m -u $treeH $treeM && + git ls-files --stage >15.out || return 1 diff -U0 M.out 15.out >15diff.out compare_change 15diff.out expected && check_cache_at nitfol dirty && @@ -242,28 +242,28 @@ test_expect_success \ test_expect_success \ '16 - conflicting local change.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo bozbar bozbar >bozbar && - git-update-index --add bozbar && - if git-read-tree -m -u $treeH $treeM; then false; else :; fi' + git update-index --add bozbar && + if git read-tree -m -u $treeH $treeM; then false; else :; fi' test_expect_success \ '17 - conflicting local change.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo bozbar bozbar >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && echo bozbar bozbar bozbar >bozbar && - if git-read-tree -m -u $treeH $treeM; then false; else :; fi' + if git read-tree -m -u $treeH $treeM; then false; else :; fi' test_expect_success \ '18 - local change already having a good result.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo gnusto >bozbar && - git-update-index --add bozbar && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >18.out && + git update-index --add bozbar && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >18.out && diff -U0 M.out 18.out && check_cache_at bozbar clean && sum bozbar frotz nitfol >actual18.sum && @@ -272,12 +272,12 @@ test_expect_success \ test_expect_success \ '19 - local change already having a good result, further modified.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo gnusto >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && echo gnusto gnusto >bozbar && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >19.out && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >19.out && diff -U0 M.out 19.out && check_cache_at bozbar dirty && sum frotz nitfol >actual19.sum && @@ -292,11 +292,11 @@ test_expect_success \ test_expect_success \ '20 - no local change, use new tree.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo bozbar >bozbar && - git-update-index --add bozbar && - git-read-tree -m -u $treeH $treeM && - git-ls-files --stage >20.out && + git update-index --add bozbar && + git read-tree -m -u $treeH $treeM && + git ls-files --stage >20.out && diff -U0 M.out 20.out && check_cache_at bozbar clean && sum bozbar frotz nitfol >actual20.sum && @@ -305,39 +305,39 @@ test_expect_success \ test_expect_success \ '21 - no local change, dirty cache.' \ 'rm -f .git/index nitfol bozbar rezrov frotz && - git-read-tree --reset -u $treeH && + git read-tree --reset -u $treeH && echo bozbar >bozbar && - git-update-index --add bozbar && + git update-index --add bozbar && echo gnusto gnusto >bozbar && - if git-read-tree -m -u $treeH $treeM; then false; else :; fi' + if git read-tree -m -u $treeH $treeM; then false; else :; fi' # Also make sure we did not break DF vs DF/DF case. test_expect_success \ 'DF vs DF/DF case setup.' \ 'rm -f .git/index echo DF >DF && - git-update-index --add DF && - treeDF=`git-write-tree` && + git update-index --add DF && + treeDF=`git write-tree` && echo treeDF $treeDF && - git-ls-tree $treeDF && + git ls-tree $treeDF && rm -f DF && mkdir DF && echo DF/DF >DF/DF && - git-update-index --add --remove DF DF/DF && - treeDFDF=`git-write-tree` && + git update-index --add --remove DF DF/DF && + treeDFDF=`git write-tree` && echo treeDFDF $treeDFDF && - git-ls-tree $treeDFDF && - git-ls-files --stage >DFDF.out' + git ls-tree $treeDFDF && + git ls-files --stage >DFDF.out' test_expect_success \ 'DF vs DF/DF case test.' \ 'rm -f .git/index && rm -fr DF && echo DF >DF && - git-update-index --add DF && - git-read-tree -m -u $treeDF $treeDFDF && - git-ls-files --stage >DFDFcheck.out && + git update-index --add DF && + git read-tree -m -u $treeDF $treeDFDF && + git ls-files --stage >DFDFcheck.out && diff -U0 DFDF.out DFDFcheck.out && check_cache_at DF/DF clean' diff --git a/t/t1003-read-tree-prefix.sh b/t/t1003-read-tree-prefix.sh index 48ab117d75..8c6d67edda 100755 --- a/t/t1003-read-tree-prefix.sh +++ b/t/t1003-read-tree-prefix.sh @@ -3,15 +3,15 @@ # Copyright (c) 2006 Junio C Hamano # -test_description='git-read-tree --prefix test. +test_description='git read-tree --prefix test. ' . ./test-lib.sh test_expect_success setup ' echo hello >one && - git-update-index --add one && - tree=`git-write-tree` && + git update-index --add one && + tree=`git write-tree` && echo tree is $tree ' @@ -19,8 +19,8 @@ echo 'one two/one' >expect test_expect_success 'read-tree --prefix' ' - git-read-tree --prefix=two/ $tree && - git-ls-files >actual && + git read-tree --prefix=two/ $tree && + git ls-files >actual && cmp expect actual ' diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh index c11420a8b6..d609a551ae 100755 --- a/t/t1004-read-tree-m-u-wf.sh +++ b/t/t1004-read-tree-m-u-wf.sh @@ -84,7 +84,7 @@ test_expect_success 'three-way not complaining on an untracked path in both' ' echo >file2 file two is untracked on the master side && echo >subdir/file2 file two is untracked on the master side && - git-read-tree -m -u branch-point master side + git read-tree -m -u branch-point master side ' test_expect_success 'three-way not clobbering a working tree file' ' diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh index 1e8f9e59df..b9cef3422c 100755 --- a/t/t1020-subdirectory.sh +++ b/t/t1020-subdirectory.sh @@ -22,19 +22,19 @@ LF=' test_expect_success 'update-index and ls-files' ' cd $HERE && - git-update-index --add one && - case "`git-ls-files`" in + git update-index --add one && + case "`git ls-files`" in one) echo ok one ;; *) echo bad one; exit 1 ;; esac && cd dir && - git-update-index --add two && - case "`git-ls-files`" in + git update-index --add two && + case "`git ls-files`" in two) echo ok two ;; *) echo bad two; exit 1 ;; esac && cd .. && - case "`git-ls-files`" in + case "`git ls-files`" in dir/two"$LF"one) echo ok both ;; *) echo bad; exit 1 ;; esac @@ -42,13 +42,13 @@ test_expect_success 'update-index and ls-files' ' test_expect_success 'cat-file' ' cd $HERE && - two=`git-ls-files -s dir/two` && + two=`git ls-files -s dir/two` && two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` && echo "$two" && - git-cat-file -p "$two" >actual && + git cat-file -p "$two" >actual && cmp dir/two actual && cd dir && - git-cat-file -p "$two" >actual && + git cat-file -p "$two" >actual && cmp two actual ' rm -f actual dir/actual @@ -57,17 +57,17 @@ test_expect_success 'diff-files' ' cd $HERE && echo a >>one && echo d >>dir/two && - case "`git-diff-files --name-only`" in + case "`git diff-files --name-only`" in dir/two"$LF"one) echo ok top ;; *) echo bad top; exit 1 ;; esac && # diff should not omit leading paths cd dir && - case "`git-diff-files --name-only`" in + case "`git diff-files --name-only`" in dir/two"$LF"one) echo ok subdir ;; *) echo bad subdir; exit 1 ;; esac && - case "`git-diff-files --name-only .`" in + case "`git diff-files --name-only .`" in dir/two) echo ok subdir limited ;; *) echo bad subdir limited; exit 1 ;; esac @@ -75,33 +75,33 @@ test_expect_success 'diff-files' ' test_expect_success 'write-tree' ' cd $HERE && - top=`git-write-tree` && + top=`git write-tree` && echo $top && cd dir && - sub=`git-write-tree` && + sub=`git write-tree` && echo $sub && test "z$top" = "z$sub" ' test_expect_success 'checkout-index' ' cd $HERE && - git-checkout-index -f -u one && + git checkout-index -f -u one && cmp one original.one && cd dir && - git-checkout-index -f -u two && + git checkout-index -f -u two && cmp two ../original.two ' test_expect_success 'read-tree' ' cd $HERE && rm -f one dir/two && - tree=`git-write-tree` && - git-read-tree --reset -u "$tree" && + tree=`git write-tree` && + git read-tree --reset -u "$tree" && cmp one original.one && cmp dir/two original.two && cd dir && rm -f two && - git-read-tree --reset -u "$tree" && + git read-tree --reset -u "$tree" && cmp two ../original.two && cmp ../one ../original.one ' diff --git a/t/t1100-commit-tree-options.sh b/t/t1100-commit-tree-options.sh index 19a0ed4d20..7f7fc36734 100755 --- a/t/t1100-commit-tree-options.sh +++ b/t/t1100-commit-tree-options.sh @@ -3,9 +3,9 @@ # Copyright (C) 2005 Rene Scharfe # -test_description='git-commit-tree options test +test_description='git commit-tree options test -This test checks that git-commit-tree can create a specific commit +This test checks that git commit-tree can create a specific commit object by defining all environment variables that it understands. ' @@ -21,7 +21,7 @@ EOF test_expect_success \ 'test preparation: write empty tree' \ - 'git-write-tree >treeid' + 'git write-tree >treeid' test_expect_success \ 'construct commit' \ @@ -32,11 +32,11 @@ test_expect_success \ GIT_COMMITTER_NAME="Committer Name" \ GIT_COMMITTER_EMAIL="committer@email" \ GIT_COMMITTER_DATE="2005-05-26 23:30" \ - TZ=GMT git-commit-tree `cat treeid` >commitid 2>/dev/null' + TZ=GMT git commit-tree `cat treeid` >commitid 2>/dev/null' test_expect_success \ 'read commit' \ - 'git-cat-file commit `cat commitid` >commit' + 'git cat-file commit `cat commitid` >commit' test_expect_success \ 'compare commit' \ diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh index d3f8358485..991d3c5e9c 100755 --- a/t/t1200-tutorial.sh +++ b/t/t1200-tutorial.sh @@ -10,11 +10,11 @@ test_description='A simple turial in the form of a test case' echo "Hello World" > hello echo "Silly example" > example -git-update-index --add hello example +git update-index --add hello example -test_expect_success 'blob' "test blob = \"$(git-cat-file -t 557db03)\"" +test_expect_success 'blob' "test blob = \"$(git cat-file -t 557db03)\"" -test_expect_success 'blob 557db03' "test \"Hello World\" = \"$(git-cat-file blob 557db03)\"" +test_expect_success 'blob 557db03' "test \"Hello World\" = \"$(git cat-file blob 557db03)\"" echo "It's a new day for git" >>hello cat > diff.expect << EOF @@ -26,25 +26,25 @@ index 557db03..263414f 100644 Hello World +It's a new day for git EOF -git-diff-files -p > diff.output -test_expect_success 'git-diff-files -p' 'cmp diff.expect diff.output' +git diff-files -p > diff.output +test_expect_success 'git diff-files -p' 'cmp diff.expect diff.output' git diff > diff.output test_expect_success 'git diff' 'cmp diff.expect diff.output' -tree=$(git-write-tree 2>/dev/null) +tree=$(git write-tree 2>/dev/null) test_expect_success 'tree' "test 8988da15d077d4829fc51d8544c097def6644dbb = $tree" -output="$(echo "Initial commit" | git-commit-tree $(git-write-tree) 2>&1 > .git/refs/heads/master)" +output="$(echo "Initial commit" | git commit-tree $(git write-tree) 2>&1 > .git/refs/heads/master)" -git-diff-index -p HEAD > diff.output -test_expect_success 'git-diff-index -p HEAD' 'cmp diff.expect diff.output' +git diff-index -p HEAD > diff.output +test_expect_success 'git diff-index -p HEAD' 'cmp diff.expect diff.output' git diff HEAD > diff.output test_expect_success 'git diff HEAD' 'cmp diff.expect diff.output' #rm hello -#test_expect_success 'git-read-tree --reset HEAD' "git-read-tree --reset HEAD ; test \"hello: needs update\" = \"$(git-update-index --refresh)\"" +#test_expect_success 'git read-tree --reset HEAD' "git read-tree --reset HEAD ; test \"hello: needs update\" = \"$(git update-index --refresh)\"" cat > whatchanged.expect << EOF commit VARIABLE @@ -69,11 +69,11 @@ index 0000000..557db03 +Hello World EOF -git-whatchanged -p --root | \ +git whatchanged -p --root | \ sed -e "1s/^\(.\{7\}\).\{40\}/\1VARIABLE/" \ -e "2,3s/^\(.\{8\}\).*$/\1VARIABLE/" \ > whatchanged.output -test_expect_success 'git-whatchanged -p --root' 'cmp whatchanged.expect whatchanged.output' +test_expect_success 'git whatchanged -p --root' 'cmp whatchanged.expect whatchanged.output' git tag my-first-tag test_expect_success 'git tag my-first-tag' 'cmp .git/refs/heads/master .git/refs/tags/my-first-tag' diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index a2c11c4639..1c43cc333d 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -3,13 +3,13 @@ # Copyright (c) 2005 Johannes Schindelin # -test_description='Test git-config in different settings' +test_description='Test git config in different settings' . ./test-lib.sh test -f .git/config && rm .git/config -git-config core.penguin "little blue" +git config core.penguin "little blue" cat > expect << EOF [core] @@ -18,7 +18,7 @@ EOF test_expect_success 'initial' 'cmp .git/config expect' -git-config Core.Movie BadPhysics +git config Core.Movie BadPhysics cat > expect << EOF [core] @@ -28,7 +28,7 @@ EOF test_expect_success 'mixed case' 'cmp .git/config expect' -git-config Cores.WhatEver Second +git config Cores.WhatEver Second cat > expect << EOF [core] @@ -40,7 +40,7 @@ EOF test_expect_success 'similar section' 'cmp .git/config expect' -git-config CORE.UPPERCASE true +git config CORE.UPPERCASE true cat > expect << EOF [core] @@ -54,10 +54,10 @@ EOF test_expect_success 'similar section' 'cmp .git/config expect' test_expect_success 'replace with non-match' \ - 'git-config core.penguin kingpin !blue' + 'git config core.penguin kingpin !blue' test_expect_success 'replace with non-match (actually matching)' \ - 'git-config core.penguin "very blue" !kingpin' + 'git config core.penguin "very blue" !kingpin' cat > expect << EOF [core] @@ -86,7 +86,7 @@ EOF cp .git/config .git/config2 test_expect_success 'multiple unset' \ - 'git-config --unset-all beta.haha' + 'git config --unset-all beta.haha' cat > expect << EOF [beta] ; silly comment # another comment @@ -102,7 +102,7 @@ test_expect_success 'multiple unset is correct' 'cmp .git/config expect' mv .git/config2 .git/config test_expect_success '--replace-all' \ - 'git-config --replace-all beta.haha gamma' + 'git config --replace-all beta.haha gamma' cat > expect << EOF [beta] ; silly comment # another comment @@ -116,7 +116,7 @@ EOF test_expect_success 'all replaced' 'cmp .git/config expect' -git-config beta.haha alpha +git config beta.haha alpha cat > expect << EOF [beta] ; silly comment # another comment @@ -130,7 +130,7 @@ EOF test_expect_success 'really mean test' 'cmp .git/config expect' -git-config nextsection.nonewline wow +git config nextsection.nonewline wow cat > expect << EOF [beta] ; silly comment # another comment @@ -145,8 +145,8 @@ EOF test_expect_success 'really really mean test' 'cmp .git/config expect' -test_expect_success 'get value' 'test alpha = $(git-config beta.haha)' -git-config --unset beta.haha +test_expect_success 'get value' 'test alpha = $(git config beta.haha)' +git config --unset beta.haha cat > expect << EOF [beta] ; silly comment # another comment @@ -160,7 +160,7 @@ EOF test_expect_success 'unset' 'cmp .git/config expect' -git-config nextsection.NoNewLine "wow2 for me" "for me$" +git config nextsection.NoNewLine "wow2 for me" "for me$" cat > expect << EOF [beta] ; silly comment # another comment @@ -176,18 +176,18 @@ EOF test_expect_success 'multivar' 'cmp .git/config expect' test_expect_success 'non-match' \ - 'git-config --get nextsection.nonewline !for' + 'git config --get nextsection.nonewline !for' test_expect_success 'non-match value' \ - 'test wow = $(git-config --get nextsection.nonewline !for)' + 'test wow = $(git config --get nextsection.nonewline !for)' test_expect_failure 'ambiguous get' \ - 'git-config --get nextsection.nonewline' + 'git config --get nextsection.nonewline' test_expect_success 'get multivar' \ - 'git-config --get-all nextsection.nonewline' + 'git config --get-all nextsection.nonewline' -git-config nextsection.nonewline "wow3" "wow$" +git config nextsection.nonewline "wow3" "wow$" cat > expect << EOF [beta] ; silly comment # another comment @@ -202,15 +202,15 @@ EOF test_expect_success 'multivar replace' 'cmp .git/config expect' -test_expect_failure 'ambiguous value' 'git-config nextsection.nonewline' +test_expect_failure 'ambiguous value' 'git config nextsection.nonewline' test_expect_failure 'ambiguous unset' \ - 'git-config --unset nextsection.nonewline' + 'git config --unset nextsection.nonewline' test_expect_failure 'invalid unset' \ - 'git-config --unset somesection.nonewline' + 'git config --unset somesection.nonewline' -git-config --unset nextsection.nonewline "wow3$" +git config --unset nextsection.nonewline "wow3$" cat > expect << EOF [beta] ; silly comment # another comment @@ -224,12 +224,12 @@ EOF test_expect_success 'multivar unset' 'cmp .git/config expect' -test_expect_failure 'invalid key' 'git-config inval.2key blabla' +test_expect_failure 'invalid key' 'git config inval.2key blabla' -test_expect_success 'correct key' 'git-config 123456.a123 987' +test_expect_success 'correct key' 'git config 123456.a123 987' test_expect_success 'hierarchical section' \ - 'git-config Version.1.2.3eX.Alpha beta' + 'git config Version.1.2.3eX.Alpha beta' cat > expect << EOF [beta] ; silly comment # another comment @@ -255,7 +255,7 @@ version.1.2.3eX.alpha=beta EOF test_expect_success 'working --list' \ - 'git-config --list > output && cmp output expect' + 'git config --list > output && cmp output expect' cat > expect << EOF beta.noindent sillyValue @@ -263,9 +263,9 @@ nextsection.nonewline wow2 for me EOF test_expect_success '--get-regexp' \ - 'git-config --get-regexp in > output && cmp output expect' + 'git config --get-regexp in > output && cmp output expect' -git-config --add nextsection.nonewline "wow4 for you" +git config --add nextsection.nonewline "wow4 for you" cat > expect << EOF wow2 for me @@ -273,7 +273,7 @@ wow4 for you EOF test_expect_success '--add' \ - 'git-config --get-all nextsection.nonewline > output && cmp output expect' + 'git config --get-all nextsection.nonewline > output && cmp output expect' cat > .git/config << EOF [novalue] @@ -281,15 +281,15 @@ cat > .git/config << EOF EOF test_expect_success 'get variable with no value' \ - 'git-config --get novalue.variable ^$' + 'git config --get novalue.variable ^$' echo novalue.variable > expect test_expect_success 'get-regexp variable with no value' \ - 'git-config --get-regexp novalue > output && + 'git config --get-regexp novalue > output && cmp output expect' -git-config > output 2>&1 +git config > output 2>&1 test_expect_success 'no arguments, but no crash' \ "test $? = 129 && grep usage output" @@ -299,7 +299,7 @@ cat > .git/config << EOF c = d EOF -git-config a.x y +git config a.x y cat > expect << EOF [a.b] @@ -310,8 +310,8 @@ EOF test_expect_success 'new section is partial match of another' 'cmp .git/config expect' -git-config b.x y -git-config a.b c +git config b.x y +git config a.b c cat > expect << EOF [a.b] @@ -334,11 +334,11 @@ cat > expect << EOF ein.bahn=strasse EOF -GIT_CONFIG=other-config git-config -l > output +GIT_CONFIG=other-config git config -l > output test_expect_success 'alternative GIT_CONFIG' 'cmp output expect' -GIT_CONFIG=other-config git-config anwohner.park ausweis +GIT_CONFIG=other-config git config anwohner.park ausweis cat > expect << EOF [ein] @@ -361,7 +361,7 @@ weird EOF test_expect_success "rename section" \ - "git-config --rename-section branch.eins branch.zwei" + "git config --rename-section branch.eins branch.zwei" cat > expect << EOF # Hallo @@ -377,12 +377,12 @@ EOF test_expect_success "rename succeeded" "git diff expect .git/config" test_expect_failure "rename non-existing section" \ - 'git-config --rename-section branch."world domination" branch.drei' + 'git config --rename-section branch."world domination" branch.drei' test_expect_success "rename succeeded" "git diff expect .git/config" test_expect_success "rename another section" \ - 'git-config --rename-section branch."1 234 blabl/a" branch.drei' + 'git config --rename-section branch."1 234 blabl/a" branch.drei' cat > expect << EOF # Hallo @@ -425,20 +425,20 @@ EOF test_expect_success 'section ending' ' - git-config gitcvs.enabled true && - git-config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && - git-config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite && + git config gitcvs.enabled true && + git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && + git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite && cmp .git/config expect ' test_expect_success numbers ' - git-config kilo.gram 1k && - git-config mega.ton 1m && - k=$(git-config --int --get kilo.gram) && + git config kilo.gram 1k && + git config mega.ton 1m && + k=$(git config --int --get kilo.gram) && test z1024 = "z$k" && - m=$(git-config --int --get mega.ton) && + m=$(git config --int --get mega.ton) && test z1048576 = "z$m" ' @@ -455,30 +455,30 @@ EOF test_expect_success bool ' - git-config bool.true1 01 && - git-config bool.true2 -1 && - git-config bool.true3 YeS && - git-config bool.true4 true && - git-config bool.false1 000 && - git-config bool.false2 "" && - git-config bool.false3 nO && - git-config bool.false4 FALSE && + git config bool.true1 01 && + git config bool.true2 -1 && + git config bool.true3 YeS && + git config bool.true4 true && + git config bool.false1 000 && + git config bool.false2 "" && + git config bool.false3 nO && + git config bool.false4 FALSE && rm -f result && for i in 1 2 3 4 do - git-config --bool --get bool.true$i >>result - git-config --bool --get bool.false$i >>result + git config --bool --get bool.true$i >>result + git config --bool --get bool.false$i >>result done && cmp expect result' test_expect_failure 'invalid bool (--get)' ' - git-config bool.nobool foobar && - git-config --bool --get bool.nobool' + git config bool.nobool foobar && + git config --bool --get bool.nobool' test_expect_failure 'invalid bool (set)' ' - git-config --bool bool.nobool foobar' + git config --bool bool.nobool foobar' rm .git/config @@ -496,14 +496,14 @@ EOF test_expect_success 'set --bool' ' - git-config --bool bool.true1 01 && - git-config --bool bool.true2 -1 && - git-config --bool bool.true3 YeS && - git-config --bool bool.true4 true && - git-config --bool bool.false1 000 && - git-config --bool bool.false2 "" && - git-config --bool bool.false3 nO && - git-config --bool bool.false4 FALSE && + git config --bool bool.true1 01 && + git config --bool bool.true2 -1 && + git config --bool bool.true3 YeS && + git config --bool bool.true4 true && + git config --bool bool.false1 000 && + git config --bool bool.false2 "" && + git config --bool bool.false3 nO && + git config --bool bool.false4 FALSE && cmp expect .git/config' rm .git/config @@ -517,17 +517,17 @@ EOF test_expect_success 'set --int' ' - git-config --int int.val1 01 && - git-config --int int.val2 -1 && - git-config --int int.val3 5m && + git config --int int.val1 01 && + git config --int int.val2 -1 && + git config --int int.val3 5m && cmp expect .git/config' rm .git/config -git-config quote.leading " test" -git-config quote.ending "test " -git-config quote.semicolon "test;test" -git-config quote.hash "test#test" +git config quote.leading " test" +git config quote.ending "test " +git config quote.semicolon "test;test" +git config quote.hash "test#test" cat > expect << EOF [quote] diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index d0aba2c2ae..c4c0dfaab1 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Shawn Pearce # -test_description='Test git-update-ref and basic ref logging' +test_description='Test git update-ref and basic ref logging' . ./test-lib.sh Z=0000000000000000000000000000000000000000 @@ -19,34 +19,34 @@ n=$n_dir/fixes test_expect_success \ "create $m" \ - "git-update-ref $m $A && + "git update-ref $m $A && test $A"' = $(cat .git/'"$m"')' test_expect_success \ "create $m" \ - "git-update-ref $m $B $A && + "git update-ref $m $B $A && test $B"' = $(cat .git/'"$m"')' rm -f .git/$m test_expect_success \ "fail to create $n" \ "touch .git/$n_dir - git-update-ref $n $A >out 2>err"' + git update-ref $n $A >out 2>err"' test $? != 0' rm -f .git/$n_dir out err test_expect_success \ "create $m (by HEAD)" \ - "git-update-ref HEAD $A && + "git update-ref HEAD $A && test $A"' = $(cat .git/'"$m"')' test_expect_success \ "create $m (by HEAD)" \ - "git-update-ref HEAD $B $A && + "git update-ref HEAD $B $A && test $B"' = $(cat .git/'"$m"')' rm -f .git/$m test_expect_failure \ '(not) create HEAD with old sha1' \ - "git-update-ref HEAD $A $B" + "git update-ref HEAD $A $B" test_expect_failure \ "(not) prior created .git/$m" \ "test -f .git/$m" @@ -54,10 +54,10 @@ rm -f .git/$m test_expect_success \ "create HEAD" \ - "git-update-ref HEAD $A" + "git update-ref HEAD $A" test_expect_failure \ '(not) change HEAD with wrong SHA1' \ - "git-update-ref HEAD $B $Z" + "git update-ref HEAD $B $Z" test_expect_failure \ "(not) changed .git/$m" \ "test $B"' = $(cat .git/'"$m"')' @@ -68,17 +68,17 @@ rm -f .git/$m test_expect_success \ "create $m (logged by touch)" \ 'GIT_COMMITTER_DATE="2005-05-26 23:30" \ - git-update-ref HEAD '"$A"' -m "Initial Creation" && + git update-ref HEAD '"$A"' -m "Initial Creation" && test '"$A"' = $(cat .git/'"$m"')' test_expect_success \ "update $m (logged by touch)" \ 'GIT_COMMITTER_DATE="2005-05-26 23:31" \ - git-update-ref HEAD'" $B $A "'-m "Switch" && + git update-ref HEAD'" $B $A "'-m "Switch" && test '"$B"' = $(cat .git/'"$m"')' test_expect_success \ "set $m (logged by touch)" \ 'GIT_COMMITTER_DATE="2005-05-26 23:41" \ - git-update-ref HEAD'" $A && + git update-ref HEAD'" $A && test $A"' = $(cat .git/'"$m"')' cat >expect <expect <.git/logs/$m < 1117150320 -0500 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500 @@ -136,49 +136,49 @@ ld="Thu, 26 May 2005 18:43:00 -0500" test_expect_success \ 'Query "master@{May 25 2005}" (before history)' \ 'rm -f o e - git-rev-parse --verify "master@{May 25 2005}" >o 2>e && + git rev-parse --verify "master@{May 25 2005}" >o 2>e && test '"$C"' = $(cat o) && test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"' test_expect_success \ "Query master@{2005-05-25} (before history)" \ 'rm -f o e - git-rev-parse --verify master@{2005-05-25} >o 2>e && + git rev-parse --verify master@{2005-05-25} >o 2>e && test '"$C"' = $(cat o) && echo test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"' test_expect_success \ 'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \ 'rm -f o e - git-rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e && + git rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e && test '"$C"' = $(cat o) && test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"' test_expect_success \ 'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \ 'rm -f o e - git-rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e && + git rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e && test '"$A"' = $(cat o) && test "" = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' \ 'rm -f o e - git-rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e && + git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e && test '"$B"' = $(cat o) && test "warning: Log .git/logs/'"$m has gap after $gd"'." = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-26 23:38:00}" (middle of history)' \ 'rm -f o e - git-rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e && + git rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e && test '"$Z"' = $(cat o) && test "" = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-26 23:43:00}" (exact end of history)' \ 'rm -f o e - git-rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e && + git rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e && test '"$E"' = $(cat o) && test "" = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-28}" (past end of history)' \ 'rm -f o e - git-rev-parse --verify "master@{2005-05-28}" >o 2>e && + git rev-parse --verify "master@{2005-05-28}" >o 2>e && test '"$D"' = $(cat o) && test "warning: Log .git/logs/'"$m unexpectedly ended on $ld"'." = "$(cat e)"' @@ -188,26 +188,26 @@ rm -f .git/$m .git/logs/$m expect test_expect_success \ 'creating initial files' \ 'echo TEST >F && - git-add F && + git add F && GIT_AUTHOR_DATE="2005-05-26 23:30" \ GIT_COMMITTER_DATE="2005-05-26 23:30" git-commit -m add -a && - h_TEST=$(git-rev-parse --verify HEAD) + h_TEST=$(git rev-parse --verify HEAD) echo The other day this did not work. >M && echo And then Bob told me how to fix it. >>M && echo OTHER >F && GIT_AUTHOR_DATE="2005-05-26 23:41" \ GIT_COMMITTER_DATE="2005-05-26 23:41" git-commit -F M -a && - h_OTHER=$(git-rev-parse --verify HEAD) && + h_OTHER=$(git rev-parse --verify HEAD) && echo FIXED >F && GIT_AUTHOR_DATE="2005-05-26 23:44" \ GIT_COMMITTER_DATE="2005-05-26 23:44" git-commit --amend && - h_FIXED=$(git-rev-parse --verify HEAD) && + h_FIXED=$(git rev-parse --verify HEAD) && echo TEST+FIXED >F && echo Merged initial commit and a later commit. >M && echo $h_TEST >.git/MERGE_HEAD && GIT_AUTHOR_DATE="2005-05-26 23:45" \ GIT_COMMITTER_DATE="2005-05-26 23:45" git-commit -F M && - h_MERGED=$(git-rev-parse --verify HEAD) + h_MERGED=$(git rev-parse --verify HEAD) rm -f M' cat >expect <path1/file1 test_expect_success \ - 'git-update-index --add various paths.' \ - 'git-update-index --add path0 path1/file1' + 'git update-index --add various paths.' \ + 'git update-index --add path0 path1/file1' rm -fr path0 path1 mkdir path0 @@ -37,15 +37,15 @@ date >path0/file0 date >path1 test_expect_failure \ - 'git-checkout-index without -f should fail on conflicting work tree.' \ - 'git-checkout-index -a' + 'git checkout-index without -f should fail on conflicting work tree.' \ + 'git checkout-index -a' test_expect_success \ - 'git-checkout-index with -f should succeed.' \ - 'git-checkout-index -f -a' + 'git checkout-index with -f should succeed.' \ + 'git checkout-index -f -a' test_expect_success \ - 'git-checkout-index conflicting paths.' \ + 'git checkout-index conflicting paths.' \ 'test -f path0 && test -d path1 && test -f path1/file1' test_done diff --git a/t/t2001-checkout-cache-clash.sh b/t/t2001-checkout-cache-clash.sh index b895a0fe36..ef007532b1 100755 --- a/t/t2001-checkout-cache-clash.sh +++ b/t/t2001-checkout-cache-clash.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-checkout-index test. +test_description='git checkout-index test. This test registers the following filesystem structure in the cache: @@ -26,46 +26,46 @@ show_files() { find path? -ls | sed -e 's/^[0-9]* * [0-9]* * \([-bcdl]\)[^ ]* *[0-9]* *[^ ]* *[^ ]* *[0-9]* [A-Z][a-z][a-z] [0-9][0-9] [^ ]* /fs: \1 /' # what's in the cache, just mode and name - git-ls-files --stage | + git ls-files --stage | sed -e 's/^\([0-9]*\) [0-9a-f]* [0-3] /ca: \1 /' # what's in the tree, just mode and name. - git-ls-tree -r "$1" | + git ls-tree -r "$1" | sed -e 's/^\([0-9]*\) [^ ]* [0-9a-f]* /tr: \1 /' } mkdir path0 date >path0/file0 test_expect_success \ - 'git-update-index --add path0/file0' \ - 'git-update-index --add path0/file0' + 'git update-index --add path0/file0' \ + 'git update-index --add path0/file0' test_expect_success \ - 'writing tree out with git-write-tree' \ - 'tree1=$(git-write-tree)' + 'writing tree out with git write-tree' \ + 'tree1=$(git write-tree)' test_debug 'show_files $tree1' mkdir path1 date >path1/file1 test_expect_success \ - 'git-update-index --add path1/file1' \ - 'git-update-index --add path1/file1' + 'git update-index --add path1/file1' \ + 'git update-index --add path1/file1' test_expect_success \ - 'writing tree out with git-write-tree' \ - 'tree2=$(git-write-tree)' + 'writing tree out with git write-tree' \ + 'tree2=$(git write-tree)' test_debug 'show_files $tree2' rm -fr path1 test_expect_success \ 'read previously written tree and checkout.' \ - 'git-read-tree -m $tree1 && git-checkout-index -f -a' + 'git read-tree -m $tree1 && git checkout-index -f -a' test_debug 'show_files $tree1' ln -s path0 path1 test_expect_success \ - 'git-update-index --add a symlink.' \ - 'git-update-index --add path1' + 'git update-index --add a symlink.' \ + 'git update-index --add path1' test_expect_success \ - 'writing tree out with git-write-tree' \ - 'tree3=$(git-write-tree)' + 'writing tree out with git write-tree' \ + 'tree3=$(git write-tree)' test_debug 'show_files $tree3' # Morten says "Got that?" here. @@ -73,7 +73,7 @@ test_debug 'show_files $tree3' test_expect_success \ 'read previously written tree and checkout.' \ - 'git-read-tree $tree2 && git-checkout-index -f -a' + 'git read-tree $tree2 && git checkout-index -f -a' test_debug 'show_files $tree2' test_expect_success \ diff --git a/t/t2002-checkout-cache-u.sh b/t/t2002-checkout-cache-u.sh index 4352ddb1cb..f7a0055920 100755 --- a/t/t2002-checkout-cache-u.sh +++ b/t/t2002-checkout-cache-u.sh @@ -3,31 +3,31 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-checkout-index -u test. +test_description='git checkout-index -u test. -With -u flag, git-checkout-index internally runs the equivalent of -git-update-index --refresh on the checked out entry.' +With -u flag, git checkout-index internally runs the equivalent of +git update-index --refresh on the checked out entry.' . ./test-lib.sh test_expect_success \ 'preparation' ' echo frotz >path0 && -git-update-index --add path0 && -t=$(git-write-tree)' +git update-index --add path0 && +t=$(git write-tree)' test_expect_failure \ -'without -u, git-checkout-index smudges stat information.' ' +'without -u, git checkout-index smudges stat information.' ' rm -f path0 && -git-read-tree $t && -git-checkout-index -f -a && -git-diff-files | diff - /dev/null' +git read-tree $t && +git checkout-index -f -a && +git diff-files | diff - /dev/null' test_expect_success \ -'with -u, git-checkout-index picks up stat information from new files.' ' +'with -u, git checkout-index picks up stat information from new files.' ' rm -f path0 && -git-read-tree $t && -git-checkout-index -u -f -a && -git-diff-files | diff - /dev/null' +git read-tree $t && +git checkout-index -u -f -a && +git diff-files | diff - /dev/null' test_done diff --git a/t/t2003-checkout-cache-mkdir.sh b/t/t2003-checkout-cache-mkdir.sh index f9bc90aee4..71894b3743 100755 --- a/t/t2003-checkout-cache-mkdir.sh +++ b/t/t2003-checkout-cache-mkdir.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-checkout-index --prefix test. +test_description='git checkout-index --prefix test. This test makes sure that --prefix option works as advertised, and also verifies that such leading path may contain symlinks, unlike @@ -17,14 +17,14 @@ test_expect_success \ 'mkdir path1 && echo frotz >path0 && echo rezrov >path1/file1 && - git-update-index --add path0 path1/file1' + git update-index --add path0 path1/file1' test_expect_success \ 'have symlink in place where dir is expected.' \ 'rm -fr path0 path1 && mkdir path2 && ln -s path2 path1 && - git-checkout-index -f -a && + git checkout-index -f -a && test ! -h path1 && test -d path1 && test -f path1/file1 && test ! -f path2/file1' @@ -32,7 +32,7 @@ test_expect_success \ 'use --prefix=path2/' \ 'rm -fr path0 path1 path2 && mkdir path2 && - git-checkout-index --prefix=path2/ -f -a && + git checkout-index --prefix=path2/ -f -a && test -f path2/path0 && test -f path2/path1/file1 && test ! -f path0 && @@ -41,7 +41,7 @@ test_expect_success \ test_expect_success \ 'use --prefix=tmp-' \ 'rm -fr path0 path1 path2 tmp* && - git-checkout-index --prefix=tmp- -f -a && + git checkout-index --prefix=tmp- -f -a && test -f tmp-path0 && test -f tmp-path1/file1 && test ! -f path0 && @@ -52,7 +52,7 @@ test_expect_success \ 'rm -fr path0 path1 path2 tmp* && echo nitfol >tmp-path1 && mkdir tmp-path0 && - git-checkout-index --prefix=tmp- -f -a && + git checkout-index --prefix=tmp- -f -a && test -f tmp-path0 && test -f tmp-path1/file1 && test ! -f path0 && @@ -64,7 +64,7 @@ test_expect_success \ 'rm -fr path0 path1 path2 tmp* && mkdir tmp1 tmp1/orary && ln -s tmp1 tmp && - git-checkout-index --prefix=tmp/orary/ -f -a && + git checkout-index --prefix=tmp/orary/ -f -a && test -d tmp1/orary && test -f tmp1/orary/path0 && test -f tmp1/orary/path1/file1 && @@ -76,7 +76,7 @@ test_expect_success \ 'rm -fr path0 path1 path2 tmp* && mkdir tmp1 && ln -s tmp1 tmp && - git-checkout-index --prefix=tmp/orary- -f -a && + git checkout-index --prefix=tmp/orary- -f -a && test -f tmp1/orary-path0 && test -f tmp1/orary-path1/file1 && test -h tmp' @@ -87,7 +87,7 @@ test_expect_success \ 'rm -fr path0 path1 path2 tmp* && mkdir tmp1 && ln -s tmp1 tmp-path1 && - git-checkout-index --prefix=tmp- -f -a && + git checkout-index --prefix=tmp- -f -a && test -f tmp-path0 && test ! -h tmp-path1 && test -d tmp-path1 && diff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh index c100959cad..39133b8c7a 100755 --- a/t/t2004-checkout-cache-temp.sh +++ b/t/t2004-checkout-cache-temp.sh @@ -3,9 +3,9 @@ # Copyright (c) 2006 Shawn Pearce # -test_description='git-checkout-index --temp test. +test_description='git checkout-index --temp test. -With --temp flag, git-checkout-index writes to temporary merge files +With --temp flag, git checkout-index writes to temporary merge files rather than the tracked path.' . ./test-lib.sh @@ -18,28 +18,28 @@ echo tree1path1 >path1 && echo tree1path3 >path3 && echo tree1path4 >path4 && echo tree1asubdir/path5 >asubdir/path5 && -git-update-index --add path0 path1 path3 path4 asubdir/path5 && -t1=$(git-write-tree) && +git update-index --add path0 path1 path3 path4 asubdir/path5 && +t1=$(git write-tree) && rm -f path* .merge_* out .git/index && echo tree2path0 >path0 && echo tree2path1 >path1 && echo tree2path2 >path2 && echo tree2path4 >path4 && -git-update-index --add path0 path1 path2 path4 && -t2=$(git-write-tree) && +git update-index --add path0 path1 path2 path4 && +t2=$(git write-tree) && rm -f path* .merge_* out .git/index && echo tree2path0 >path0 && echo tree3path1 >path1 && echo tree3path2 >path2 && echo tree3path3 >path3 && -git-update-index --add path0 path1 path2 path3 && -t3=$(git-write-tree)' +git update-index --add path0 path1 path2 path3 && +t3=$(git write-tree)' test_expect_success \ 'checkout one stage 0 to temporary file' ' rm -f path* .merge_* out .git/index && -git-read-tree $t1 && -git-checkout-index --temp -- path1 >out && +git read-tree $t1 && +git checkout-index --temp -- path1 >out && test $(wc -l out && +git read-tree $t1 && +git checkout-index -a --temp >out && test $(wc -l out && +git checkout-index --stage=2 --temp -- path1 >out && test $(wc -l out && +git checkout-index --all --stage=2 --temp >out && test $(wc -l out && +git checkout-index --stage=all --temp -- path0 >out && test $(wc -l out && +git checkout-index --stage=all --temp -- path1 >out && test $(wc -l out && +git checkout-index --stage=all --temp -- path2 >out && test $(wc -l out && +git checkout-index -a --stage=all --temp >out && test $(wc -l out && + git checkout-index -a --stage=all >out && test $(wc -l out && +git read-tree $t4 && +git checkout-index --temp -a >out && test $(wc -l path2/file2 date >path3/file3 test_expect_success \ - 'git-update-index --add to add various paths.' \ - 'git-update-index --add -- path0 path1 path2/file2 path3/file3' + 'git update-index --add to add various paths.' \ + 'git update-index --add -- path0 path1 path2/file2 path3/file3' rm -fr path? @@ -45,7 +45,7 @@ date >path1/file1 for p in path0/file0 path1/file1 path2 path3 do test_expect_failure \ - "git-update-index to add conflicting path $p should fail." \ - "git-update-index --add -- $p" + "git update-index to add conflicting path $p should fail." \ + "git update-index --add -- $p" done test_done diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh index a78ea7f0b0..59b560bfdf 100755 --- a/t/t2101-update-index-reupdate.sh +++ b/t/t2101-update-index-reupdate.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Junio C Hamano # -test_description='git-update-index --again test. +test_description='git update-index --again test. ' . ./test-lib.sh @@ -15,29 +15,29 @@ EOF test_expect_success 'update-index --add' \ 'echo hello world >file1 && echo goodbye people >file2 && - git-update-index --add file1 file2 && - git-ls-files -s >current && + git update-index --add file1 file2 && + git ls-files -s >current && cmp current expected' test_expect_success 'update-index --again' \ 'rm -f file1 && echo hello everybody >file2 && - if git-update-index --again + if git update-index --again then echo should have refused to remove file1 exit 1 else echo happy - failed as expected fi && - git-ls-files -s >current && + git ls-files -s >current && cmp current expected' cat > expected <<\EOF 100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0 file2 EOF test_expect_success 'update-index --remove --again' \ - 'git-update-index --remove --again && - git-ls-files -s >current && + 'git update-index --remove --again && + git ls-files -s >current && cmp current expected' test_expect_success 'first commit' 'git-commit -m initial' @@ -50,11 +50,11 @@ test_expect_success 'update-index again' \ 'mkdir -p dir1 && echo hello world >dir1/file3 && echo goodbye people >file2 && - git-update-index --add file2 dir1/file3 && + git update-index --add file2 dir1/file3 && echo hello everybody >file2 echo happy >dir1/file3 && - git-update-index --again && - git-ls-files -s >current && + git update-index --again && + git ls-files -s >current && cmp current expected' cat > expected <<\EOF @@ -65,9 +65,9 @@ test_expect_success 'update-index --update from subdir' \ 'echo not so happy >file2 && cd dir1 && cat ../file2 >file3 && - git-update-index --again && + git update-index --again && cd .. && - git-ls-files -s >current && + git ls-files -s >current && cmp current expected' cat > expected <<\EOF @@ -77,8 +77,8 @@ EOF test_expect_success 'update-index --update with pathspec' \ 'echo very happy >file2 && cat file2 >dir1/file3 && - git-update-index --again dir1/ && - git-ls-files -s >current && + git update-index --again dir1/ && + git ls-files -s >current && cmp current expected' test_done diff --git a/t/t2102-update-index-symlinks.sh b/t/t2102-update-index-symlinks.sh index 969ef891d3..19d0894d26 100755 --- a/t/t2102-update-index-symlinks.sh +++ b/t/t2102-update-index-symlinks.sh @@ -3,29 +3,29 @@ # Copyright (c) 2007 Johannes Sixt # -test_description='git-update-index on filesystem w/o symlinks test. +test_description='git update-index on filesystem w/o symlinks test. -This tests that git-update-index keeps the symbolic link property +This tests that git update-index keeps the symbolic link property even if a plain file is in the working tree if core.symlinks is false.' . ./test-lib.sh test_expect_success \ 'preparation' ' -git-config core.symlinks false && +git config core.symlinks false && l=$(echo -n file | git-hash-object -t blob -w --stdin) && -echo "120000 $l symlink" | git-update-index --index-info' +echo "120000 $l symlink" | git update-index --index-info' test_expect_success \ 'modify the symbolic link' ' echo -n new-file > symlink && -git-update-index symlink' +git update-index symlink' test_expect_success \ 'the index entry must still be a symbolic link' ' -case "`git-ls-files --stage --cached symlink`" in +case "`git ls-files --stage --cached symlink`" in 120000" "*symlink) echo ok;; -*) echo fail; git-ls-files --stage --cached symlink; (exit 1);; +*) echo fail; git ls-files --stage --cached symlink; (exit 1);; esac' test_done diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index 83005e70d0..0a703af149 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-add -u with path limiting +test_description='git add -u with path limiting This test creates a working tree state with three files: @@ -8,7 +8,7 @@ This test creates a working tree state with three files: dir/sub (previously committed, modified) dir/other (untracked) -and issues a git-add -u with path limiting on "dir" to add +and issues a git add -u with path limiting on "dir" to add only the updates to dir/sub.' . ./test-lib.sh @@ -17,22 +17,22 @@ test_expect_success 'setup' ' echo initial >top && mkdir dir && echo initial >dir/sub && -git-add dir/sub top && +git add dir/sub top && git-commit -m initial && echo changed >top && echo changed >dir/sub && echo other >dir/other ' -test_expect_success 'update' 'git-add -u dir' +test_expect_success 'update' 'git add -u dir' test_expect_success 'update touched correct path' \ - 'test "`git-diff-files --name-status dir/sub`" = ""' + 'test "`git diff-files --name-status dir/sub`" = ""' test_expect_success 'update did not touch other tracked files' \ - 'test "`git-diff-files --name-status top`" = "M top"' + 'test "`git diff-files --name-status top`" = "M top"' test_expect_success 'update did not touch untracked files' \ - 'test "`git-diff-files --name-status dir/other`" = ""' + 'test "`git diff-files --name-status dir/other`" = ""' test_done diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh index adcbe03d56..bc0a351392 100755 --- a/t/t3000-ls-files-others.sh +++ b/t/t3000-ls-files-others.sh @@ -3,9 +3,9 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-ls-files test (--others should pick up symlinks). +test_description='git ls-files test (--others should pick up symlinks). -This test runs git-ls-files --others with the following on the +This test runs git ls-files --others with the following on the filesystem. path0 - a file @@ -23,7 +23,7 @@ date >path2/file2 date >path2-junk date >path3/file3 date >path3-junk -git-update-index --add path3-junk path3/file3 +git update-index --add path3-junk path3/file3 cat >expected1 <expected2 test_expect_success \ - 'git-ls-files --others to show output.' \ - 'git-ls-files --others >output' + 'git ls-files --others to show output.' \ + 'git ls-files --others >output' test_expect_success \ - 'git-ls-files --others should pick up symlinks.' \ + 'git ls-files --others should pick up symlinks.' \ 'diff output expected1' test_expect_success \ - 'git-ls-files --others --directory to show output.' \ - 'git-ls-files --others --directory >output' + 'git ls-files --others --directory to show output.' \ + 'git ls-files --others --directory >output' test_expect_success \ - 'git-ls-files --others --directory should not get confused.' \ + 'git ls-files --others --directory should not get confused.' \ 'diff output expected2' test_done diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index fcfcfbba7d..ae0639d8f3 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -3,9 +3,9 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-ls-files --others --exclude +test_description='git ls-files --others --exclude -This test runs git-ls-files --others and tests --exclude patterns. +This test runs git ls-files --others and tests --exclude patterns. ' . ./test-lib.sh @@ -59,8 +59,8 @@ echo '!*.2 !*.8' >one/two/.gitignore test_expect_success \ - 'git-ls-files --others with various exclude options.' \ - 'git-ls-files --others \ + 'git ls-files --others with various exclude options.' \ + 'git ls-files --others \ --exclude=\*.6 \ --exclude-per-directory=.gitignore \ --exclude-from=.git/ignore \ @@ -71,8 +71,8 @@ test_expect_success \ printf '*.1\r\n/*.3\r\n!*.6\r\n' >.gitignore test_expect_success \ - 'git-ls-files --others with \r\n line endings.' \ - 'git-ls-files --others \ + 'git ls-files --others with \r\n line endings.' \ + 'git ls-files --others \ --exclude=\*.6 \ --exclude-per-directory=.gitignore \ --exclude-from=.git/ignore \ @@ -84,9 +84,9 @@ cat > excludes-file << EOF e* EOF -git-config core.excludesFile excludes-file +git config core.excludesFile excludes-file -git-runstatus | grep "^# " > output +git runstatus | grep "^# " > output cat > expect << EOF # .gitignore diff --git a/t/t3002-ls-files-dashpath.sh b/t/t3002-ls-files-dashpath.sh index cc8967d76b..8687a01d2b 100755 --- a/t/t3002-ls-files-dashpath.sh +++ b/t/t3002-ls-files-dashpath.sh @@ -3,9 +3,9 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-ls-files test (-- to terminate the path list). +test_description='git ls-files test (-- to terminate the path list). -This test runs git-ls-files --others with the following on the +This test runs git ls-files --others with the following on the filesystem. path0 - a file @@ -21,8 +21,8 @@ test_expect_success \ echo frotz >./--' test_expect_success \ - 'git-ls-files without path restriction.' \ - 'git-ls-files --others >output && + 'git ls-files without path restriction.' \ + 'git ls-files --others >output && git diff output - <output && + 'git ls-files with path restriction.' \ + 'git ls-files --others path0 >output && git diff output - <output && + 'git ls-files with path restriction with --.' \ + 'git ls-files --others -- path0 >output && git diff output - <output && + 'git ls-files with path restriction with -- --.' \ + 'git ls-files --others -- -- >output && git diff output - <output && + 'git ls-files with no path restriction.' \ + 'git ls-files --others -- >output && git diff output - <path8 : >path9 date >path10 test_expect_success \ - 'git-update-index --add to add various paths.' \ - "git-update-index --add -- path0 path1 path?/file? path7 path8 path9 path10" + 'git update-index --add to add various paths.' \ + "git update-index --add -- path0 path1 path?/file? path7 path8 path9 path10" rm -fr path? ;# leave path10 alone date >path2 @@ -64,8 +64,8 @@ date >path7 touch path10 test_expect_success \ - 'git-ls-files -k to show killed files.' \ - 'git-ls-files -k >.output' + 'git ls-files -k to show killed files.' \ + 'git ls-files -k >.output' cat >.expected <.output' + 'git ls-files -m to show modified files.' \ + 'git ls-files -m >.output' cat >.expected <path2/baz/b && find path? \( -type f -o -type l \) -print | - xargs git-update-index --add && - tree=`git-write-tree` && + xargs git update-index --add && + tree=`git write-tree` && echo $tree' _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' @@ -40,7 +40,7 @@ test_output () { test_expect_success \ 'ls-tree plain' \ - 'git-ls-tree $tree >current && + 'git ls-tree $tree >current && cat >expected <<\EOF && 100644 blob X path0 120000 blob X path1 @@ -50,7 +50,7 @@ EOF test_expect_success \ 'ls-tree recursive' \ - 'git-ls-tree -r $tree >current && + 'git ls-tree -r $tree >current && cat >expected <<\EOF && 100644 blob X path0 120000 blob X path1 @@ -62,7 +62,7 @@ EOF test_expect_success \ 'ls-tree recursive with -t' \ - 'git-ls-tree -r -t $tree >current && + 'git ls-tree -r -t $tree >current && cat >expected <<\EOF && 100644 blob X path0 120000 blob X path1 @@ -76,7 +76,7 @@ EOF test_expect_success \ 'ls-tree recursive with -d' \ - 'git-ls-tree -r -d $tree >current && + 'git ls-tree -r -d $tree >current && cat >expected <<\EOF && 040000 tree X path2 040000 tree X path2/baz @@ -85,7 +85,7 @@ EOF test_expect_success \ 'ls-tree filtered with path' \ - 'git-ls-tree $tree path >current && + 'git ls-tree $tree path >current && cat >expected <<\EOF && EOF test_output' @@ -95,7 +95,7 @@ EOF # they are shown in canonical order. test_expect_success \ 'ls-tree filtered with path1 path0' \ - 'git-ls-tree $tree path1 path0 >current && + 'git ls-tree $tree path1 path0 >current && cat >expected <<\EOF && 100644 blob X path0 120000 blob X path1 @@ -104,7 +104,7 @@ EOF test_expect_success \ 'ls-tree filtered with path0/' \ - 'git-ls-tree $tree path0/ >current && + 'git ls-tree $tree path0/ >current && cat >expected <<\EOF && EOF test_output' @@ -113,7 +113,7 @@ EOF # with pathspec semantics it shows only path2 test_expect_success \ 'ls-tree filtered with path2' \ - 'git-ls-tree $tree path2 >current && + 'git ls-tree $tree path2 >current && cat >expected <<\EOF && 040000 tree X path2 EOF @@ -122,7 +122,7 @@ EOF # ... and path2/ shows the children. test_expect_success \ 'ls-tree filtered with path2/' \ - 'git-ls-tree $tree path2/ >current && + 'git ls-tree $tree path2/ >current && cat >expected <<\EOF && 040000 tree X path2/baz 120000 blob X path2/bazbo @@ -134,7 +134,7 @@ EOF # path2/baz test_expect_success \ 'ls-tree filtered with path2/baz' \ - 'git-ls-tree $tree path2/baz >current && + 'git ls-tree $tree path2/baz >current && cat >expected <<\EOF && 040000 tree X path2/baz EOF @@ -142,14 +142,14 @@ EOF test_expect_success \ 'ls-tree filtered with path2/bak' \ - 'git-ls-tree $tree path2/bak >current && + 'git ls-tree $tree path2/bak >current && cat >expected <<\EOF && EOF test_output' test_expect_success \ 'ls-tree -t filtered with path2/bak' \ - 'git-ls-tree -t $tree path2/bak >current && + 'git ls-tree -t $tree path2/bak >current && cat >expected <<\EOF && 040000 tree X path2 EOF diff --git a/t/t3101-ls-tree-dirname.sh b/t/t3101-ls-tree-dirname.sh index 087929a4bf..39fe2676dc 100755 --- a/t/t3101-ls-tree-dirname.sh +++ b/t/t3101-ls-tree-dirname.sh @@ -4,9 +4,9 @@ # Copyright (c) 2005 Robert Fitzsimons # -test_description='git-ls-tree directory and filenames handling. +test_description='git ls-tree directory and filenames handling. -This test runs git-ls-tree with the following in a tree. +This test runs git ls-tree with the following in a tree. 1.txt - a file 2.txt - a file @@ -35,8 +35,8 @@ test_expect_success \ echo 111 >path3/1.txt && echo 222 >path3/2.txt && find *.txt path* \( -type f -o -type l \) -print | - xargs git-update-index --add && - tree=`git-write-tree` && + xargs git update-index --add && + tree=`git write-tree` && echo $tree' _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' @@ -48,7 +48,7 @@ test_output () { test_expect_success \ 'ls-tree plain' \ - 'git-ls-tree $tree >current && + 'git ls-tree $tree >current && cat >expected <<\EOF && 100644 blob X 1.txt 100644 blob X 2.txt @@ -62,7 +62,7 @@ EOF # Recursive does not show tree nodes anymore... test_expect_success \ 'ls-tree recursive' \ - 'git-ls-tree -r $tree >current && + 'git ls-tree -r $tree >current && cat >expected <<\EOF && 100644 blob X 1.txt 100644 blob X 2.txt @@ -76,7 +76,7 @@ EOF test_expect_success \ 'ls-tree filter 1.txt' \ - 'git-ls-tree $tree 1.txt >current && + 'git ls-tree $tree 1.txt >current && cat >expected <<\EOF && 100644 blob X 1.txt EOF @@ -84,7 +84,7 @@ EOF test_expect_success \ 'ls-tree filter path1/b/c/1.txt' \ - 'git-ls-tree $tree path1/b/c/1.txt >current && + 'git ls-tree $tree path1/b/c/1.txt >current && cat >expected <<\EOF && 100644 blob X path1/b/c/1.txt EOF @@ -92,7 +92,7 @@ EOF test_expect_success \ 'ls-tree filter all 1.txt files' \ - 'git-ls-tree $tree 1.txt path0/a/b/c/1.txt path1/b/c/1.txt path2/1.txt path3/1.txt >current && + 'git ls-tree $tree 1.txt path0/a/b/c/1.txt path1/b/c/1.txt path2/1.txt path3/1.txt >current && cat >expected <<\EOF && 100644 blob X 1.txt 100644 blob X path0/a/b/c/1.txt @@ -107,7 +107,7 @@ EOF # it behaves as if path0/a/b/c, path1/b/c, path2 and path3 are specified. test_expect_success \ 'ls-tree filter directories' \ - 'git-ls-tree $tree path3 path2 path0/a/b/c path1/b/c path0/a >current && + 'git ls-tree $tree path3 path2 path0/a/b/c path1/b/c path0/a >current && cat >expected <<\EOF && 040000 tree X path0/a/b/c 040000 tree X path1/b/c @@ -120,7 +120,7 @@ EOF # having 1.txt and path3 test_expect_success \ 'ls-tree filter odd names' \ - 'git-ls-tree $tree 1.txt /1.txt //1.txt path3/1.txt /path3/1.txt //path3//1.txt path3 /path3/ path3// >current && + 'git ls-tree $tree 1.txt /1.txt //1.txt path3/1.txt /path3/1.txt //path3//1.txt path3 /path3/ path3// >current && cat >expected <<\EOF && 100644 blob X 1.txt 100644 blob X path3/1.txt @@ -130,7 +130,7 @@ EOF test_expect_success \ 'ls-tree filter missing files and extra slashes' \ - 'git-ls-tree $tree 1.txt/ abc.txt path3//23.txt path3/2.txt/// >current && + 'git ls-tree $tree 1.txt/ abc.txt path3//23.txt path3/2.txt/// >current && cat >expected <<\EOF && EOF test_output' diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index f1793d0b9a..c6f472ac04 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -13,22 +13,22 @@ handled. Specifically, that a bogus branch is not created. test_expect_success \ 'prepare a trivial repository' \ 'echo Hello > A && - git-update-index --add A && + git update-index --add A && git-commit -m "Initial commit." && - HEAD=$(git-rev-parse --verify HEAD)' + HEAD=$(git rev-parse --verify HEAD)' test_expect_failure \ 'git branch --help should not have created a bogus branch' \ - 'git-branch --help /dev/null 2>/dev/null || : + 'git branch --help /dev/null 2>/dev/null || : test -f .git/refs/heads/--help' test_expect_success \ 'git branch abc should create a branch' \ - 'git-branch abc && test -f .git/refs/heads/abc' + 'git branch abc && test -f .git/refs/heads/abc' test_expect_success \ 'git branch a/b/c should create a branch' \ - 'git-branch a/b/c && test -f .git/refs/heads/a/b/c' + 'git branch a/b/c && test -f .git/refs/heads/a/b/c' cat >expect < 1117150200 +0000 branch: Created from master @@ -36,149 +36,149 @@ EOF test_expect_success \ 'git branch -l d/e/f should create a branch and a log' \ 'GIT_COMMITTER_DATE="2005-05-26 23:30" \ - git-branch -l d/e/f && + git branch -l d/e/f && test -f .git/refs/heads/d/e/f && test -f .git/logs/refs/heads/d/e/f && diff expect .git/logs/refs/heads/d/e/f' test_expect_success \ 'git branch -d d/e/f should delete a branch and a log' \ - 'git-branch -d d/e/f && + 'git branch -d d/e/f && test ! -f .git/refs/heads/d/e/f && test ! -f .git/logs/refs/heads/d/e/f' test_expect_success \ 'git branch j/k should work after branch j has been deleted' \ - 'git-branch j && - git-branch -d j && - git-branch j/k' + 'git branch j && + git branch -d j && + git branch j/k' test_expect_success \ 'git branch l should work after branch l/m has been deleted' \ - 'git-branch l/m && - git-branch -d l/m && - git-branch l' + 'git branch l/m && + git branch -d l/m && + git branch l' test_expect_success \ 'git branch -m m m/m should work' \ - 'git-branch -l m && - git-branch -m m m/m && + 'git branch -l m && + git branch -m m m/m && test -f .git/logs/refs/heads/m/m' test_expect_success \ 'git branch -m n/n n should work' \ - 'git-branch -l n/n && - git-branch -m n/n n + 'git branch -l n/n && + git branch -m n/n n test -f .git/logs/refs/heads/n' test_expect_failure \ 'git branch -m o/o o should fail when o/p exists' \ - 'git-branch o/o && - git-branch o/p && - git-branch -m o/o o' + 'git branch o/o && + git branch o/p && + git branch -m o/o o' test_expect_failure \ 'git branch -m q r/q should fail when r exists' \ - 'git-branch q && - git-branch r && - git-branch -m q r/q' + 'git branch q && + git branch r && + git branch -m q r/q' mv .git/config .git/config-saved test_expect_success 'git branch -m q q2 without config should succeed' ' - git-branch -m q q2 && - git-branch -m q2 q + git branch -m q q2 && + git branch -m q2 q ' mv .git/config-saved .git/config -git-config branch.s/s.dummy Hello +git config branch.s/s.dummy Hello test_expect_success \ 'git branch -m s/s s should work when s/t is deleted' \ - 'git-branch -l s/s && + 'git branch -l s/s && test -f .git/logs/refs/heads/s/s && - git-branch -l s/t && + git branch -l s/t && test -f .git/logs/refs/heads/s/t && - git-branch -d s/t && - git-branch -m s/s s && + git branch -d s/t && + git branch -m s/s s && test -f .git/logs/refs/heads/s' test_expect_success 'config information was renamed, too' \ - "test $(git-config branch.s.dummy) = Hello && - ! git-config branch.s/s/dummy" + "test $(git config branch.s.dummy) = Hello && + ! git config branch.s/s/dummy" test_expect_failure \ - 'git-branch -m u v should fail when the reflog for u is a symlink' \ - 'git-branch -l u && + 'git branch -m u v should fail when the reflog for u is a symlink' \ + 'git branch -l u && mv .git/logs/refs/heads/u real-u && ln -s real-u .git/logs/refs/heads/u && - git-branch -m u v' + git branch -m u v' test_expect_success 'test tracking setup via --track' \ - 'git-config remote.local.url . && - git-config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git-show-ref -q refs/remotes/local/master || git-fetch local) && - git-branch --track my1 local/master && - test $(git-config branch.my1.remote) = local && - test $(git-config branch.my1.merge) = refs/heads/master' + 'git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track my1 local/master && + test $(git config branch.my1.remote) = local && + test $(git config branch.my1.merge) = refs/heads/master' test_expect_success 'test tracking setup (non-wildcard, matching)' \ - 'git-config remote.local.url . && - git-config remote.local.fetch refs/heads/master:refs/remotes/local/master && - (git-show-ref -q refs/remotes/local/master || git-fetch local) && - git-branch --track my4 local/master && - test $(git-config branch.my4.remote) = local && - test $(git-config branch.my4.merge) = refs/heads/master' + 'git config remote.local.url . && + git config remote.local.fetch refs/heads/master:refs/remotes/local/master && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track my4 local/master && + test $(git config branch.my4.remote) = local && + test $(git config branch.my4.merge) = refs/heads/master' test_expect_success 'test tracking setup (non-wildcard, not matching)' \ - 'git-config remote.local.url . && - git-config remote.local.fetch refs/heads/s:refs/remotes/local/s && - (git-show-ref -q refs/remotes/local/master || git-fetch local) && - git-branch --track my5 local/master && - ! test "$(git-config branch.my5.remote)" = local && - ! test "$(git-config branch.my5.merge)" = refs/heads/master' + 'git config remote.local.url . && + git config remote.local.fetch refs/heads/s:refs/remotes/local/s && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --track my5 local/master && + ! test "$(git config branch.my5.remote)" = local && + ! test "$(git config branch.my5.merge)" = refs/heads/master' test_expect_success 'test tracking setup via config' \ - 'git-config branch.autosetupmerge true && - git-config remote.local.url . && - git-config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git-show-ref -q refs/remotes/local/master || git-fetch local) && - git-branch my3 local/master && - test $(git-config branch.my3.remote) = local && - test $(git-config branch.my3.merge) = refs/heads/master' + 'git config branch.autosetupmerge true && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch my3 local/master && + test $(git config branch.my3.remote) = local && + test $(git config branch.my3.merge) = refs/heads/master' test_expect_success 'test overriding tracking setup via --no-track' \ - 'git-config branch.autosetupmerge true && - git-config remote.local.url . && - git-config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git-show-ref -q refs/remotes/local/master || git-fetch local) && - git-branch --no-track my2 local/master && - git-config branch.autosetupmerge false && - ! test "$(git-config branch.my2.remote)" = local && - ! test "$(git-config branch.my2.merge)" = refs/heads/master' + 'git config branch.autosetupmerge true && + git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/master || git-fetch local) && + git branch --no-track my2 local/master && + git config branch.autosetupmerge false && + ! test "$(git config branch.my2.remote)" = local && + ! test "$(git config branch.my2.merge)" = refs/heads/master' test_expect_success 'test local tracking setup' \ 'git branch --track my6 s && - test $(git-config branch.my6.remote) = . && - test $(git-config branch.my6.merge) = refs/heads/s' + test $(git config branch.my6.remote) = . && + test $(git config branch.my6.merge) = refs/heads/s' test_expect_success 'test tracking setup via --track but deeper' \ - 'git-config remote.local.url . && - git-config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git-show-ref -q refs/remotes/local/o/o || git-fetch local) && - git-branch --track my7 local/o/o && - test "$(git-config branch.my7.remote)" = local && - test "$(git-config branch.my7.merge)" = refs/heads/o/o' + 'git config remote.local.url . && + git config remote.local.fetch refs/heads/*:refs/remotes/local/* && + (git show-ref -q refs/remotes/local/o/o || git-fetch local) && + git branch --track my7 local/o/o && + test "$(git config branch.my7.remote)" = local && + test "$(git config branch.my7.merge)" = refs/heads/o/o' test_expect_success 'test deleting branch deletes branch config' \ - 'git-branch -d my7 && - test "$(git-config branch.my7.remote)" = "" && - test "$(git-config branch.my7.merge)" = ""' + 'git branch -d my7 && + test "$(git config branch.my7.remote)" = "" && + test "$(git config branch.my7.merge)" = ""' test_expect_success 'test deleting branch without config' \ - 'git-branch my7 s && - test "$(git-branch -d my7 2>&1)" = "Deleted branch my7."' + 'git branch my7 s && + test "$(git branch -d my7 2>&1)" = "Deleted branch my7."' # Keep this test last, as it changes the current branch cat >expect <>.git/config test_expect_success \ 'prepare a trivial repository' \ 'echo Hello > A && - git-update-index --add A && + git update-index --add A && git-commit -m "Initial commit." && - HEAD=$(git-rev-parse --verify HEAD)' + HEAD=$(git rev-parse --verify HEAD)' SHA1= test_expect_success \ 'see if git show-ref works as expected' \ - 'git-branch a && + 'git branch a && SHA1=`cat .git/refs/heads/a` && echo "$SHA1 refs/heads/a" >expect && - git-show-ref a >result && + git show-ref a >result && diff expect result' test_expect_success \ 'see if a branch still exists when packed' \ - 'git-branch b && - git-pack-refs --all && + 'git branch b && + git pack-refs --all && rm -f .git/refs/heads/b && echo "$SHA1 refs/heads/b" >expect && - git-show-ref b >result && + git show-ref b >result && diff expect result' test_expect_failure \ 'git branch c/d should barf if branch c exists' \ - 'git-branch c && - git-pack-refs --all && + 'git branch c && + git pack-refs --all && rm .git/refs/heads/c && - git-branch c/d' + git branch c/d' test_expect_success \ 'see if a branch still exists after git pack-refs --prune' \ - 'git-branch e && - git-pack-refs --all --prune && + 'git branch e && + git pack-refs --all --prune && echo "$SHA1 refs/heads/e" >expect && - git-show-ref e >result && + git show-ref e >result && diff expect result' test_expect_failure \ 'see if git pack-refs --prune remove ref files' \ - 'git-branch f && - git-pack-refs --all --prune && + 'git branch f && + git pack-refs --all --prune && ls .git/refs/heads/f' test_expect_success \ 'git branch g should work when git branch g/h has been deleted' \ - 'git-branch g/h && - git-pack-refs --all --prune && - git-branch -d g/h && - git-branch g && - git-pack-refs --all && - git-branch -d g' + 'git branch g/h && + git pack-refs --all --prune && + git branch -d g/h && + git branch g && + git pack-refs --all && + git branch -d g' test_expect_failure \ 'git branch i/j/k should barf if branch i exists' \ - 'git-branch i && - git-pack-refs --all --prune && - git-branch i/j/k' + 'git branch i && + git pack-refs --all --prune && + git branch i/j/k' test_expect_success \ 'test git branch k after branch k/l/m and k/lm have been deleted' \ - 'git-branch k/l && - git-branch k/lm && - git-branch -d k/l && - git-branch k/l/m && - git-branch -d k/l/m && - git-branch -d k/lm && - git-branch k' + 'git branch k/l && + git branch k/lm && + git branch -d k/l && + git branch k/l/m && + git branch -d k/l/m && + git branch -d k/lm && + git branch k' test_expect_success \ 'test git branch n after some branch deletion and pruning' \ - 'git-branch n/o && - git-branch n/op && - git-branch -d n/o && - git-branch n/o/p && - git-branch -d n/op && - git-pack-refs --all --prune && - git-branch -d n/o/p && - git-branch n' + 'git branch n/o && + git branch n/op && + git branch -d n/o && + git branch n/o/p && + git branch -d n/op && + git pack-refs --all --prune && + git branch -d n/o/p && + git branch n' test_expect_success 'pack, prune and repack' ' git-tag foo && - git-pack-refs --all --prune && - git-show-ref >all-of-them && - git-pack-refs && - git-show-ref >again && + git pack-refs --all --prune && + git show-ref >all-of-them && + git pack-refs && + git show-ref >again && diff all-of-them again ' diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh index b5a1400e18..dc8c369310 100755 --- a/t/t3300-funny-names.sh +++ b/t/t3300-funny-names.sh @@ -32,12 +32,12 @@ test -f "$p1" && cmp "$p0" "$p1" || { echo 'just space no-funny' >expected -test_expect_success 'git-ls-files no-funny' \ - 'git-update-index --add "$p0" "$p2" && - git-ls-files >current && +test_expect_success 'git ls-files no-funny' \ + 'git update-index --add "$p0" "$p2" && + git ls-files >current && git diff expected current' -t0=`git-write-tree` +t0=`git write-tree` echo "$t0" >t0 cat > expected <<\EOF @@ -45,19 +45,19 @@ just space no-funny "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git-ls-files with-funny' \ - 'git-update-index --add "$p1" && - git-ls-files >current && +test_expect_success 'git ls-files with-funny' \ + 'git update-index --add "$p1" && + git ls-files >current && git diff expected current' echo 'just space no-funny tabs ," (dq) and spaces' >expected -test_expect_success 'git-ls-files -z with-funny' \ - 'git-ls-files -z | tr \\0 \\012 >current && +test_expect_success 'git ls-files -z with-funny' \ + 'git ls-files -z | tr \\0 \\012 >current && git diff expected current' -t1=`git-write-tree` +t1=`git write-tree` echo "$t1" >t1 cat > expected <<\EOF @@ -65,45 +65,45 @@ just space no-funny "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git-ls-tree with funny' \ - 'git-ls-tree -r $t1 | sed -e "s/^[^ ]* //" >current && +test_expect_success 'git ls-tree with funny' \ + 'git ls-tree -r $t1 | sed -e "s/^[^ ]* //" >current && git diff expected current' cat > expected <<\EOF A "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git-diff-index with-funny' \ - 'git-diff-index --name-status $t0 >current && +test_expect_success 'git diff-index with-funny' \ + 'git diff-index --name-status $t0 >current && git diff expected current' -test_expect_success 'git-diff-tree with-funny' \ - 'git-diff-tree --name-status $t0 $t1 >current && +test_expect_success 'git diff-tree with-funny' \ + 'git diff-tree --name-status $t0 $t1 >current && git diff expected current' echo 'A tabs ," (dq) and spaces' >expected -test_expect_success 'git-diff-index -z with-funny' \ - 'git-diff-index -z --name-status $t0 | tr \\0 \\012 >current && +test_expect_success 'git diff-index -z with-funny' \ + 'git diff-index -z --name-status $t0 | tr \\0 \\012 >current && git diff expected current' -test_expect_success 'git-diff-tree -z with-funny' \ - 'git-diff-tree -z --name-status $t0 $t1 | tr \\0 \\012 >current && +test_expect_success 'git diff-tree -z with-funny' \ + 'git diff-tree -z --name-status $t0 $t1 | tr \\0 \\012 >current && git diff expected current' cat > expected <<\EOF CNUM no-funny "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git-diff-tree -C with-funny' \ - 'git-diff-tree -C --find-copies-harder --name-status \ +test_expect_success 'git diff-tree -C with-funny' \ + 'git diff-tree -C --find-copies-harder --name-status \ $t0 $t1 | sed -e 's/^C[0-9]*/CNUM/' >current && git diff expected current' cat > expected <<\EOF RNUM no-funny "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git-diff-tree delete with-funny' \ - 'git-update-index --force-remove "$p0" && - git-diff-index -M --name-status \ +test_expect_success 'git diff-tree delete with-funny' \ + 'git update-index --force-remove "$p0" && + git diff-index -M --name-status \ $t0 | sed -e 's/^R[0-9]*/RNUM/' >current && git diff expected current' @@ -113,8 +113,8 @@ similarity index NUM% rename from no-funny rename to "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git-diff-tree delete with-funny' \ - 'git-diff-index -M -p $t0 | +test_expect_success 'git diff-tree delete with-funny' \ + 'git diff-index -M -p $t0 | sed -e "s/index [0-9]*%/index NUM%/" >current && git diff expected current' @@ -127,8 +127,8 @@ similarity index NUM% rename from no-funny rename to "tabs\t,\" (dq) and spaces" EOF -test_expect_success 'git-diff-tree delete with-funny' \ - 'git-diff-index -M -p $t0 | +test_expect_success 'git diff-tree delete with-funny' \ + 'git diff-index -M -p $t0 | sed -e "s/index [0-9]*%/index NUM%/" >current && git diff expected current' @@ -136,9 +136,9 @@ cat >expected <<\EOF "tabs\t,\" (dq) and spaces" 1 files changed, 0 insertions(+), 0 deletions(-) EOF -test_expect_success 'git-diff-tree rename with-funny applied' \ - 'git-diff-index -M -p $t0 | - git-apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && +test_expect_success 'git diff-tree rename with-funny applied' \ + 'git diff-index -M -p $t0 | + git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && git diff expected current' cat > expected <<\EOF @@ -146,15 +146,15 @@ cat > expected <<\EOF "tabs\t,\" (dq) and spaces" 2 files changed, 3 insertions(+), 3 deletions(-) EOF -test_expect_success 'git-diff-tree delete with-funny applied' \ - 'git-diff-index -p $t0 | - git-apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && +test_expect_success 'git diff-tree delete with-funny applied' \ + 'git diff-index -p $t0 | + git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && git diff expected current' -test_expect_success 'git-apply non-git diff' \ - 'git-diff-index -p $t0 | +test_expect_success 'git apply non-git diff' \ + 'git diff-index -p $t0 | sed -ne "/^[-+@]/p" | - git-apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && + git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current && git diff expected current' test_done diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index b9d3131cc2..95f3a2a556 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -14,15 +14,15 @@ export GIT_AUTHOR_EMAIL=bogus_email_address test_expect_success \ 'prepare repository with topic branch, then rebase against master' \ 'echo First > A && - git-update-index --add A && + git update-index --add A && git-commit -m "Add A." && git checkout -b my-topic-branch && echo Second > B && - git-update-index --add B && + git update-index --add B && git-commit -m "Add B." && git checkout -f master && echo Third >> A && - git-update-index A && + git update-index A && git-commit -m "Modify A." && git checkout -f my-topic-branch && git rebase master' diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh index 8b19d3ccea..4934a4e010 100755 --- a/t/t3401-rebase-partial.sh +++ b/t/t3401-rebase-partial.sh @@ -14,37 +14,37 @@ local branch. test_expect_success \ 'prepare repository with topic branch' \ 'echo First > A && - git-update-index --add A && + git update-index --add A && git-commit -m "Add A." && git-checkout -b my-topic-branch && echo Second > B && - git-update-index --add B && + git update-index --add B && git-commit -m "Add B." && echo AnotherSecond > C && - git-update-index --add C && + git update-index --add C && git-commit -m "Add C." && git-checkout -f master && echo Third >> A && - git-update-index A && + git update-index A && git-commit -m "Modify A." ' test_expect_success \ 'pick top patch from topic branch into master' \ - 'git-cherry-pick my-topic-branch^0 && + 'git cherry-pick my-topic-branch^0 && git-checkout -f my-topic-branch && - git-branch master-merge master && - git-branch my-topic-branch-merge my-topic-branch + git branch master-merge master && + git branch my-topic-branch-merge my-topic-branch ' test_debug \ - 'git-cherry master && - git-format-patch -k --stdout --full-index master >/dev/null && + 'git cherry master && + git format-patch -k --stdout --full-index master >/dev/null && gitk --all & sleep 1 ' diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index 9e11ed295d..eab053c3e0 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -49,7 +49,7 @@ test_expect_success 'rebase --skip with --merge' ' ' test_expect_success 'merge and reference trees equal' \ - 'test -z "`git-diff-tree skip-merge skip-reference`"' + 'test -z "`git diff-tree skip-merge skip-reference`"' test_debug 'gitk --all & sleep 1' diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh index e83bbee074..d0a440feba 100755 --- a/t/t3500-cherry.sh +++ b/t/t3500-cherry.sh @@ -3,10 +3,10 @@ # Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland # -test_description='git-cherry should detect patches integrated upstream +test_description='git cherry should detect patches integrated upstream This test cherry-picks one local change of two into master branch, and -checks that git-cherry only returns the second patch in the local branch +checks that git cherry only returns the second patch in the local branch ' . ./test-lib.sh @@ -15,40 +15,40 @@ export GIT_AUTHOR_EMAIL=bogus_email_address test_expect_success \ 'prepare repository with topic branch, and check cherry finds the 2 patches from there' \ 'echo First > A && - git-update-index --add A && + git update-index --add A && git-commit -m "Add A." && git-checkout -b my-topic-branch && echo Second > B && - git-update-index --add B && + git update-index --add B && git-commit -m "Add B." && sleep 2 && echo AnotherSecond > C && - git-update-index --add C && + git update-index --add C && git-commit -m "Add C." && git-checkout -f master && rm -f B C && echo Third >> A && - git-update-index A && + git update-index A && git-commit -m "Modify A." && - expr "$(echo $(git-cherry master my-topic-branch) )" : "+ [^ ]* + .*" + expr "$(echo $(git cherry master my-topic-branch) )" : "+ [^ ]* + .*" ' test_expect_success \ 'check that cherry with limit returns only the top patch'\ - 'expr "$(echo $(git-cherry master my-topic-branch my-topic-branch^1) )" : "+ [^ ]*" + 'expr "$(echo $(git cherry master my-topic-branch my-topic-branch^1) )" : "+ [^ ]*" ' test_expect_success \ 'cherry-pick one of the 2 patches, and check cherry recognized one and only one as new' \ - 'git-cherry-pick my-topic-branch^0 && - echo $(git-cherry master my-topic-branch) && - expr "$(echo $(git-cherry master my-topic-branch) )" : "+ [^ ]* - .*" + 'git cherry-pick my-topic-branch^0 && + echo $(git cherry master my-topic-branch) && + expr "$(echo $(git cherry master my-topic-branch) )" : "+ [^ ]* - .*" ' test_done diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 0a97b75288..13a461f31b 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Carl D. Worth # -test_description='Test of the various options to git-rm.' +test_description='Test of the various options to git rm.' . ./test-lib.sh @@ -11,13 +11,13 @@ test_description='Test of the various options to git-rm.' test_expect_success \ 'Initialize test directory' \ "touch -- foo bar baz 'space embedded' -q && - git-add -- foo bar baz 'space embedded' -q && + git add -- foo bar baz 'space embedded' -q && git-commit -m 'add normal files' && test_tabs=y && if touch -- 'tab embedded' 'newline embedded' then - git-add -- 'tab embedded' 'newline + git add -- 'tab embedded' 'newline embedded' && git-commit -m 'add files with tabs and newlines' else @@ -26,7 +26,7 @@ embedded' && fi" # Later we will try removing an unremovable path to make sure -# git-rm barfs, but if the test is run as root that cannot be +# git rm barfs, but if the test is run as root that cannot be # arranged. test_expect_success \ 'Determine rm behavior' \ @@ -38,51 +38,51 @@ test_expect_success \ rm -f test-file' test_expect_success \ - 'Pre-check that foo exists and is in index before git-rm foo' \ - '[ -f foo ] && git-ls-files --error-unmatch foo' + 'Pre-check that foo exists and is in index before git rm foo' \ + '[ -f foo ] && git ls-files --error-unmatch foo' test_expect_success \ - 'Test that git-rm foo succeeds' \ - 'git-rm --cached foo' + 'Test that git rm foo succeeds' \ + 'git rm --cached foo' test_expect_success \ - 'Post-check that foo exists but is not in index after git-rm foo' \ - '[ -f foo ] && ! git-ls-files --error-unmatch foo' + 'Post-check that foo exists but is not in index after git rm foo' \ + '[ -f foo ] && ! git ls-files --error-unmatch foo' test_expect_success \ - 'Pre-check that bar exists and is in index before "git-rm bar"' \ - '[ -f bar ] && git-ls-files --error-unmatch bar' + 'Pre-check that bar exists and is in index before "git rm bar"' \ + '[ -f bar ] && git ls-files --error-unmatch bar' test_expect_success \ - 'Test that "git-rm bar" succeeds' \ - 'git-rm bar' + 'Test that "git rm bar" succeeds' \ + 'git rm bar' test_expect_success \ - 'Post-check that bar does not exist and is not in index after "git-rm -f bar"' \ - '! [ -f bar ] && ! git-ls-files --error-unmatch bar' + 'Post-check that bar does not exist and is not in index after "git rm -f bar"' \ + '! [ -f bar ] && ! git ls-files --error-unmatch bar' test_expect_success \ - 'Test that "git-rm -- -q" succeeds (remove a file that looks like an option)' \ - 'git-rm -- -q' + 'Test that "git rm -- -q" succeeds (remove a file that looks like an option)' \ + 'git rm -- -q' test "$test_tabs" = y && test_expect_success \ - "Test that \"git-rm -f\" succeeds with embedded space, tab, or newline characters." \ - "git-rm -f 'space embedded' 'tab embedded' 'newline + "Test that \"git rm -f\" succeeds with embedded space, tab, or newline characters." \ + "git rm -f 'space embedded' 'tab embedded' 'newline embedded'" if test "$test_failed_remove" = y; then chmod a-w . test_expect_failure \ - 'Test that "git-rm -f" fails if its rm fails' \ - 'git-rm -f baz' + 'Test that "git rm -f" fails if its rm fails' \ + 'git rm -f baz' chmod 775 . else test_expect_success 'skipping removal failure (perhaps running as root?)' : fi test_expect_success \ - 'When the rm in "git-rm -f" fails, it should not remove the file from the index' \ - 'git-ls-files --error-unmatch baz' + 'When the rm in "git rm -f" fails, it should not remove the file from the index' \ + 'git ls-files --error-unmatch baz' test_expect_success 'Remove nonexistent file with --ignore-unmatch' ' git rm --ignore-unmatch nonexistent diff --git a/t/t3700-add.sh b/t/t3700-add.sh index e6466d74a0..b52fde8577 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -3,72 +3,72 @@ # Copyright (c) 2006 Carl D. Worth # -test_description='Test of git-add, including the -- option.' +test_description='Test of git add, including the -- option.' . ./test-lib.sh test_expect_success \ - 'Test of git-add' \ - 'touch foo && git-add foo' + 'Test of git add' \ + 'touch foo && git add foo' test_expect_success \ 'Post-check that foo is in the index' \ - 'git-ls-files foo | grep foo' + 'git ls-files foo | grep foo' test_expect_success \ - 'Test that "git-add -- -q" works' \ - 'touch -- -q && git-add -- -q' + 'Test that "git add -- -q" works' \ + 'touch -- -q && git add -- -q' test_expect_success \ - 'git-add: Test that executable bit is not used if core.filemode=0' \ + 'git add: Test that executable bit is not used if core.filemode=0' \ 'git config core.filemode 0 && echo foo >xfoo1 && chmod 755 xfoo1 && - git-add xfoo1 && - case "`git-ls-files --stage xfoo1`" in + git add xfoo1 && + case "`git ls-files --stage xfoo1`" in 100644" "*xfoo1) echo ok;; - *) echo fail; git-ls-files --stage xfoo1; (exit 1);; + *) echo fail; git ls-files --stage xfoo1; (exit 1);; esac' -test_expect_success 'git-add: filemode=0 should not get confused by symlink' ' +test_expect_success 'git add: filemode=0 should not get confused by symlink' ' rm -f xfoo1 && ln -s foo xfoo1 && - git-add xfoo1 && - case "`git-ls-files --stage xfoo1`" in + git add xfoo1 && + case "`git ls-files --stage xfoo1`" in 120000" "*xfoo1) echo ok;; - *) echo fail; git-ls-files --stage xfoo1; (exit 1);; + *) echo fail; git ls-files --stage xfoo1; (exit 1);; esac ' test_expect_success \ - 'git-update-index --add: Test that executable bit is not used...' \ + 'git update-index --add: Test that executable bit is not used...' \ 'git config core.filemode 0 && echo foo >xfoo2 && chmod 755 xfoo2 && - git-update-index --add xfoo2 && - case "`git-ls-files --stage xfoo2`" in + git update-index --add xfoo2 && + case "`git ls-files --stage xfoo2`" in 100644" "*xfoo2) echo ok;; - *) echo fail; git-ls-files --stage xfoo2; (exit 1);; + *) echo fail; git ls-files --stage xfoo2; (exit 1);; esac' -test_expect_success 'git-add: filemode=0 should not get confused by symlink' ' +test_expect_success 'git add: filemode=0 should not get confused by symlink' ' rm -f xfoo2 && ln -s foo xfoo2 && git update-index --add xfoo2 && - case "`git-ls-files --stage xfoo2`" in + case "`git ls-files --stage xfoo2`" in 120000" "*xfoo2) echo ok;; - *) echo fail; git-ls-files --stage xfoo2; (exit 1);; + *) echo fail; git ls-files --stage xfoo2; (exit 1);; esac ' test_expect_success \ - 'git-update-index --add: Test that executable bit is not used...' \ + 'git update-index --add: Test that executable bit is not used...' \ 'git config core.filemode 0 && ln -s xfoo2 xfoo3 && - git-update-index --add xfoo3 && - case "`git-ls-files --stage xfoo3`" in + git update-index --add xfoo3 && + case "`git ls-files --stage xfoo3`" in 120000" "*xfoo3) echo ok;; - *) echo fail; git-ls-files --stage xfoo3; (exit 1);; + *) echo fail; git ls-files --stage xfoo3; (exit 1);; esac' test_expect_success '.gitignore test setup' ' @@ -80,28 +80,28 @@ test_expect_success '.gitignore test setup' ' ' test_expect_success '.gitignore is honored' ' - git-add . && - ! git-ls-files | grep "\\.ig" + git add . && + ! git ls-files | grep "\\.ig" ' test_expect_success 'error out when attempting to add ignored ones without -f' ' - ! git-add a.?? && - ! git-ls-files | grep "\\.ig" + ! git add a.?? && + ! git ls-files | grep "\\.ig" ' test_expect_success 'error out when attempting to add ignored ones without -f' ' - ! git-add d.?? && - ! git-ls-files | grep "\\.ig" + ! git add d.?? && + ! git ls-files | grep "\\.ig" ' test_expect_success 'add ignored ones with -f' ' - git-add -f a.?? && - git-ls-files --error-unmatch a.ig + git add -f a.?? && + git ls-files --error-unmatch a.ig ' test_expect_success 'add ignored ones with -f' ' - git-add -f d.??/* && - git-ls-files --error-unmatch d.ig/d.if d.ig/d.ig + git add -f d.??/* && + git ls-files --error-unmatch d.ig/d.if d.ig/d.ig ' mkdir 1 1/2 1/3 diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh index 7c7e4335d6..261f199a0c 100755 --- a/t/t3800-mktag.sh +++ b/t/t3800-mktag.sh @@ -22,9 +22,9 @@ check_verify_failure () { # first create a commit, so we have a valid object/type # for the tag. echo Hello >A -git-update-index --add A +git update-index --add A git-commit -m "Initial commit" -head=$(git-rev-parse --verify HEAD) +head=$(git rev-parse --verify HEAD) ############################################################ # 1. length check diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh index ffddb68db3..fcbabe8ec3 100755 --- a/t/t3900-i18n-commit.sh +++ b/t/t3900-i18n-commit.sh @@ -8,28 +8,28 @@ test_description='commit and log output encodings' . ./test-lib.sh compare_with () { - git-show -s $1 | sed -e '1,/^$/d' -e 's/^ //' -e '$d' >current && + git show -s $1 | sed -e '1,/^$/d' -e 's/^ //' -e '$d' >current && git diff current "$2" } test_expect_success setup ' : >F && - git-add F && - T=$(git-write-tree) && - C=$(git-commit-tree $T <../t3900/1-UTF-8.txt) && - git-update-ref HEAD $C && + git add F && + T=$(git write-tree) && + C=$(git commit-tree $T <../t3900/1-UTF-8.txt) && + git update-ref HEAD $C && git-tag C0 ' test_expect_success 'no encoding header for base case' ' - E=$(git-cat-file commit C0 | sed -ne "s/^encoding //p") && + E=$(git cat-file commit C0 | sed -ne "s/^encoding //p") && test z = "z$E" ' for H in ISO-8859-1 EUCJP ISO-2022-JP do test_expect_success "$H setup" ' - git-config i18n.commitencoding $H && + git config i18n.commitencoding $H && git-checkout -b $H C0 && echo $H >F && git-commit -a -F ../t3900/$H.txt @@ -39,21 +39,21 @@ done for H in ISO-8859-1 EUCJP ISO-2022-JP do test_expect_success "check encoding header for $H" ' - E=$(git-cat-file commit '$H' | sed -ne "s/^encoding //p") && + E=$(git cat-file commit '$H' | sed -ne "s/^encoding //p") && test "z$E" = "z'$H'" ' done test_expect_success 'config to remove customization' ' - git-config --unset-all i18n.commitencoding && - if Z=$(git-config --get-all i18n.commitencoding) + git config --unset-all i18n.commitencoding && + if Z=$(git config --get-all i18n.commitencoding) then echo Oops, should have failed. false else test z = "z$Z" fi && - git-config i18n.commitencoding utf-8 + git config i18n.commitencoding utf-8 ' test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' ' @@ -68,8 +68,8 @@ do done test_expect_success 'config to add customization' ' - git-config --unset-all i18n.commitencoding && - if Z=$(git-config --get-all i18n.commitencoding) + git config --unset-all i18n.commitencoding && + if Z=$(git config --get-all i18n.commitencoding) then echo Oops, should have failed. false @@ -81,13 +81,13 @@ test_expect_success 'config to add customization' ' for H in ISO-8859-1 EUCJP ISO-2022-JP do test_expect_success "$H should be shown in itself now" ' - git-config i18n.commitencoding '$H' && + git config i18n.commitencoding '$H' && compare_with '$H' ../t3900/'$H'.txt ' done test_expect_success 'config to tweak customization' ' - git-config i18n.logoutputencoding utf-8 + git config i18n.logoutputencoding utf-8 ' test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' ' @@ -103,7 +103,7 @@ done for J in EUCJP ISO-2022-JP do - git-config i18n.logoutputencoding $J + git config i18n.logoutputencoding $J for H in EUCJP ISO-2022-JP do test_expect_success "$H should be shown in $J now" ' diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh index 24bf0ee018..28e9e372f3 100755 --- a/t/t3901-i18n-patch.sh +++ b/t/t3901-i18n-patch.sh @@ -14,7 +14,7 @@ check_encoding () { do git format-patch --encoding=UTF-8 --stdout HEAD~$i..HEAD~$j | grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD=20=C3=B3=C3=BA?=" && - git-cat-file commit HEAD~$j | + git cat-file commit HEAD~$j | case "$header" in 8859) grep "^encoding ISO-8859-1" ;; @@ -31,7 +31,7 @@ check_encoding () { } test_expect_success setup ' - git-config i18n.commitencoding UTF-8 && + git config i18n.commitencoding UTF-8 && # use UTF-8 in author and committer name to match the # i18n.commitencoding settings @@ -55,7 +55,7 @@ test_expect_success setup ' git commit -s -m "Second on side" && # the second one on the side branch is ISO-8859-1 - git-config i18n.commitencoding ISO-8859-1 && + git config i18n.commitencoding ISO-8859-1 && # use author and committer name in ISO-8859-1 to match it. . ../t3901-8859-1.txt && test_tick && @@ -64,11 +64,11 @@ test_expect_success setup ' git commit -s -m "Third on side" && # Back to default - git-config i18n.commitencoding UTF-8 + git config i18n.commitencoding UTF-8 ' test_expect_success 'format-patch output (ISO-8859-1)' ' - git-config i18n.logoutputencoding ISO-8859-1 && + git config i18n.logoutputencoding ISO-8859-1 && git format-patch --stdout master..HEAD^ >out-l1 && git format-patch --stdout HEAD^ >out-l2 && @@ -91,7 +91,7 @@ test_expect_success 'format-patch output (UTF-8)' ' test_expect_success 'rebase (U/U)' ' # We want the result of rebase in UTF-8 - git-config i18n.commitencoding UTF-8 && + git config i18n.commitencoding UTF-8 && # The test is about logoutputencoding not affecting the # final outcome -- it is used internally to generate the @@ -109,7 +109,7 @@ test_expect_success 'rebase (U/U)' ' ' test_expect_success 'rebase (U/L)' ' - git-config i18n.commitencoding UTF-8 && + git config i18n.commitencoding UTF-8 && git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-utf8.txt && @@ -121,7 +121,7 @@ test_expect_success 'rebase (U/L)' ' test_expect_success 'rebase (L/L)' ' # In this test we want ISO-8859-1 encoded commits as the result - git-config i18n.commitencoding ISO-8859-1 && + git config i18n.commitencoding ISO-8859-1 && git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-8859-1.txt && @@ -134,7 +134,7 @@ test_expect_success 'rebase (L/L)' ' test_expect_success 'rebase (L/U)' ' # This is pathological -- use UTF-8 as intermediate form # to get ISO-8859-1 results. - git-config i18n.commitencoding ISO-8859-1 && + git config i18n.commitencoding ISO-8859-1 && git config i18n.logoutputencoding UTF-8 && . ../t3901-8859-1.txt && @@ -147,7 +147,7 @@ test_expect_success 'rebase (L/U)' ' test_expect_success 'cherry-pick(U/U)' ' # Both the commitencoding and logoutputencoding is set to UTF-8. - git-config i18n.commitencoding UTF-8 && + git config i18n.commitencoding UTF-8 && git config i18n.logoutputencoding UTF-8 && . ../t3901-utf8.txt && @@ -162,7 +162,7 @@ test_expect_success 'cherry-pick(U/U)' ' test_expect_success 'cherry-pick(L/L)' ' # Both the commitencoding and logoutputencoding is set to ISO-8859-1 - git-config i18n.commitencoding ISO-8859-1 && + git config i18n.commitencoding ISO-8859-1 && git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-8859-1.txt && @@ -177,7 +177,7 @@ test_expect_success 'cherry-pick(L/L)' ' test_expect_success 'cherry-pick(U/L)' ' # Commitencoding is set to UTF-8 but logoutputencoding is ISO-8859-1 - git-config i18n.commitencoding UTF-8 && + git config i18n.commitencoding UTF-8 && git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-utf8.txt && @@ -193,7 +193,7 @@ test_expect_success 'cherry-pick(L/U)' ' # Again, the commitencoding is set to ISO-8859-1 but # logoutputencoding is set to UTF-8. - git-config i18n.commitencoding ISO-8859-1 && + git config i18n.commitencoding ISO-8859-1 && git config i18n.logoutputencoding UTF-8 && . ../t3901-8859-1.txt && @@ -206,7 +206,7 @@ test_expect_success 'cherry-pick(L/U)' ' ' test_expect_success 'rebase --merge (U/U)' ' - git-config i18n.commitencoding UTF-8 && + git config i18n.commitencoding UTF-8 && git config i18n.logoutputencoding UTF-8 && . ../t3901-utf8.txt && @@ -217,7 +217,7 @@ test_expect_success 'rebase --merge (U/U)' ' ' test_expect_success 'rebase --merge (U/L)' ' - git-config i18n.commitencoding UTF-8 && + git config i18n.commitencoding UTF-8 && git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-utf8.txt && @@ -229,7 +229,7 @@ test_expect_success 'rebase --merge (U/L)' ' test_expect_success 'rebase --merge (L/L)' ' # In this test we want ISO-8859-1 encoded commits as the result - git-config i18n.commitencoding ISO-8859-1 && + git config i18n.commitencoding ISO-8859-1 && git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-8859-1.txt && @@ -242,7 +242,7 @@ test_expect_success 'rebase --merge (L/L)' ' test_expect_success 'rebase --merge (L/U)' ' # This is pathological -- use UTF-8 as intermediate form # to get ISO-8859-1 results. - git-config i18n.commitencoding ISO-8859-1 && + git config i18n.commitencoding ISO-8859-1 && git config i18n.logoutputencoding UTF-8 && . ../t3901-8859-1.txt && diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh index 9c58d77cc2..7d92ae3e99 100755 --- a/t/t4000-diff-format.sh +++ b/t/t4000-diff-format.sh @@ -17,15 +17,15 @@ chmod +x path1 test_expect_success \ 'update-cache --add two files with and without +x.' \ - 'git-update-index --add path0 path1' + 'git update-index --add path0 path1' mv path0 path0- sed -e 's/line/Line/' path0 chmod +x path0 rm -f path1 test_expect_success \ - 'git-diff-files -p after editing work tree.' \ - 'git-diff-files -p >current' + 'git diff-files -p after editing work tree.' \ + 'git diff-files -p >current' # that's as far as it comes if [ "$(git config --get core.filemode)" = false ] @@ -56,7 +56,7 @@ deleted file mode 100755 EOF test_expect_success \ - 'validate git-diff-files -p output.' \ + 'validate git diff-files -p output.' \ 'compare_diff_patch current expected' test_done diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index 90c085f828..063e79257a 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -28,21 +28,21 @@ Line 15 test_expect_success \ 'update-cache --add a file.' \ - 'git-update-index --add path0' + 'git update-index --add path0' test_expect_success \ 'write that tree.' \ - 'tree=$(git-write-tree) && echo $tree' + 'tree=$(git write-tree) && echo $tree' sed -e 's/line/Line/' path1 rm -f path0 test_expect_success \ 'renamed and edited the file.' \ - 'git-update-index --add --remove path0 path1' + 'git update-index --add --remove path0 path1' test_expect_success \ - 'git-diff-index -p -M after rename and editing.' \ - 'git-diff-index -p -M $tree >current' + 'git diff-index -p -M after rename and editing.' \ + 'git diff-index -p -M $tree >current' cat >expected <<\EOF diff --git a/path0 b/path1 rename from path0 diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index 56eda63fc2..a4cfde6b29 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -140,80 +140,80 @@ cmp_diff_files_output () { test_expect_success \ 'diff-tree of known trees.' \ - 'git-diff-tree $tree_O $tree_A >.test-a && + 'git diff-tree $tree_O $tree_A >.test-a && cmp -s .test-a .test-plain-OA' test_expect_success \ 'diff-tree of known trees.' \ - 'git-diff-tree -r $tree_O $tree_A >.test-a && + 'git diff-tree -r $tree_O $tree_A >.test-a && cmp -s .test-a .test-recursive-OA' test_expect_success \ 'diff-tree of known trees.' \ - 'git-diff-tree $tree_O $tree_B >.test-a && + 'git diff-tree $tree_O $tree_B >.test-a && cmp -s .test-a .test-plain-OB' test_expect_success \ 'diff-tree of known trees.' \ - 'git-diff-tree -r $tree_O $tree_B >.test-a && + 'git diff-tree -r $tree_O $tree_B >.test-a && cmp -s .test-a .test-recursive-OB' test_expect_success \ 'diff-tree of known trees.' \ - 'git-diff-tree $tree_A $tree_B >.test-a && + 'git diff-tree $tree_A $tree_B >.test-a && cmp -s .test-a .test-plain-AB' test_expect_success \ 'diff-tree of known trees.' \ - 'git-diff-tree -r $tree_A $tree_B >.test-a && + 'git diff-tree -r $tree_A $tree_B >.test-a && cmp -s .test-a .test-recursive-AB' test_expect_success \ 'diff-cache O with A in cache' \ - 'git-read-tree $tree_A && - git-diff-index --cached $tree_O >.test-a && + 'git read-tree $tree_A && + git diff-index --cached $tree_O >.test-a && cmp -s .test-a .test-recursive-OA' test_expect_success \ 'diff-cache O with B in cache' \ - 'git-read-tree $tree_B && - git-diff-index --cached $tree_O >.test-a && + 'git read-tree $tree_B && + git diff-index --cached $tree_O >.test-a && cmp -s .test-a .test-recursive-OB' test_expect_success \ 'diff-cache A with B in cache' \ - 'git-read-tree $tree_B && - git-diff-index --cached $tree_A >.test-a && + 'git read-tree $tree_B && + git diff-index --cached $tree_A >.test-a && cmp -s .test-a .test-recursive-AB' test_expect_success \ 'diff-files with O in cache and A checked out' \ 'rm -fr Z [A-Z][A-Z] && - git-read-tree $tree_A && - git-checkout-index -f -a && - git-read-tree --reset $tree_O || return 1 - git-update-index --refresh >/dev/null ;# this can exit non-zero - git-diff-files >.test-a && + git read-tree $tree_A && + git checkout-index -f -a && + git read-tree --reset $tree_O || return 1 + git update-index --refresh >/dev/null ;# this can exit non-zero + git diff-files >.test-a && cmp_diff_files_output .test-a .test-recursive-OA' test_expect_success \ 'diff-files with O in cache and B checked out' \ 'rm -fr Z [A-Z][A-Z] && - git-read-tree $tree_B && - git-checkout-index -f -a && - git-read-tree --reset $tree_O || return 1 - git-update-index --refresh >/dev/null ;# this can exit non-zero - git-diff-files >.test-a && + git read-tree $tree_B && + git checkout-index -f -a && + git read-tree --reset $tree_O || return 1 + git update-index --refresh >/dev/null ;# this can exit non-zero + git diff-files >.test-a && cmp_diff_files_output .test-a .test-recursive-OB' test_expect_success \ 'diff-files with A in cache and B checked out' \ 'rm -fr Z [A-Z][A-Z] && - git-read-tree $tree_B && - git-checkout-index -f -a && - git-read-tree --reset $tree_A || return 1 - git-update-index --refresh >/dev/null ;# this can exit non-zero - git-diff-files >.test-a && + git read-tree $tree_B && + git checkout-index -f -a && + git read-tree --reset $tree_A || return 1 + git update-index --refresh >/dev/null ;# this can exit non-zero + git diff-files >.test-a && cmp_diff_files_output .test-a .test-recursive-AB' ################################################################ @@ -222,26 +222,26 @@ test_expect_success \ test_expect_success \ 'diff-tree O A == diff-tree -R A O' \ - 'git-diff-tree $tree_O $tree_A >.test-a && - git-diff-tree -R $tree_A $tree_O >.test-b && + 'git diff-tree $tree_O $tree_A >.test-a && + git diff-tree -R $tree_A $tree_O >.test-b && cmp -s .test-a .test-b' test_expect_success \ 'diff-tree -r O A == diff-tree -r -R A O' \ - 'git-diff-tree -r $tree_O $tree_A >.test-a && - git-diff-tree -r -R $tree_A $tree_O >.test-b && + 'git diff-tree -r $tree_O $tree_A >.test-a && + git diff-tree -r -R $tree_A $tree_O >.test-b && cmp -s .test-a .test-b' test_expect_success \ 'diff-tree B A == diff-tree -R A B' \ - 'git-diff-tree $tree_B $tree_A >.test-a && - git-diff-tree -R $tree_A $tree_B >.test-b && + 'git diff-tree $tree_B $tree_A >.test-a && + git diff-tree -R $tree_A $tree_B >.test-b && cmp -s .test-a .test-b' test_expect_success \ 'diff-tree -r B A == diff-tree -r -R A B' \ - 'git-diff-tree -r $tree_B $tree_A >.test-a && - git-diff-tree -r -R $tree_A $tree_B >.test-b && + 'git diff-tree -r $tree_B $tree_A >.test-a && + git diff-tree -r -R $tree_A $tree_B >.test-b && cmp -s .test-a .test-b' test_done diff --git a/t/t4003-diff-rename-1.sh b/t/t4003-diff-rename-1.sh index 27519704d4..8b1f875286 100755 --- a/t/t4003-diff-rename-1.sh +++ b/t/t4003-diff-rename-1.sh @@ -13,8 +13,8 @@ test_expect_success \ 'prepare reference tree' \ 'cat ../../COPYING >COPYING && echo frotz >rezrov && - git-update-index --add COPYING rezrov && - tree=$(git-write-tree) && + git update-index --add COPYING rezrov && + tree=$(git write-tree) && echo $tree' test_expect_success \ @@ -22,14 +22,14 @@ test_expect_success \ 'sed -e 's/HOWEVER/However/' COPYING.1 && sed -e 's/GPL/G.P.L/g' COPYING.2 && rm -f COPYING && - git-update-index --add --remove COPYING COPYING.?' + git update-index --add --remove COPYING COPYING.?' # tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2, # both are slightly edited, and unchanged rezrov. So we say you # copy-and-edit one, and rename-and-edit the other. We do not say # anything about rezrov. -GIT_DIFF_OPTS=--unified=0 git-diff-index -M -p $tree >current +GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current cat >expected <<\EOF diff --git a/COPYING b/COPYING.1 copy from COPYING @@ -62,14 +62,14 @@ test_expect_success \ test_expect_success \ 'prepare work tree again' \ 'mv COPYING.2 COPYING && - git-update-index --add --remove COPYING COPYING.1 COPYING.2' + git update-index --add --remove COPYING COPYING.1 COPYING.2' # tree has COPYING and rezrov. work tree has COPYING and COPYING.1, # both are slightly edited, and unchanged rezrov. So we say you # edited one, and copy-and-edit the other. We do not say # anything about rezrov. -GIT_DIFF_OPTS=--unified=0 git-diff-index -C -p $tree >current +GIT_DIFF_OPTS=--unified=0 git diff-index -C -p $tree >current cat >expected <<\EOF diff --git a/COPYING b/COPYING --- a/COPYING @@ -100,16 +100,16 @@ test_expect_success \ test_expect_success \ 'prepare work tree once again' \ 'cat ../../COPYING >COPYING && - git-update-index --add --remove COPYING COPYING.1' + git update-index --add --remove COPYING COPYING.1' # tree has COPYING and rezrov. work tree has COPYING and COPYING.1, # but COPYING is not edited. We say you copy-and-edit COPYING.1; this # is only possible because -C mode now reports the unmodified file to # the diff-core. Unchanged rezrov, although being fed to -# git-diff-index as well, should not be mentioned. +# git diff-index as well, should not be mentioned. GIT_DIFF_OPTS=--unified=0 \ - git-diff-index -C --find-copies-harder -p $tree >current + git diff-index -C --find-copies-harder -p $tree >current cat >expected <<\EOF diff --git a/COPYING b/COPYING.1 copy from COPYING diff --git a/t/t4004-diff-rename-symlink.sh b/t/t4004-diff-rename-symlink.sh index a23aaa0a94..3d25be7a67 100755 --- a/t/t4004-diff-rename-symlink.sh +++ b/t/t4004-diff-rename-symlink.sh @@ -16,8 +16,8 @@ test_expect_success \ 'prepare reference tree' \ 'echo xyzzy | tr -d '\\\\'012 >yomin && ln -s xyzzy frotz && - git-update-index --add frotz yomin && - tree=$(git-write-tree) && + git update-index --add frotz yomin && + tree=$(git write-tree) && echo $tree' test_expect_success \ @@ -26,7 +26,7 @@ test_expect_success \ rm -f yomin && ln -s xyzzy nitfol && ln -s xzzzy bozbar && - git-update-index --add --remove frotz rezrov nitfol bozbar yomin' + git update-index --add --remove frotz rezrov nitfol bozbar yomin' # tree has frotz pointing at xyzzy, and yomin that contains xyzzy to # confuse things. work tree has rezrov (xyzzy) nitfol (xyzzy) and @@ -34,7 +34,7 @@ test_expect_success \ # rezrov and nitfol are rename/copy of frotz and bozbar should be # a new creation. -GIT_DIFF_OPTS=--unified=0 git-diff-index -M -p $tree >current +GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current cat >expected <<\EOF diff --git a/bozbar b/bozbar new file mode 120000 diff --git a/t/t4005-diff-rename-2.sh b/t/t4005-diff-rename-2.sh index 684fd23a41..6630017312 100755 --- a/t/t4005-diff-rename-2.sh +++ b/t/t4005-diff-rename-2.sh @@ -13,8 +13,8 @@ test_expect_success \ 'prepare reference tree' \ 'cat ../../COPYING >COPYING && echo frotz >rezrov && - git-update-index --add COPYING rezrov && - tree=$(git-write-tree) && + git update-index --add COPYING rezrov && + tree=$(git write-tree) && echo $tree' test_expect_success \ @@ -22,14 +22,14 @@ test_expect_success \ 'sed -e 's/HOWEVER/However/' COPYING.1 && sed -e 's/GPL/G.P.L/g' COPYING.2 && rm -f COPYING && - git-update-index --add --remove COPYING COPYING.?' + git update-index --add --remove COPYING COPYING.?' # tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2, # both are slightly edited, and unchanged rezrov. We say COPYING.1 # and COPYING.2 are based on COPYING, and do not say anything about # rezrov. -git-diff-index -M $tree >current +git diff-index -M $tree >current cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1 @@ -45,14 +45,14 @@ test_expect_success \ test_expect_success \ 'prepare work tree again' \ 'mv COPYING.2 COPYING && - git-update-index --add --remove COPYING COPYING.1 COPYING.2' + git update-index --add --remove COPYING COPYING.1 COPYING.2' # tree has COPYING and rezrov. work tree has COPYING and COPYING.1, # both are slightly edited, and unchanged rezrov. We say COPYING.1 # is based on COPYING and COPYING is still there, and do not say anything # about rezrov. -git-diff-index -C $tree >current +git diff-index -C $tree >current cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M COPYING :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1 @@ -72,9 +72,9 @@ test_expect_success \ test_expect_success \ 'prepare work tree once again' \ 'cat ../../COPYING >COPYING && - git-update-index --add --remove COPYING COPYING.1' + git update-index --add --remove COPYING COPYING.1' -git-diff-index -C --find-copies-harder $tree >current +git diff-index -C --find-copies-harder $tree >current cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1 EOF diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh index b8acca1813..ab5406dd9f 100755 --- a/t/t4006-diff-mode.sh +++ b/t/t4006-diff-mode.sh @@ -11,24 +11,24 @@ test_description='Test mode change diffs. test_expect_success \ 'setup' \ 'echo frotz >rezrov && - git-update-index --add rezrov && - tree=`git-write-tree` && + git update-index --add rezrov && + tree=`git write-tree` && echo $tree' if [ "$(git config --get core.filemode)" = false ] then say 'filemode disabled on the filesystem, using update-index --chmod=+x' test_expect_success \ - 'git-update-index --chmod=+x' \ - 'git-update-index rezrov && - git-update-index --chmod=+x rezrov && - git-diff-index $tree >current' + 'git update-index --chmod=+x' \ + 'git update-index rezrov && + git update-index --chmod=+x rezrov && + git diff-index $tree >current' else test_expect_success \ 'chmod' \ 'chmod +x rezrov && - git-update-index rezrov && - git-diff-index $tree >current' + git update-index rezrov && + git diff-index $tree >current' fi _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh index bb6ba69258..104a4e1492 100755 --- a/t/t4007-rename-3.sh +++ b/t/t4007-rename-3.sh @@ -13,20 +13,20 @@ test_expect_success \ 'prepare reference tree' \ 'mkdir path0 path1 && cp ../../COPYING path0/COPYING && - git-update-index --add path0/COPYING && - tree=$(git-write-tree) && + git update-index --add path0/COPYING && + tree=$(git write-tree) && echo $tree' test_expect_success \ 'prepare work tree' \ 'cp path0/COPYING path1/COPYING && - git-update-index --add --remove path0/COPYING path1/COPYING' + git update-index --add --remove path0/COPYING path1/COPYING' # In the tree, there is only path0/COPYING. In the cache, path0 and # path1 both have COPYING and the latter is a copy of path0/COPYING. # Comparing the full tree with cache should tell us so. -git-diff-index -C --find-copies-harder $tree >current +git diff-index -C --find-copies-harder $tree >current cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100 path0/COPYING path1/COPYING @@ -42,7 +42,7 @@ test_expect_success \ # path1/COPYING suddenly appearing from nowhere, not detected as # a copy from path0/COPYING. -git-diff-index -C $tree path1 >current +git diff-index -C $tree path1 >current cat >expected <<\EOF :000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A path1/COPYING @@ -55,14 +55,14 @@ test_expect_success \ test_expect_success \ 'tweak work tree' \ 'rm -f path0/COPYING && - git-update-index --remove path0/COPYING' + git update-index --remove path0/COPYING' # In the tree, there is only path0/COPYING. In the cache, path0 does # not have COPYING anymore and path1 has COPYING which is a copy of # path0/COPYING. Showing the full tree with cache should tell us about # the rename. -git-diff-index -C $tree >current +git diff-index -C $tree >current cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100 path0/COPYING path1/COPYING @@ -77,7 +77,7 @@ test_expect_success \ # path0/COPYING. When we say we care only about path1, we should just # see path1/COPYING appearing from nowhere. -git-diff-index -C $tree path1 >current +git diff-index -C $tree path1 >current cat >expected <<\EOF :000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A path1/COPYING diff --git a/t/t4008-diff-break-rewrite.sh b/t/t4008-diff-break-rewrite.sh index 263ac1ebf7..5836e3a899 100755 --- a/t/t4008-diff-break-rewrite.sh +++ b/t/t4008-diff-break-rewrite.sh @@ -28,19 +28,19 @@ test_expect_success \ setup \ 'cat ../../README >file0 && cat ../../COPYING >file1 && - git-update-index --add file0 file1 && - tree=$(git-write-tree) && + git update-index --add file0 file1 && + tree=$(git write-tree) && echo "$tree"' test_expect_success \ 'change file1 with copy-edit of file0 and remove file0' \ 'sed -e "s/git/GIT/" file0 >file1 && rm -f file0 && - git-update-index --remove file0 file1' + git update-index --remove file0 file1' test_expect_success \ 'run diff with -B' \ - 'git-diff-index -B --cached "$tree" >current' + 'git diff-index -B --cached "$tree" >current' cat >expected <<\EOF :100644 000000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 0000000000000000000000000000000000000000 D file0 @@ -53,7 +53,7 @@ test_expect_success \ test_expect_success \ 'run diff with -B and -M' \ - 'git-diff-index -B -M "$tree" >current' + 'git diff-index -B -M "$tree" >current' cat >expected <<\EOF :100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 08bb2fb671deff4c03a4d4a0a1315dff98d5732c R100 file0 file1 @@ -66,16 +66,16 @@ test_expect_success \ test_expect_success \ 'swap file0 and file1' \ 'rm -f file0 file1 && - git-read-tree -m $tree && - git-checkout-index -f -u -a && + git read-tree -m $tree && + git checkout-index -f -u -a && mv file0 tmp && mv file1 file0 && mv tmp file1 && - git-update-index file0 file1' + git update-index file0 file1' test_expect_success \ 'run diff with -B' \ - 'git-diff-index -B "$tree" >current' + 'git diff-index -B "$tree" >current' cat >expected <<\EOF :100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 6ff87c4664981e4397625791c8ea3bbb5f2279a3 M100 file0 @@ -88,7 +88,7 @@ test_expect_success \ test_expect_success \ 'run diff with -B and -M' \ - 'git-diff-index -B -M "$tree" >current' + 'git diff-index -B -M "$tree" >current' cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100 file1 file0 @@ -103,11 +103,11 @@ test_expect_success \ 'make file0 into something completely different' \ 'rm -f file0 && ln -s frotz file0 && - git-update-index file0 file1' + git update-index file0 file1' test_expect_success \ 'run diff with -B' \ - 'git-diff-index -B "$tree" >current' + 'git diff-index -B "$tree" >current' cat >expected <<\EOF :100644 120000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 67be421f88824578857624f7b3dc75e99a8a1481 T file0 @@ -120,7 +120,7 @@ test_expect_success \ test_expect_success \ 'run diff with -B' \ - 'git-diff-index -B -M "$tree" >current' + 'git diff-index -B -M "$tree" >current' # This should not mistake file0 as the copy source of new file1 # due to type differences. @@ -135,7 +135,7 @@ test_expect_success \ test_expect_success \ 'run diff with -M' \ - 'git-diff-index -M "$tree" >current' + 'git diff-index -M "$tree" >current' # This should not mistake file0 as the copy source of new file1 # due to type differences. @@ -151,16 +151,16 @@ test_expect_success \ test_expect_success \ 'file1 edited to look like file0 and file0 rename-edited to file2' \ 'rm -f file0 file1 && - git-read-tree -m $tree && - git-checkout-index -f -u -a && + git read-tree -m $tree && + git checkout-index -f -u -a && sed -e "s/git/GIT/" file0 >file1 && sed -e "s/git/GET/" file0 >file2 && rm -f file0 - git-update-index --add --remove file0 file1 file2' + git update-index --add --remove file0 file1 file2' test_expect_success \ 'run diff with -B' \ - 'git-diff-index -B "$tree" >current' + 'git diff-index -B "$tree" >current' cat >expected <<\EOF :100644 000000 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 0000000000000000000000000000000000000000 D file0 @@ -174,7 +174,7 @@ test_expect_success \ test_expect_success \ 'run diff with -B -M' \ - 'git-diff-index -B -M "$tree" >current' + 'git diff-index -B -M "$tree" >current' cat >expected <<\EOF :100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 08bb2fb671deff4c03a4d4a0a1315dff98d5732c C095 file0 file1 diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh index 2f2f8b1216..d2b45e7b8f 100755 --- a/t/t4009-diff-rename-4.sh +++ b/t/t4009-diff-rename-4.sh @@ -13,8 +13,8 @@ test_expect_success \ 'prepare reference tree' \ 'cat ../../COPYING >COPYING && echo frotz >rezrov && - git-update-index --add COPYING rezrov && - tree=$(git-write-tree) && + git update-index --add COPYING rezrov && + tree=$(git write-tree) && echo $tree' test_expect_success \ @@ -22,14 +22,14 @@ test_expect_success \ 'sed -e 's/HOWEVER/However/' COPYING.1 && sed -e 's/GPL/G.P.L/g' COPYING.2 && rm -f COPYING && - git-update-index --add --remove COPYING COPYING.?' + git update-index --add --remove COPYING COPYING.?' # tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2, # both are slightly edited, and unchanged rezrov. We say COPYING.1 # and COPYING.2 are based on COPYING, and do not say anything about # rezrov. -git-diff-index -z -M $tree >current +git diff-index -z -M $tree >current cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 @@ -49,14 +49,14 @@ test_expect_success \ test_expect_success \ 'prepare work tree again' \ 'mv COPYING.2 COPYING && - git-update-index --add --remove COPYING COPYING.1 COPYING.2' + git update-index --add --remove COPYING COPYING.1 COPYING.2' # tree has COPYING and rezrov. work tree has COPYING and COPYING.1, # both are slightly edited, and unchanged rezrov. We say COPYING.1 # is based on COPYING and COPYING is still there, and do not say anything # about rezrov. -git-diff-index -z -C $tree >current +git diff-index -z -C $tree >current cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M COPYING @@ -79,9 +79,9 @@ test_expect_success \ test_expect_success \ 'prepare work tree once again' \ 'cat ../../COPYING >COPYING && - git-update-index --add --remove COPYING COPYING.1' + git update-index --add --remove COPYING COPYING.1' -git-diff-index -z -C --find-copies-harder $tree >current +git diff-index -z -C --find-copies-harder $tree >current cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index 9e1544df9d..ad3d9e4845 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -17,18 +17,18 @@ test_expect_success \ 'echo frotz >file0 && mkdir path1 && echo rezrov >path1/file1 && - git-update-index --add file0 path1/file1 && - tree=`git-write-tree` && + git update-index --add file0 path1/file1 && + tree=`git write-tree` && echo "$tree" && echo nitfol >file0 && echo yomin >path1/file1 && - git-update-index file0 path1/file1' + git update-index file0 path1/file1' cat >expected <<\EOF EOF test_expect_success \ 'limit to path should show nothing' \ - 'git-diff-index --cached $tree -- path >current && + 'git diff-index --cached $tree -- path >current && compare_diff_raw current expected' cat >expected <<\EOF @@ -36,7 +36,7 @@ cat >expected <<\EOF EOF test_expect_success \ 'limit to path1 should show path1/file1' \ - 'git-diff-index --cached $tree -- path1 >current && + 'git diff-index --cached $tree -- path1 >current && compare_diff_raw current expected' cat >expected <<\EOF @@ -44,7 +44,7 @@ cat >expected <<\EOF EOF test_expect_success \ 'limit to path1/ should show path1/file1' \ - 'git-diff-index --cached $tree -- path1/ >current && + 'git diff-index --cached $tree -- path1/ >current && compare_diff_raw current expected' cat >expected <<\EOF @@ -52,14 +52,14 @@ cat >expected <<\EOF EOF test_expect_success \ 'limit to file0 should show file0' \ - 'git-diff-index --cached $tree -- file0 >current && + 'git diff-index --cached $tree -- file0 >current && compare_diff_raw current expected' cat >expected <<\EOF EOF test_expect_success \ 'limit to file0/ should emit nothing.' \ - 'git-diff-index --cached $tree -- file0/ >current && + 'git diff-index --cached $tree -- file0/ >current && compare_diff_raw current expected' test_done diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index 379a831f0b..c6d13693ba 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -23,17 +23,17 @@ EOF test_expect_success \ 'diff new symlink' \ 'ln -s xyzzy frotz && - git-update-index && - tree=$(git-write-tree) && - git-update-index --add frotz && - GIT_DIFF_OPTS=--unified=0 git-diff-index -M -p $tree > current && + git update-index && + tree=$(git write-tree) && + git update-index --add frotz && + GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree > current && compare_diff_patch current expected' test_expect_success \ 'diff unchanged symlink' \ - 'tree=$(git-write-tree) && - git-update-index frotz && - test -z "$(git-diff-index --name-only $tree)"' + 'tree=$(git write-tree) && + git update-index frotz && + test -z "$(git diff-index --name-only $tree)"' cat > expected << EOF diff --git a/frotz b/frotz @@ -49,7 +49,7 @@ EOF test_expect_success \ 'diff removed symlink' \ 'rm frotz && - git-diff-index -M -p $tree > current && + git diff-index -M -p $tree > current && compare_diff_patch current expected' cat > expected << EOF @@ -60,7 +60,7 @@ test_expect_success \ 'diff identical, but newly created symlink' \ 'sleep 3 && ln -s xyzzy frotz && - git-diff-index -M -p $tree > current && + git diff-index -M -p $tree > current && compare_diff_patch current expected' cat > expected << EOF @@ -79,7 +79,7 @@ test_expect_success \ 'diff different symlink' \ 'rm frotz && ln -s yxyyz frotz && - git-diff-index -M -p $tree > current && + git diff-index -M -p $tree > current && compare_diff_patch current expected' test_done diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh index 323606c65c..eced1f30fb 100755 --- a/t/t4012-diff-binary.sh +++ b/t/t4012-diff-binary.sh @@ -10,7 +10,7 @@ test_description='Binary diff and apply test_expect_success 'prepare repository' \ 'echo AIT >a && echo BIT >b && echo CIT >c && echo DIT >d && - git-update-index --add a b c d && + git update-index --add a b c d && echo git >a && cat ../test4012.png >b && echo git >c && @@ -24,18 +24,18 @@ cat > expected <<\EOF 4 files changed, 2 insertions(+), 2 deletions(-) EOF test_expect_success 'diff without --binary' \ - 'git-diff | git-apply --stat --summary >current && + 'git diff | git apply --stat --summary >current && cmp current expected' test_expect_success 'diff with --binary' \ - 'git-diff --binary | git-apply --stat --summary >current && + 'git diff --binary | git apply --stat --summary >current && cmp current expected' # apply needs to be able to skip the binary material correctly # in order to report the line number of a corrupt patch. test_expect_success 'apply detecting corrupt patch correctly' \ - 'git-diff | sed -e 's/-CIT/xCIT/' >broken && - if git-apply --stat --summary broken 2>detected + 'git diff | sed -e 's/-CIT/xCIT/' >broken && + if git apply --stat --summary broken 2>detected then echo unhappy - should have detected an error (exit 1) @@ -48,8 +48,8 @@ test_expect_success 'apply detecting corrupt patch correctly' \ test "$detected" = xCIT' test_expect_success 'apply detecting corrupt patch correctly' \ - 'git-diff --binary | sed -e 's/-CIT/xCIT/' >broken && - if git-apply --stat --summary broken 2>detected + 'git diff --binary | sed -e 's/-CIT/xCIT/' >broken && + if git apply --stat --summary broken 2>detected then echo unhappy - should have detected an error (exit 1) @@ -66,15 +66,15 @@ test_expect_success 'initial commit' 'git-commit -a -m initial' # Try removal (b), modification (d), and creation (e). test_expect_success 'diff-index with --binary' \ 'echo AIT >a && mv b e && echo CIT >c && cat e >d && - git-update-index --add --remove a b c d e && - tree0=`git-write-tree` && - git-diff --cached --binary >current && - git-apply --stat --summary current' + git update-index --add --remove a b c d e && + tree0=`git write-tree` && + git diff --cached --binary >current && + git apply --stat --summary current' test_expect_success 'apply binary patch' \ 'git-reset --hard && - git-apply --binary --index x do @@ -42,13 +42,13 @@ index adf3937..6edc172 100644 +while (0); EOF -git-diff > out +git diff > out test_expect_success "Ray's example without options" 'git diff expect out' -git-diff -w > out +git diff -w > out test_expect_success "Ray's example with -w" 'git diff expect out' -git-diff -b > out +git diff -b > out test_expect_success "Ray's example with -b" 'git diff expect out' tr 'Q' '\015' << EOF > x @@ -60,7 +60,7 @@ unchanged line CR at endQ EOF -git-update-index x +git update-index x cat << EOF > x whitespace at beginning @@ -89,14 +89,14 @@ index d99af23..8b32fb5 100644 -CR at endQ +CR at end EOF -git-diff > out +git diff > out test_expect_success 'another test, without options' 'git diff expect out' cat << EOF > expect diff --git a/x b/x index d99af23..8b32fb5 100644 EOF -git-diff -w > out +git diff -w > out test_expect_success 'another test, with -w' 'git diff expect out' tr 'Q' '\015' << EOF > expect @@ -114,7 +114,7 @@ index d99af23..8b32fb5 100644 unchanged line CR at endQ EOF -git-diff -b > out +git diff -b > out test_expect_success 'another test, with -b' 'git diff expect out' test_done diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh index c23341feb5..435f65b370 100755 --- a/t/t4100-apply-stat.sh +++ b/t/t4100-apply-stat.sh @@ -3,44 +3,44 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply --stat --summary test. +test_description='git apply --stat --summary test. ' . ./test-lib.sh test_expect_success \ 'rename' \ - 'git-apply --stat --summary <../t4100/t-apply-1.patch >current && + 'git apply --stat --summary <../t4100/t-apply-1.patch >current && git diff ../t4100/t-apply-1.expect current' test_expect_success \ 'copy' \ - 'git-apply --stat --summary <../t4100/t-apply-2.patch >current && + 'git apply --stat --summary <../t4100/t-apply-2.patch >current && git diff ../t4100/t-apply-2.expect current' test_expect_success \ 'rewrite' \ - 'git-apply --stat --summary <../t4100/t-apply-3.patch >current && + 'git apply --stat --summary <../t4100/t-apply-3.patch >current && git diff ../t4100/t-apply-3.expect current' test_expect_success \ 'mode' \ - 'git-apply --stat --summary <../t4100/t-apply-4.patch >current && + 'git apply --stat --summary <../t4100/t-apply-4.patch >current && git diff ../t4100/t-apply-4.expect current' test_expect_success \ 'non git' \ - 'git-apply --stat --summary <../t4100/t-apply-5.patch >current && + 'git apply --stat --summary <../t4100/t-apply-5.patch >current && git diff ../t4100/t-apply-5.expect current' test_expect_success \ 'non git' \ - 'git-apply --stat --summary <../t4100/t-apply-6.patch >current && + 'git apply --stat --summary <../t4100/t-apply-6.patch >current && git diff ../t4100/t-apply-6.expect current' test_expect_success \ 'non git' \ - 'git-apply --stat --summary <../t4100/t-apply-7.patch >current && + 'git apply --stat --summary <../t4100/t-apply-7.patch >current && git diff ../t4100/t-apply-7.expect current' test_done diff --git a/t/t4101-apply-nonl.sh b/t/t4101-apply-nonl.sh index 026fac8c55..da8abcf364 100755 --- a/t/t4101-apply-nonl.sh +++ b/t/t4101-apply-nonl.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply should handle files with incomplete lines. +test_description='git apply should handle files with incomplete lines. ' . ./test-lib.sh @@ -23,7 +23,7 @@ do cat frotz.$i >frotz test_expect_success \ "apply diff between $i and $j" \ - "git-apply <../t4101/diff.$i-$j && diff frotz.$j frotz" + "git apply <../t4101/diff.$i-$j && diff frotz.$j frotz" done done diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh index b4662b0364..d42abff1ad 100755 --- a/t/t4102-apply-rename.sh +++ b/t/t4102-apply-rename.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply handling copy/rename patch. +test_description='git apply handling copy/rename patch. ' . ./test-lib.sh @@ -26,10 +26,10 @@ echo 'This is foo' >foo chmod +x foo test_expect_success setup \ - 'git-update-index --add foo' + 'git update-index --add foo' test_expect_success apply \ - 'git-apply --index --stat --summary --apply test-patch' + 'git apply --index --stat --summary --apply test-patch' if [ "$(git config --get core.filemode)" = false ] then @@ -40,7 +40,7 @@ else fi test_expect_success 'apply reverse' \ - 'git-apply -R --index --stat --summary --apply test-patch && + 'git apply -R --index --stat --summary --apply test-patch && test "$(cat foo)" = "This is foo"' cat >test-patch <<\EOF @@ -56,7 +56,7 @@ copy to bar EOF test_expect_success 'apply copy' \ - 'git-apply --index --stat --summary --apply test-patch && + 'git apply --index --stat --summary --apply test-patch && test "$(cat bar)" = "This is bar" -a "$(cat foo)" = "This is foo"' test_done diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index e2b1124c78..011126f336 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply handling binary patches +test_description='git apply handling binary patches ' . ./test-lib.sh @@ -20,55 +20,55 @@ EOF cat file1 >file2 cat file1 >file4 -git-update-index --add --remove file1 file2 file4 +git update-index --add --remove file1 file2 file4 git-commit -m 'Initial Version' 2>/dev/null git-checkout -b binary tr 'x' '\0' file3 cat file3 >file4 -git-add file2 +git add file2 tr '\0' 'v' file1 rm -f file2 -git-update-index --add --remove file1 file2 file3 file4 +git update-index --add --remove file1 file2 file3 file4 git-commit -m 'Second Version' -git-diff-tree -p master binary >B.diff -git-diff-tree -p -C master binary >C.diff +git diff-tree -p master binary >B.diff +git diff-tree -p -C master binary >C.diff -git-diff-tree -p --binary master binary >BF.diff -git-diff-tree -p --binary -C master binary >CF.diff +git diff-tree -p --binary master binary >BF.diff +git diff-tree -p --binary -C master binary >CF.diff test_expect_success 'stat binary diff -- should not fail.' \ 'git-checkout master - git-apply --stat --summary B.diff' + git apply --stat --summary B.diff' test_expect_success 'stat binary diff (copy) -- should not fail.' \ 'git-checkout master - git-apply --stat --summary C.diff' + git apply --stat --summary C.diff' test_expect_failure 'check binary diff -- should fail.' \ 'git-checkout master - git-apply --check B.diff' + git apply --check B.diff' test_expect_failure 'check binary diff (copy) -- should fail.' \ 'git-checkout master - git-apply --check C.diff' + git apply --check C.diff' test_expect_failure 'check incomplete binary diff with replacement -- should fail.' \ 'git-checkout master - git-apply --check --allow-binary-replacement B.diff' + git apply --check --allow-binary-replacement B.diff' test_expect_failure 'check incomplete binary diff with replacement (copy) -- should fail.' \ 'git-checkout master - git-apply --check --allow-binary-replacement C.diff' + git apply --check --allow-binary-replacement C.diff' test_expect_success 'check binary diff with replacement.' \ 'git-checkout master - git-apply --check --allow-binary-replacement BF.diff' + git apply --check --allow-binary-replacement BF.diff' test_expect_success 'check binary diff with replacement (copy).' \ 'git-checkout master - git-apply --check --allow-binary-replacement CF.diff' + git apply --check --allow-binary-replacement CF.diff' # Now we start applying them. @@ -80,36 +80,36 @@ do_reset () { test_expect_failure 'apply binary diff -- should fail.' \ 'do_reset - git-apply B.diff' + git apply B.diff' test_expect_failure 'apply binary diff -- should fail.' \ 'do_reset - git-apply --index B.diff' + git apply --index B.diff' test_expect_failure 'apply binary diff (copy) -- should fail.' \ 'do_reset - git-apply C.diff' + git apply C.diff' test_expect_failure 'apply binary diff (copy) -- should fail.' \ 'do_reset - git-apply --index C.diff' + git apply --index C.diff' test_expect_success 'apply binary diff without replacement.' \ 'do_reset - git-apply BF.diff' + git apply BF.diff' test_expect_success 'apply binary diff without replacement (copy).' \ 'do_reset - git-apply CF.diff' + git apply CF.diff' test_expect_success 'apply binary diff.' \ 'do_reset - git-apply --allow-binary-replacement --index BF.diff && - test -z "$(git-diff --name-status binary)"' + git apply --allow-binary-replacement --index BF.diff && + test -z "$(git diff --name-status binary)"' test_expect_success 'apply binary diff (copy).' \ 'do_reset - git-apply --allow-binary-replacement --index CF.diff && - test -z "$(git-diff --name-status binary)"' + git apply --allow-binary-replacement --index CF.diff && + test -z "$(git diff --name-status binary)"' test_done diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh index a5fb3ea40e..64f34e3298 100755 --- a/t/t4104-apply-boundary.sh +++ b/t/t4104-apply-boundary.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply boundary tests +test_description='git apply boundary tests ' . ./test-lib.sh diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh index 5988e1ae4c..bd40a218cd 100755 --- a/t/t4109-apply-multifrag.sh +++ b/t/t4109-apply-multifrag.sh @@ -4,7 +4,7 @@ # Copyright (c) 2005 Robert Fitzsimons # -test_description='git-apply test patches with multiple fragments. +test_description='git apply test patches with multiple fragments. ' . ./test-lib.sh @@ -138,8 +138,8 @@ diff --git a/main.c b/main.c EOF -test_expect_success "S = git-apply (1)" \ - 'git-apply patch1.patch patch2.patch' +test_expect_success "S = git apply (1)" \ + 'git apply patch1.patch patch2.patch' mv main.c main.c.git test_expect_success "S = patch (1)" \ @@ -150,8 +150,8 @@ test_expect_success "S = cmp (1)" \ rm -f main.c main.c.git -test_expect_success "S = git-apply (2)" \ - 'git-apply patch1.patch patch2.patch patch3.patch' +test_expect_success "S = git apply (2)" \ + 'git apply patch1.patch patch2.patch patch3.patch' mv main.c main.c.git test_expect_success "S = patch (2)" \ @@ -162,8 +162,8 @@ test_expect_success "S = cmp (2)" \ rm -f main.c main.c.git -test_expect_success "S = git-apply (3)" \ - 'git-apply patch1.patch patch4.patch' +test_expect_success "S = git apply (3)" \ + 'git apply patch1.patch patch4.patch' mv main.c main.c.git test_expect_success "S = patch (3)" \ diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh index 9faef0d66e..db60652a37 100755 --- a/t/t4110-apply-scan.sh +++ b/t/t4110-apply-scan.sh @@ -4,7 +4,7 @@ # Copyright (c) 2005 Robert Fitzsimons # -test_description='git-apply test for patches which require scanning forwards and backwards. +test_description='git apply test for patches which require scanning forwards and backwards. ' . ./test-lib.sh @@ -86,8 +86,8 @@ diff --git a/new.txt b/new.txt +c2222 EOF -test_expect_success "S = git-apply scan" \ - 'git-apply patch1.patch patch2.patch patch3.patch patch4.patch patch5.patch' +test_expect_success "S = git apply scan" \ + 'git apply patch1.patch patch2.patch patch3.patch patch4.patch patch5.patch' mv new.txt apply.txt test_expect_success "S = patch scan" \ diff --git a/t/t4112-apply-renames.sh b/t/t4112-apply-renames.sh index 9baf810bee..70a1859503 100755 --- a/t/t4112-apply-renames.sh +++ b/t/t4112-apply-renames.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply should not get confused with rename/copy. +test_description='git apply should not get confused with rename/copy. ' @@ -115,10 +115,10 @@ rename to include/arch/m32r/klibc/archsetjmp.h +#endif /* _KLIBC_ARCHSETJMP_H */ EOF -find klibc -type f -print | xargs git-update-index --add -- +find klibc -type f -print | xargs git update-index --add -- -test_expect_success 'check rename/copy patch' 'git-apply --check patch' +test_expect_success 'check rename/copy patch' 'git apply --check patch' -test_expect_success 'apply rename/copy patch' 'git-apply --index patch' +test_expect_success 'apply rename/copy patch' 'git apply --index patch' test_done diff --git a/t/t4113-apply-ending.sh b/t/t4113-apply-ending.sh index 7fd0cf62ec..1c6bec044a 100755 --- a/t/t4113-apply-ending.sh +++ b/t/t4113-apply-ending.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Catalin Marinas # -test_description='git-apply trying to add an ending line. +test_description='git apply trying to add an ending line. ' . ./test-lib.sh @@ -25,12 +25,12 @@ echo 'b' >>file echo 'c' >>file test_expect_success setup \ - 'git-update-index --add file' + 'git update-index --add file' # test test_expect_failure 'apply at the end' \ - 'git-apply --index test-patch' + 'git apply --index test-patch' cat >test-patch <<\EOF diff a/file b/file @@ -45,9 +45,9 @@ EOF echo >file 'a b c' -git-update-index file +git update-index file test_expect_failure 'apply at the beginning' \ - 'git-apply --index test-patch' + 'git apply --index test-patch' test_done diff --git a/t/t4114-apply-typechange.sh b/t/t4114-apply-typechange.sh index ca81d72157..55334927ab 100755 --- a/t/t4114-apply-typechange.sh +++ b/t/t4114-apply-typechange.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Eric Wong # -test_description='git-apply should not get confused with type changes. +test_description='git apply should not get confused with type changes. ' diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh index b947ed83bb..a07ff42c2f 100755 --- a/t/t4115-apply-symlink.sh +++ b/t/t4115-apply-symlink.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply symlinks and partial files +test_description='git apply symlinks and partial files ' diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh index 2685b22630..a7f5905f1e 100755 --- a/t/t4116-apply-reverse.sh +++ b/t/t4116-apply-reverse.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply in reverse +test_description='git apply in reverse ' diff --git a/t/t4117-apply-reject.sh b/t/t4117-apply-reject.sh index 91931f0e3f..659e17c92e 100755 --- a/t/t4117-apply-reject.sh +++ b/t/t4117-apply-reject.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-apply with rejects +test_description='git apply with rejects ' diff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh index dd88e81e04..1d531caf79 100755 --- a/t/t4118-apply-empty-context.sh +++ b/t/t4118-apply-empty-context.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Junio C Hamano # -test_description='git-apply with new style GNU diff with empty context +test_description='git apply with new style GNU diff with empty context ' diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh index edae7056e4..65571e0549 100755 --- a/t/t4119-apply-config.sh +++ b/t/t4119-apply-config.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Junio C Hamano # -test_description='git-apply --whitespace=strip and configuration file. +test_description='git apply --whitespace=strip and configuration file. ' diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh index 2f672f30d4..83d4ba6798 100755 --- a/t/t4120-apply-popt.sh +++ b/t/t4120-apply-popt.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Shawn O. Pearce # -test_description='git-apply -p handling.' +test_description='git apply -p handling.' . ./test-lib.sh diff --git a/t/t4121-apply-diffs.sh b/t/t4121-apply-diffs.sh index b95b89c341..aff551a1d7 100755 --- a/t/t4121-apply-diffs.sh +++ b/t/t4121-apply-diffs.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-apply for contextually independent diffs' +test_description='git apply for contextually independent diffs' . ./test-lib.sh echo '1 diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index a46d7f74be..71d364ab79 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Johannes E. Schindelin # -test_description='git-rerere +test_description='git rerere ' . ./test-lib.sh diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index a48733cee0..10a5fa9a3a 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Johannes E. Schindelin # -test_description='git-shortlog +test_description='git shortlog ' . ./test-lib.sh diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index a6c5bf6ab4..1a4c53a031 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -3,7 +3,7 @@ # Copyright (C) 2005 Rene Scharfe # -test_description='git-tar-tree and git-get-tar-commit-id test +test_description='git tar-tree and git get-tar-commit-id test This test covers the topics of file contents, commit date handling and commit id embedding: @@ -13,13 +13,13 @@ commit id embedding: binary file (/bin/sh). Only paths shorter than 99 characters are used. - git-tar-tree applies the commit date to every file in the archive it + git tar-tree applies the commit date to every file in the archive it creates. The test sets the commit date to a specific value and checks if the tar archive contains that value. - When giving git-tar-tree a commit id (in contrast to a tree id) it + When giving git tar-tree a commit id (in contrast to a tree id) it embeds this commit id into the tar archive as a comment. The test - checks the ability of git-get-tar-commit-id to figure it out from the + checks the ability of git get-tar-commit-id to figure it out from the tar file. ' @@ -42,23 +42,23 @@ test_expect_success \ test_expect_success \ 'add files to repository' \ - 'find a -type f | xargs git-update-index --add && - find a -type l | xargs git-update-index --add && - treeid=`git-write-tree` && + 'find a -type f | xargs git update-index --add && + find a -type l | xargs git update-index --add && + treeid=`git write-tree` && echo $treeid >treeid && - git-update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE="2005-05-27 22:00:00" \ - git-commit-tree $treeid b.tar' + 'git archive' \ + 'git archive HEAD >b.tar' test_expect_success \ - 'git-tar-tree' \ - 'git-tar-tree HEAD >b2.tar' + 'git tar-tree' \ + 'git tar-tree HEAD >b2.tar' test_expect_success \ - 'git-archive vs. git-tar-tree' \ + 'git archive vs. git tar-tree' \ 'diff b.tar b2.tar' test_expect_success \ @@ -70,9 +70,9 @@ test_expect_success \ diff expected.mtime b.mtime' test_expect_success \ - 'git-get-tar-commit-id' \ - 'git-get-tar-commit-id b.commitid && - diff .git/$(git-symbolic-ref HEAD) b.commitid' + 'git get-tar-commit-id' \ + 'git get-tar-commit-id b.commitid && + diff .git/$(git symbolic-ref HEAD) b.commitid' test_expect_success \ 'extract tar archive' \ @@ -88,8 +88,8 @@ test_expect_success \ 'diff -r a b/a' test_expect_success \ - 'git-tar-tree with prefix' \ - 'git-tar-tree HEAD prefix >c.tar' + 'git tar-tree with prefix' \ + 'git tar-tree HEAD prefix >c.tar' test_expect_success \ 'extract tar archive with prefix' \ @@ -105,8 +105,8 @@ test_expect_success \ 'diff -r a c/prefix/a' test_expect_success \ - 'git-archive --format=zip' \ - 'git-archive --format=zip HEAD >d.zip' + 'git archive --format=zip' \ + 'git archive --format=zip HEAD >d.zip' $UNZIP -v >/dev/null 2>&1 if [ $? -eq 127 ]; then @@ -129,8 +129,8 @@ test_expect_success \ 'diff -r a d/a' test_expect_success \ - 'git-archive --format=zip with prefix' \ - 'git-archive --format=zip --prefix=prefix/ HEAD >e.zip' + 'git archive --format=zip with prefix' \ + 'git archive --format=zip --prefix=prefix/ HEAD >e.zip' test_expect_success \ 'extract ZIP archive with prefix' \ @@ -146,7 +146,7 @@ test_expect_success \ 'diff -r a e/prefix/a' test_expect_success \ - 'git-archive --list outside of a git repo' \ - 'GIT_DIR=some/non-existing/directory git-archive --list' + 'git archive --list outside of a git repo' \ + 'GIT_DIR=some/non-existing/directory git archive --list' test_done diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh index ca96918da2..9b1a74542a 100755 --- a/t/t5100-mailinfo.sh +++ b/t/t5100-mailinfo.sh @@ -3,12 +3,12 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-mailinfo and git-mailsplit test' +test_description='git mailinfo and git mailsplit test' . ./test-lib.sh test_expect_success 'split sample box' \ - 'git-mailsplit -o. ../t5100/sample.mbox >last && + 'git mailsplit -o. ../t5100/sample.mbox >last && last=`cat last` && echo total is $last && test `cat last` = 8' @@ -16,7 +16,7 @@ test_expect_success 'split sample box' \ for mail in `echo 00*` do test_expect_success "mailinfo $mail" \ - "git-mailinfo -u msg$mail patch$mail <$mail >info$mail && + "git mailinfo -u msg$mail patch$mail <$mail >info$mail && echo msg && diff ../t5100/msg$mail msg$mail && echo patch && diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index f336769836..ba7579c251 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -16,26 +16,26 @@ test_expect_success \ for i in a b c do dd if=/dev/zero bs=4k count=1 | tr "\\0" $i >$i && - git-update-index --add $i || return 1 + git update-index --add $i || return 1 done && - cat c >d && echo foo >>d && git-update-index --add d && - tree=`git-write-tree` && - commit=`git-commit-tree $tree d && echo foo >>d && git update-index --add d && + tree=`git write-tree` && + commit=`git commit-tree $tree obj-list && { - git-diff-tree --root -p $commit && + git diff-tree --root -p $commit && while read object do - t=`git-cat-file -t $object` && - git-cat-file $t $object || return 1 + t=`git cat-file -t $object` && + git cat-file $t $object || return 1 done expect' test_expect_success \ 'pack without delta' \ - 'packname_1=$(git-pack-objects --window=0 test-1 current && diff expect current' @@ -154,11 +154,11 @@ test_expect_success \ export GIT_OBJECT_DIRECTORY && rm -f .git2/objects/pack/test-* && cp test-2-${packname_2}.pack test-2-${packname_2}.idx .git2/objects/pack && { - git-diff-tree --root -p $commit && + git diff-tree --root -p $commit && while read object do - t=`git-cat-file -t $object` && - git-cat-file $t $object || return 1 + t=`git cat-file -t $object` && + git cat-file $t $object || return 1 done current && diff expect current' @@ -169,11 +169,11 @@ test_expect_success \ export GIT_OBJECT_DIRECTORY && rm -f .git2/objects/pack/test-* && cp test-3-${packname_3}.pack test-3-${packname_3}.idx .git2/objects/pack && { - git-diff-tree --root -p $commit && + git diff-tree --root -p $commit && while read object do - t=`git-cat-file -t $object` && - git-cat-file $t $object || return 1 + t=`git cat-file -t $object` && + git cat-file $t $object || return 1 done current && diff expect current' @@ -182,7 +182,7 @@ unset GIT_OBJECT_DIRECTORY test_expect_success \ 'verify pack' \ - 'git-verify-pack test-1-${packname_1}.idx \ + 'git verify-pack test-1-${packname_1}.idx \ test-2-${packname_2}.idx \ test-3-${packname_3}.idx' @@ -190,7 +190,7 @@ test_expect_success \ 'corrupt a pack and see if verify catches' \ 'cat test-1-${packname_1}.idx >test-3.idx && cat test-2-${packname_2}.pack >test-3.pack && - if git-verify-pack test-3.idx + if git verify-pack test-3.idx then false else :; fi && @@ -198,7 +198,7 @@ test_expect_success \ : PACK_SIGNATURE && cat test-1-${packname_1}.pack >test-3.pack && dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=2 && - if git-verify-pack test-3.idx + if git verify-pack test-3.idx then false else :; fi && @@ -206,7 +206,7 @@ test_expect_success \ : PACK_VERSION && cat test-1-${packname_1}.pack >test-3.pack && dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=7 && - if git-verify-pack test-3.idx + if git verify-pack test-3.idx then false else :; fi && @@ -214,7 +214,7 @@ test_expect_success \ : TYPE/SIZE byte of the first packed object data && cat test-1-${packname_1}.pack >test-3.pack && dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=12 && - if git-verify-pack test-3.idx + if git verify-pack test-3.idx then false else :; fi && @@ -224,7 +224,7 @@ test_expect_success \ l=`expr $l - 20` && cat test-1-${packname_1}.pack >test-3.pack && dd if=/dev/zero of=test-3.idx count=20 bs=1 conv=notrunc seek=$l && - if git-verify-pack test-3.pack + if git verify-pack test-3.pack then false else :; fi && diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index fce77f1255..073ac0c6f9 100755 --- a/t/t5301-sliding-window.sh +++ b/t/t5301-sliding-window.sh @@ -13,48 +13,48 @@ test_expect_success \ do echo $i >$i && test-genrandom "$i" 32768 >>$i && - git-update-index --add $i || return 1 + git update-index --add $i || return 1 done && - echo d >d && cat c >>d && git-update-index --add d && - tree=`git-write-tree` && - commit1=`git-commit-tree $tree d && cat c >>d && git update-index --add d && + tree=`git write-tree` && + commit1=`git commit-tree $tree file_$i && test-genrandom "$i" 8192 >>file_$i && - git-update-index --add file_$i && + git update-index --add file_$i && i=`expr $i + 1` || return 1 done && { echo 101 && test-genrandom 100 8192; } >file_101 && - git-update-index --add file_101 && - tree=`git-write-tree` && - commit=`git-commit-tree $tree obj-list && - git-update-ref HEAD $commit' + git update-ref HEAD $commit' test_expect_success \ 'pack-objects with index version 1' \ - 'pack1=$(git-pack-objects --index-version=1 test-1 blob_1 && + git cat-file blob "$delta_sha1" > blob_1 && chmod +w ".git/objects/pack/pack-${pack1}.pack" && dd of=".git/objects/pack/pack-${pack1}.pack" seek=$(($delta_offs + 1)) \ if=".git/objects/pack/pack-${pack1}.idx" skip=$((256 * 4 + 4)) \ bs=1 count=20 conv=notrunc && - git-cat-file blob "$delta_sha1" > blob_2 )' + git cat-file blob "$delta_sha1" > blob_2 )' test_expect_failure \ '[index v1] 3) corrupted delta happily returned wrong data' \ @@ -102,37 +102,37 @@ test_expect_failure \ test_expect_failure \ '[index v1] 4) confirm that the pack is actually corrupted' \ - 'git-fsck --full $commit' + 'git fsck --full $commit' test_expect_success \ '[index v1] 5) pack-objects happily reuses corrupted data' \ - 'pack4=$(git-pack-objects test-4 blob_3 && + git cat-file blob "$delta_sha1" > blob_3 && chmod +w ".git/objects/pack/pack-${pack1}.pack" && dd of=".git/objects/pack/pack-${pack1}.pack" seek=$(($delta_offs + 1)) \ if=".git/objects/pack/pack-${pack1}.idx" skip=$((8 + 256 * 4)) \ bs=1 count=20 conv=notrunc && - git-cat-file blob "$delta_sha1" > blob_4 )' + git cat-file blob "$delta_sha1" > blob_4 )' test_expect_failure \ '[index v2] 3) corrupted delta happily returned wrong data' \ @@ -140,10 +140,10 @@ test_expect_failure \ test_expect_failure \ '[index v2] 4) confirm that the pack is actually corrupted' \ - 'git-fsck --full $commit' + 'git fsck --full $commit' test_expect_failure \ '[index v2] 5) pack-objects refuses to reuse corrupted data' \ - 'git-pack-objects test-5 mozart/is/pink && - git-update-index --add mozart/is/pink && - tree=$(git-write-tree) && - commit=$(echo "Commit #0" | git-commit-tree $tree) && + git update-index --add mozart/is/pink && + tree=$(git write-tree) && + commit=$(echo "Commit #0" | git commit-tree $tree) && zero=$commit && parent=$zero && i=0 && @@ -24,18 +24,18 @@ test_expect_success setup ' i=$(($i+1)) && test_tick && echo "Commit #$i" >mozart/is/pink && - git-update-index --add mozart/is/pink && - tree=$(git-write-tree) && - commit=$(echo "Commit #$i" | git-commit-tree $tree -p $parent) && - git-update-ref refs/tags/commit$i $commit && + git update-index --add mozart/is/pink && + tree=$(git write-tree) && + commit=$(echo "Commit #$i" | git commit-tree $tree -p $parent) && + git update-ref refs/tags/commit$i $commit && parent=$commit || return 1 done && - git-update-ref HEAD "$commit" && + git update-ref HEAD "$commit" && git-clone ./. victim && cd victim && - git-log && + git log && cd .. && - git-update-ref HEAD "$zero" && + git update-ref HEAD "$zero" && parent=$zero && i=0 && while test $i -le $cnt @@ -43,15 +43,15 @@ test_expect_success setup ' i=$(($i+1)) && test_tick && echo "Rebase #$i" >mozart/is/pink && - git-update-index --add mozart/is/pink && - tree=$(git-write-tree) && - commit=$(echo "Rebase #$i" | git-commit-tree $tree -p $parent) && - git-update-ref refs/tags/rebase$i $commit && + git update-index --add mozart/is/pink && + tree=$(git write-tree) && + commit=$(echo "Rebase #$i" | git commit-tree $tree -p $parent) && + git update-ref refs/tags/rebase$i $commit && parent=$commit || return 1 done && - git-update-ref HEAD "$commit" && + git update-ref HEAD "$commit" && echo Rebase && - git-log' + git log' test_expect_success 'pack the source repository' ' git repack -a -d && @@ -106,9 +106,9 @@ export HOME ;# this way we force the victim/.git/config to be used. test_expect_success \ 'pushing with --force should be denied with denyNonFastforwards' ' cd victim && - git-config receive.denyNonFastforwards true && + git config receive.denyNonFastforwards true && cd .. && - git-update-ref refs/heads/master master^ || return 1 + git update-ref refs/heads/master master^ || return 1 git-send-pack --force ./victim/.git/ master && return 1 ! git diff .git/refs/heads/master victim/.git/refs/heads/master ' diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh index f1c7ff0c0a..c5dd30d0a4 100755 --- a/t/t5401-update-hooks.sh +++ b/t/t5401-update-hooks.sh @@ -8,19 +8,19 @@ test_description='Test the update hook infrastructure.' test_expect_success setup ' echo This is a test. >a && - git-update-index --add a && - tree0=$(git-write-tree) && - commit0=$(echo setup | git-commit-tree $tree0) && + git update-index --add a && + tree0=$(git write-tree) && + commit0=$(echo setup | git commit-tree $tree0) && echo We hope it works. >a && - git-update-index a && - tree1=$(git-write-tree) && - commit1=$(echo modify | git-commit-tree $tree1 -p $commit0) && - git-update-ref refs/heads/master $commit0 && - git-update-ref refs/heads/tofail $commit1 && + git update-index a && + tree1=$(git write-tree) && + commit1=$(echo modify | git commit-tree $tree1 -p $commit0) && + git update-ref refs/heads/master $commit0 && + git update-ref refs/heads/tofail $commit1 && git-clone ./. victim && - GIT_DIR=victim/.git git-update-ref refs/heads/tofail $commit1 && - git-update-ref refs/heads/master $commit1 && - git-update-ref refs/heads/tofail $commit0 + GIT_DIR=victim/.git git update-ref refs/heads/tofail $commit1 && + git update-ref refs/heads/master $commit1 && + git update-ref refs/heads/tofail $commit0 ' cat >victim/.git/hooks/pre-receive <<'EOF' @@ -65,8 +65,8 @@ test_expect_failure push ' ' test_expect_success 'updated as expected' ' - test $(GIT_DIR=victim/.git git-rev-parse master) = $commit1 && - test $(GIT_DIR=victim/.git git-rev-parse tofail) = $commit1 + test $(GIT_DIR=victim/.git git rev-parse master) = $commit1 && + test $(GIT_DIR=victim/.git git rev-parse tofail) = $commit1 ' test_expect_success 'hooks ran' ' diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 48e3d1705f..7da515361a 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -25,12 +25,12 @@ add () { done echo "$text" > test.txt - git-update-index --add test.txt - tree=$(git-write-tree) + git update-index --add test.txt + tree=$(git write-tree) # make sure timestamps are in correct order sec=$(($sec+1)) commit=$(echo "$text" | GIT_AUTHOR_DATE=$sec \ - git-commit-tree $tree $parents 2>>log2.txt) + git commit-tree $tree $parents 2>>log2.txt) export $name=$commit echo $commit > .git/refs/heads/$branch eval ${branch}TIP=$commit @@ -61,19 +61,19 @@ pull_to_client () { "git-fetch-pack -k -v .. $heads" case "$heads" in *A*) echo $ATIP > .git/refs/heads/A;; esac case "$heads" in *B*) echo $BTIP > .git/refs/heads/B;; esac - git-symbolic-ref HEAD refs/heads/`echo $heads | sed -e 's/^\(.\).*$/\1/'` + git symbolic-ref HEAD refs/heads/`echo $heads | sed -e 's/^\(.\).*$/\1/'` - test_expect_success "fsck" 'git-fsck --full > fsck.txt 2>&1' + test_expect_success "fsck" 'git fsck --full > fsck.txt 2>&1' test_expect_success 'check downloaded results' \ 'mv .git/objects/pack/pack-* . && p=`ls -1 pack-*.pack` && - git-unpack-objects <$p && - git-fsck --full' + git unpack-objects <$p && + git fsck --full' test_expect_success "new object count after $number pull" \ 'idx=`echo pack-*.idx` && - pack_count=`git-show-index <$idx | wc -l` && + pack_count=`git show-index <$idx | wc -l` && test $pack_count = $count' test -z "$pack_count" && pack_count=0 if [ -z "$no_strict_count_check" ]; then @@ -97,7 +97,7 @@ pull_to_client () { ( mkdir client && cd client && - git-init 2>> log2.txt && + git init 2>> log2.txt && git config transfer.unpacklimit 0 ) @@ -113,7 +113,7 @@ add B1 $A1 echo $ATIP > .git/refs/heads/A echo $BTIP > .git/refs/heads/B -git-symbolic-ref HEAD refs/heads/B +git symbolic-ref HEAD refs/heads/B pull_to_client 1st "B A" $((11*3)) @@ -131,7 +131,7 @@ pull_to_client 3rd "A" $((1*3)) # old fails test_expect_success "clone shallow" "git-clone --depth 2 . shallow" -(cd shallow; git-count-objects -v) > count.shallow +(cd shallow; git count-objects -v) > count.shallow test_expect_success "clone shallow object count" \ "test \"in-pack: 18\" = \"$(grep in-pack count.shallow)\"" @@ -145,7 +145,7 @@ test_expect_success "clone shallow object count (part 2)" ' ' test_expect_success "fsck in shallow repo" \ - "(cd shallow; git-fsck --full)" + "(cd shallow; git fsck --full)" #test_done; exit @@ -155,7 +155,7 @@ add B67 $B66 test_expect_success "pull in shallow repo" \ "(cd shallow; git pull .. B)" -(cd shallow; git-count-objects -v) > count.shallow +(cd shallow; git count-objects -v) > count.shallow test_expect_success "clone shallow object count" \ "test \"count: 6\" = \"$(grep count count.shallow)\"" @@ -165,14 +165,14 @@ add B69 $B68 test_expect_success "deepening pull in shallow repo" \ "(cd shallow; git pull --depth 4 .. B)" -(cd shallow; git-count-objects -v) > count.shallow +(cd shallow; git count-objects -v) > count.shallow test_expect_success "clone shallow object count" \ "test \"count: 12\" = \"$(grep count count.shallow)\"" test_expect_success "deepening fetch in shallow repo" \ "(cd shallow; git fetch --depth 4 .. A:A)" -(cd shallow; git-count-objects -v) > count.shallow +(cd shallow; git count-objects -v) > count.shallow test_expect_success "clone shallow object count" \ "test \"count: 18\" = \"$(grep count count.shallow)\"" diff --git a/t/t6000lib.sh b/t/t6000lib.sh index d548bf8026..180633e1e0 100755 --- a/t/t6000lib.sh +++ b/t/t6000lib.sh @@ -17,7 +17,7 @@ unique_commit() _text=$1 _tree=$2 shift 2 - echo $_text | git-commit-tree $(tag $_tree) "$@" + echo $_text | git commit-tree $(tag $_tree) "$@" } # Save the output of a command into the tag specified. Prepend @@ -62,7 +62,7 @@ as_author() commit_date() { _commit=$1 - git-cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p" + git cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p" } on_committer_date() diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh index 71cbb72e1b..8f5de097ec 100755 --- a/t/t6002-rev-list-bisect.sh +++ b/t/t6002-rev-list-bisect.sh @@ -2,7 +2,7 @@ # # Copyright (c) 2005 Jon Seymour # -test_description='Tests git-rev-list --bisect functionality' +test_description='Tests git rev-list --bisect functionality' . ./test-lib.sh . ../t6000lib.sh # t6xxx specific functions @@ -16,11 +16,11 @@ test_bisection_diff() _max_diff=$1 _bisect_option=$2 shift 2 - _bisection=$(git-rev-list $_bisect_option "$@") - _list_size=$(git-rev-list "$@" | wc -l) + _bisection=$(git rev-list $_bisect_option "$@") + _list_size=$(git rev-list "$@" | wc -l) _head=$1 shift 1 - _bisection_size=$(git-rev-list $_bisection "$@" | wc -l) + _bisection_size=$(git rev-list $_bisection "$@" | wc -l) [ -n "$_list_size" -a -n "$_bisection_size" ] || error "test_bisection_diff failed" @@ -37,8 +37,8 @@ test_bisection_diff() } date >path0 -git-update-index --add path0 -save_tag tree git-write-tree +git update-index --add path0 +save_tag tree git write-tree on_committer_date "1971-08-16 00:00:00" hide_error save_tag root unique_commit root tree on_committer_date "1971-08-16 00:00:01" save_tag l0 unique_commit l0 tree -p root on_committer_date "1971-08-16 00:00:02" save_tag l1 unique_commit l1 tree -p l0 @@ -58,7 +58,7 @@ on_committer_date "1971-08-16 00:00:15" save_tag a4 unique_commit a4 tree -p a3 on_committer_date "1971-08-16 00:00:16" save_tag l3 unique_commit l3 tree -p a4 on_committer_date "1971-08-16 00:00:17" save_tag l4 unique_commit l4 tree -p l3 on_committer_date "1971-08-16 00:00:18" save_tag l5 unique_commit l5 tree -p l4 -git-update-ref HEAD $(tag l5) +git update-ref HEAD $(tag l5) # E @@ -163,23 +163,23 @@ test_sequence() # the bisection point is the head - this is the bad point. # -test_output_expect_success "$_bisect_option l5 ^root" 'git-rev-list $_bisect_option l5 ^root' <path0 -git-update-index --add path0 -save_tag tree git-write-tree +git update-index --add path0 +save_tag tree git write-tree on_committer_date "1971-08-16 00:00:00" hide_error save_tag root unique_commit root tree on_committer_date "1971-08-16 00:00:01" save_tag l0 unique_commit l0 tree -p root on_committer_date "1971-08-16 00:00:02" save_tag l1 unique_commit l1 tree -p l0 @@ -77,13 +77,13 @@ save_tag h2 unique_commit g4 tree -p g2 save_tag g3 unique_commit g5 tree -p g2 save_tag g4 unique_commit g6 tree -p g3 -p h2 -git-update-ref HEAD $(tag l5) +git update-ref HEAD $(tag l5) -test_output_expect_success 'rev-list has correct number of entries' 'git-rev-list HEAD | wc -l | tr -d \" \"' <foo && git-commit -a -m "changed foo" ' @@ -14,8 +14,8 @@ touch foo && git-add foo && git-commit -m "added foo" && test_format() { cat >expect.$1 test_expect_success "format $1" " -git-rev-list --pretty=format:$2 master >output.$1 && -git-diff expect.$1 output.$1 +git rev-list --pretty=format:$2 master >output.$1 && +git diff expect.$1 output.$1 " } @@ -113,7 +113,7 @@ and it will be encoded in iso8859-1. We should therefore include an iso8859 character: ¡bueno! EOF test_expect_success 'setup complex body' ' -git-config i18n.commitencoding iso8859-1 && +git config i18n.commitencoding iso8859-1 && echo change2 >foo && git-commit -a -F commit-msg ' diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh index 22e0893056..96f3d35530 100755 --- a/t/t6010-merge-base.sh +++ b/t/t6010-merge-base.sh @@ -8,7 +8,7 @@ test_description='Merge base computation. . ./test-lib.sh -T=$(git-write-tree) +T=$(git write-tree) M=1130000000 Z=+0000 @@ -29,7 +29,7 @@ doit() { GIT_COMMITTER_DATE="$(($M + $OFFSET)) $Z" GIT_AUTHOR_DATE=$GIT_COMMITTER_DATE export GIT_COMMITTER_DATE GIT_AUTHOR_DATE - commit=$(echo $NAME | git-commit-tree $T $PARENTS) + commit=$(echo $NAME | git commit-tree $T $PARENTS) echo $commit >.git/refs/tags/$NAME echo $commit } @@ -51,16 +51,16 @@ G=$(doit 7 G $B $E) H=$(doit 8 H $A $F) test_expect_success 'compute merge-base (single)' \ - 'MB=$(git-merge-base G H) && - expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/B"' + 'MB=$(git merge-base G H) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' test_expect_success 'compute merge-base (all)' \ - 'MB=$(git-merge-base --all G H) && - expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/B"' + 'MB=$(git merge-base --all G H) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' test_expect_success 'compute merge-base with show-branch' \ - 'MB=$(git-show-branch --merge-base G H) && - expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/B"' + 'MB=$(git show-branch --merge-base G H) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/B"' # Setup for second test to demonstrate that relying on timestamps in a # distributed SCM to provide a _consistent_ partial ordering of commits @@ -100,11 +100,11 @@ PL=$(doit 4 PL $L2 $C2) PR=$(doit 4 PR $C2 $R2) test_expect_success 'compute merge-base (single)' \ - 'MB=$(git-merge-base PL PR) && - expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/C2"' + 'MB=$(git merge-base PL PR) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/C2"' test_expect_success 'compute merge-base (all)' \ - 'MB=$(git-merge-base --all PL PR) && - expr "$(git-name-rev "$MB")" : "[0-9a-f]* tags/C2"' + 'MB=$(git merge-base --all PL PR) && + expr "$(git name-rev "$MB")" : "[0-9a-f]* tags/C2"' test_done diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh index ecc11c1a84..ae3b6f2831 100755 --- a/t/t6023-merge-file.sh +++ b/t/t6023-merge-file.sh @@ -56,18 +56,18 @@ printf "propter nomen suum." >> new4.txt cp new1.txt test.txt test_expect_success "merge without conflict" \ - "git-merge-file test.txt orig.txt new2.txt" + "git merge-file test.txt orig.txt new2.txt" cp new1.txt test2.txt test_expect_success "merge without conflict (missing LF at EOF)" \ - "git-merge-file test2.txt orig.txt new2.txt" + "git merge-file test2.txt orig.txt new2.txt" test_expect_success "merge result added missing LF" \ "git diff test.txt test2.txt" cp test.txt backup.txt test_expect_failure "merge with conflicts" \ - "git-merge-file test.txt orig.txt new3.txt" + "git merge-file test.txt orig.txt new3.txt" cat > expect.txt << EOF <<<<<<< test.txt @@ -90,7 +90,7 @@ test_expect_success "expected conflict markers" "git diff test.txt expect.txt" cp backup.txt test.txt test_expect_failure "merge with conflicts, using -L" \ - "git-merge-file -L 1 -L 2 test.txt orig.txt new3.txt" + "git merge-file -L 1 -L 2 test.txt orig.txt new3.txt" cat > expect.txt << EOF <<<<<<< 1 @@ -114,7 +114,7 @@ test_expect_success "expected conflict markers, with -L" \ sed "s/ tu / TU /" < new1.txt > new5.txt test_expect_failure "conflict in removed tail" \ - "git-merge-file -p orig.txt new1.txt new5.txt > out" + "git merge-file -p orig.txt new1.txt new5.txt > out" cat > expect << EOF Dominus regit me, diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh index 058db9cc52..c154f03cf5 100755 --- a/t/t6024-recursive-merge.sh +++ b/t/t6024-recursive-merge.sh @@ -28,7 +28,7 @@ echo B > a1 && GIT_AUTHOR_DATE="2006-12-12 23:00:02" git commit -m B a1 && git checkout -b D A && -git-rev-parse B > .git/MERGE_HEAD && +git rev-parse B > .git/MERGE_HEAD && echo D > a1 && git update-index a1 && GIT_AUTHOR_DATE="2006-12-12 23:00:03" git commit -m D && @@ -42,19 +42,19 @@ echo C > a1 && GIT_AUTHOR_DATE="2006-12-12 23:00:05" git commit -m C a1 && git checkout -b E C && -git-rev-parse B > .git/MERGE_HEAD && +git rev-parse B > .git/MERGE_HEAD && echo E > a1 && git update-index a1 && GIT_AUTHOR_DATE="2006-12-12 23:00:06" git commit -m E && git checkout -b G E && -git-rev-parse A > .git/MERGE_HEAD && +git rev-parse A > .git/MERGE_HEAD && echo G > a1 && git update-index a1 && GIT_AUTHOR_DATE="2006-12-12 23:00:07" git commit -m G && git checkout -b F D && -git-rev-parse C > .git/MERGE_HEAD && +git rev-parse C > .git/MERGE_HEAD && echo F > a1 && git update-index a1 && GIT_AUTHOR_DATE="2006-12-12 23:00:08" git commit -m F diff --git a/t/t6025-merge-symlinks.sh b/t/t6025-merge-symlinks.sh index 3c1a6972bd..950c2e9b63 100755 --- a/t/t6025-merge-symlinks.sh +++ b/t/t6025-merge-symlinks.sh @@ -12,22 +12,22 @@ if core.symlinks is false.' test_expect_success \ 'setup' ' -git-config core.symlinks false && +git config core.symlinks false && > file && -git-add file && +git add file && git-commit -m initial && -git-branch b-symlink && -git-branch b-file && +git branch b-symlink && +git branch b-file && l=$(echo -n file | git-hash-object -t blob -w --stdin) && -echo "120000 $l symlink" | git-update-index --index-info && +echo "120000 $l symlink" | git update-index --index-info && git-commit -m master && git-checkout b-symlink && l=$(echo -n file-different | git-hash-object -t blob -w --stdin) && -echo "120000 $l symlink" | git-update-index --index-info && +echo "120000 $l symlink" | git update-index --index-info && git-commit -m b-symlink && git-checkout b-file && echo plain-file > symlink && -git-add symlink && +git add symlink && git-commit -m b-file' test_expect_failure \ diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index dd6cc3a55c..0724864e56 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -3,31 +3,31 @@ # Copyright (c) 2005 Johannes Schindelin # -test_description='Test git-rev-parse with different parent options' +test_description='Test git rev-parse with different parent options' . ./test-lib.sh . ../t6000lib.sh # t6xxx specific functions date >path0 -git-update-index --add path0 -save_tag tree git-write-tree +git update-index --add path0 +save_tag tree git write-tree hide_error save_tag start unique_commit "start" tree save_tag second unique_commit "second" tree -p start hide_error save_tag start2 unique_commit "start2" tree save_tag two_parents unique_commit "next" tree -p second -p start2 save_tag final unique_commit "final" tree -p two_parents -test_expect_success 'start is valid' 'git-rev-parse start | grep "^[0-9a-f]\{40\}$"' -test_expect_success 'start^0' "test $(cat .git/refs/tags/start) = $(git-rev-parse start^0)" -test_expect_success 'start^1 not valid' "if git-rev-parse --verify start^1; then false; else :; fi" -test_expect_success 'second^1 = second^' "test $(git-rev-parse second^1) = $(git-rev-parse second^)" -test_expect_success 'final^1^1^1' "test $(git-rev-parse start) = $(git-rev-parse final^1^1^1)" -test_expect_success 'final^1^1^1 = final^^^' "test $(git-rev-parse final^1^1^1) = $(git-rev-parse final^^^)" -test_expect_success 'final^1^2' "test $(git-rev-parse start2) = $(git-rev-parse final^1^2)" -test_expect_success 'final^1^2 != final^1^1' "test $(git-rev-parse final^1^2) != $(git-rev-parse final^1^1)" -test_expect_success 'final^1^3 not valid' "if git-rev-parse --verify final^1^3; then false; else :; fi" -test_expect_failure '--verify start2^1' 'git-rev-parse --verify start2^1' -test_expect_success '--verify start2^0' 'git-rev-parse --verify start2^0' +test_expect_success 'start is valid' 'git rev-parse start | grep "^[0-9a-f]\{40\}$"' +test_expect_success 'start^0' "test $(cat .git/refs/tags/start) = $(git rev-parse start^0)" +test_expect_success 'start^1 not valid' "if git rev-parse --verify start^1; then false; else :; fi" +test_expect_success 'second^1 = second^' "test $(git rev-parse second^1) = $(git rev-parse second^)" +test_expect_success 'final^1^1^1' "test $(git rev-parse start) = $(git rev-parse final^1^1^1)" +test_expect_success 'final^1^1^1 = final^^^' "test $(git rev-parse final^1^1^1) = $(git rev-parse final^^^)" +test_expect_success 'final^1^2' "test $(git rev-parse start2) = $(git rev-parse final^1^2)" +test_expect_success 'final^1^2 != final^1^1' "test $(git rev-parse final^1^2) != $(git rev-parse final^1^1)" +test_expect_success 'final^1^3 not valid' "if git rev-parse --verify final^1^3; then false; else :; fi" +test_expect_failure '--verify start2^1' 'git rev-parse --verify start2^1' +test_expect_success '--verify start2^0' 'git rev-parse --verify start2^0' test_expect_success 'repack for next test' 'git repack -a -d' test_expect_success 'short SHA-1 works' ' diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 3e9edda1ca..ae8ee11183 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -28,39 +28,39 @@ check_describe () { test_expect_success setup ' test_tick && - echo one >file && git-add file && git-commit -m initial && - one=$(git-rev-parse HEAD) && + echo one >file && git add file && git-commit -m initial && + one=$(git rev-parse HEAD) && test_tick && - echo two >file && git-add file && git-commit -m second && - two=$(git-rev-parse HEAD) && + echo two >file && git add file && git-commit -m second && + two=$(git rev-parse HEAD) && test_tick && - echo three >file && git-add file && git-commit -m third && + echo three >file && git add file && git-commit -m third && test_tick && - echo A >file && git-add file && git-commit -m A && + echo A >file && git add file && git-commit -m A && test_tick && git-tag -a -m A A && test_tick && - echo c >file && git-add file && git-commit -m c && + echo c >file && git add file && git-commit -m c && test_tick && git-tag c && git reset --hard $two && test_tick && - echo B >side && git-add side && git-commit -m B && + echo B >side && git add side && git-commit -m B && test_tick && git-tag -a -m B B && test_tick && git-merge -m Merged c && - merged=$(git-rev-parse HEAD) && + merged=$(git rev-parse HEAD) && git reset --hard $two && test_tick && - echo D >another && git-add another && git-commit -m D && + echo D >another && git add another && git-commit -m D && test_tick && git-tag -a -m D D && @@ -77,7 +77,7 @@ test_expect_success setup ' git-merge -m Merged $merged && test_tick && - echo X >file && echo X >side && git-add file side && + echo X >file && echo X >side && git add file side && git-commit -m x ' diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 344033249c..8b43fb5a27 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -1,18 +1,18 @@ #!/bin/sh -test_description='git-mv in subdirs' +test_description='git mv in subdirs' . ./test-lib.sh test_expect_success \ 'prepare reference tree' \ 'mkdir path0 path1 && cp ../../COPYING path0/COPYING && - git-add path0/COPYING && + git add path0/COPYING && git-commit -m add -a' test_expect_success \ 'moving the file out of subdirectory' \ - 'cd path0 && git-mv COPYING ../path1/COPYING' + 'cd path0 && git mv COPYING ../path1/COPYING' # in path0 currently test_expect_success \ @@ -21,12 +21,12 @@ test_expect_success \ test_expect_success \ 'checking the commit' \ - 'git-diff-tree -r -M --name-status HEAD^ HEAD | \ + 'git diff-tree -r -M --name-status HEAD^ HEAD | \ grep -E "^R100.+path0/COPYING.+path1/COPYING"' test_expect_success \ 'moving the file back into subdirectory' \ - 'cd path0 && git-mv ../path1/COPYING COPYING' + 'cd path0 && git mv ../path1/COPYING COPYING' # in path0 currently test_expect_success \ @@ -35,18 +35,18 @@ test_expect_success \ test_expect_success \ 'checking the commit' \ - 'git-diff-tree -r -M --name-status HEAD^ HEAD | \ + 'git diff-tree -r -M --name-status HEAD^ HEAD | \ grep -E "^R100.+path1/COPYING.+path0/COPYING"' test_expect_success \ 'adding another file' \ 'cp ../../README path0/README && - git-add path0/README && + git add path0/README && git-commit -m add2 -a' test_expect_success \ 'moving whole subdirectory' \ - 'git-mv path0 path2' + 'git mv path0 path2' test_expect_success \ 'commiting the change' \ @@ -54,18 +54,18 @@ test_expect_success \ test_expect_success \ 'checking the commit' \ - 'git-diff-tree -r -M --name-status HEAD^ HEAD | \ + 'git diff-tree -r -M --name-status HEAD^ HEAD | \ grep -E "^R100.+path0/COPYING.+path2/COPYING" && - git-diff-tree -r -M --name-status HEAD^ HEAD | \ + git diff-tree -r -M --name-status HEAD^ HEAD | \ grep -E "^R100.+path0/README.+path2/README"' test_expect_success \ 'succeed when source is a prefix of destination' \ - 'git-mv path2/COPYING path2/COPYING-renamed' + 'git mv path2/COPYING path2/COPYING-renamed' test_expect_success \ 'moving whole subdirectory into subdirectory' \ - 'git-mv path2 path1' + 'git mv path2 path1' test_expect_success \ 'commiting the change' \ @@ -73,18 +73,18 @@ test_expect_success \ test_expect_success \ 'checking the commit' \ - 'git-diff-tree -r -M --name-status HEAD^ HEAD | \ + 'git diff-tree -r -M --name-status HEAD^ HEAD | \ grep -E "^R100.+path2/COPYING.+path1/path2/COPYING" && - git-diff-tree -r -M --name-status HEAD^ HEAD | \ + git diff-tree -r -M --name-status HEAD^ HEAD | \ grep -E "^R100.+path2/README.+path1/path2/README"' test_expect_failure \ 'do not move directory over existing directory' \ - 'mkdir path0 && mkdir path0/path2 && git-mv path2 path0' + 'mkdir path0 && mkdir path0/path2 && git mv path2 path0' test_expect_success \ 'move into "."' \ - 'git-mv path1/path2/ .' + 'git mv path1/path2/ .' test_expect_success "Michael Cassar's test case" ' rm -fr .git papers partA && diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index f00c262e45..21f9bc5dd6 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -27,14 +27,14 @@ test_expect_success 'setup' ' make_commit H ' -H=$(git-rev-parse H) +H=$(git rev-parse H) test_expect_success 'rewrite identically' ' git-filter-branch H2 ' test_expect_success 'result is really identical' ' - test $H = $(git-rev-parse H2) + test $H = $(git rev-parse H2) ' test_expect_success 'rewrite, renaming a specific file' ' @@ -51,7 +51,7 @@ test_expect_success 'rewrite one branch, keeping a side branch' ' ' test_expect_success 'common ancestor is still common (unchanged)' ' - test "$(git-merge-base modD D)" = "$(git-rev-parse B)" + test "$(git merge-base modD D)" = "$(git rev-parse B)" ' test_expect_success 'filter subdirectory only' ' @@ -73,7 +73,7 @@ test_expect_success 'filter subdirectory only' ' ' test_expect_success 'subdirectory filter result looks okay' ' - test 2 = $(git-rev-list sub | wc -l) && + test 2 = $(git rev-list sub | wc -l) && git show sub:new && ! git show sub:subdir ' @@ -93,7 +93,7 @@ test_expect_success 'setup and filter history that requires --full-history' ' ' test_expect_success 'subdirectory filter result looks okay' ' - test 3 = $(git-rev-list -1 --parents sub-master | wc -w) && + test 3 = $(git rev-list -1 --parents sub-master | wc -w) && git show sub-master^:new && git show sub-master^2:new && ! git show sub:subdir @@ -101,9 +101,9 @@ test_expect_success 'subdirectory filter result looks okay' ' test_expect_success 'use index-filter to move into a subdirectory' ' git-filter-branch --index-filter \ - "git-ls-files -s | sed \"s-\\t-&newsubdir/-\" | + "git ls-files -s | sed \"s-\\t-&newsubdir/-\" | GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \ - git-update-index --index-info && + git update-index --index-info && mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved && test -z "$(git diff HEAD directorymoved:newsubdir)"' diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 5d15449be5..a845930404 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -176,7 +176,7 @@ EOF test_expect_success \ 'listing tags with substring as pattern must print those matching' ' git-tag -l a > actual && - git-diff expect actual + git diff expect actual ' cat >expect < actual && - git-diff expect actual + git diff expect actual ' cat >expect < actual && - git-diff expect actual + git diff expect actual ' cat >expect < actual && - git-diff expect actual + git diff expect actual ' cat >expect < actual && - git-diff expect actual + git diff expect actual ' cat >expect < actual && - git-diff expect actual + git diff expect actual ' >expect test_expect_success \ 'listing tags using v.* should print nothing because none have v.' ' git-tag -l "v.*" > actual && - git-diff expect actual + git diff expect actual ' cat >expect < actual && - git-diff expect actual + git diff expect actual ' # creating and verifying lightweight tags: @@ -253,8 +253,8 @@ test_expect_success \ test_expect_success \ 'a non-annotated tag created without parameters should point to HEAD' ' git-tag non-annotated-tag && - test $(git-cat-file -t non-annotated-tag) = commit && - test $(git-rev-parse non-annotated-tag) = $(git-rev-parse HEAD) + test $(git cat-file -t non-annotated-tag) = commit && + test $(git rev-parse non-annotated-tag) = $(git rev-parse HEAD) ' test_expect_failure 'trying to verify an unknown tag should fail' \ @@ -475,7 +475,7 @@ echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success 'creating a signed tag with -m message should succeed' ' git-tag -s -m "A signed tag message" signed-tag && get_tag_msg signed-tag >actual && - git-diff expect actual + git diff expect actual ' test_expect_success 'verifying a signed tag should succeed' \ diff --git a/t/t7101-reset.sh b/t/t7101-reset.sh index a9191407f2..66d40430b2 100755 --- a/t/t7101-reset.sh +++ b/t/t7101-reset.sh @@ -10,7 +10,7 @@ test_expect_success \ 'creating initial files' \ 'mkdir path0 && cp ../../COPYING path0/COPYING && - git-add path0/COPYING && + git add path0/COPYING && git-commit -m add -a' test_expect_success \ @@ -21,10 +21,10 @@ test_expect_success \ cp ../../COPYING path1/COPYING && cp ../../COPYING COPYING && cp ../../COPYING path0/COPYING-TOO && - git-add path1/path2/COPYING && - git-add path1/COPYING && - git-add COPYING && - git-add path0/COPYING-TOO && + git add path1/path2/COPYING && + git add path1/COPYING && + git add COPYING && + git add path0/COPYING-TOO && git-commit -m change -a' test_expect_success \ diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index de70b38d1c..eb0847afe9 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -13,10 +13,10 @@ test_expect_success 'setup' ' touch src/part1.c Makefile && echo build >.gitignore && echo \*.o >>.gitignore && - git-add . && + git add . && git-commit -m setup && touch src/part2.c README && - git-add . + git add . ' @@ -141,7 +141,7 @@ test_expect_success 'git-clean -d -X' ' test_expect_success 'clean.requireForce' ' - git-config clean.requireForce true && + git config clean.requireForce true && ! git-clean ' diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 7a9b505b13..5e91db64e9 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -23,24 +23,24 @@ subcommands of git-submodule. test_expect_success 'Prepare submodule testing' ' mkdir lib && cd lib && - git-init && + git init && echo a >a && - git-add a && + git add a && git-commit -m "submodule commit 1" && git-tag -a -m "rev-1" rev-1 && - rev1=$(git-rev-parse HEAD) && + rev1=$(git rev-parse HEAD) && if test -z "$rev1" then - echo "[OOPS] submodule git-rev-parse returned nothing" + echo "[OOPS] submodule git rev-parse returned nothing" false fi && cd .. && echo a >a && echo z >z && - git-add a lib z && + git add a lib z && git-commit -m "super commit 1" && mv lib .subrepo && - GIT_CONFIG=.gitmodules git-config submodule.example.url git://example.com/lib.git + GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/lib.git ' test_expect_success 'status should fail for unmapped paths' ' @@ -48,9 +48,9 @@ test_expect_success 'status should fail for unmapped paths' ' then echo "[OOPS] submodule status succeeded" false - elif ! GIT_CONFIG=.gitmodules git-config submodule.example.path lib + elif ! GIT_CONFIG=.gitmodules git config submodule.example.path lib then - echo "[OOPS] git-config failed to update .gitmodules" + echo "[OOPS] git config failed to update .gitmodules" false fi ' @@ -66,12 +66,12 @@ test_expect_success 'status should initially be "missing"' ' test_expect_success 'init should register submodule url in .git/config' ' git-submodule init && - url=$(git-config submodule.example.url) && + url=$(git config submodule.example.url) && if test "$url" != "git://example.com/lib.git" then echo "[OOPS] init succeeded but submodule url is wrong" false - elif ! git-config submodule.example.url ./.subrepo + elif ! git config submodule.example.url ./.subrepo then echo "[OOPS] init succeeded but update of url failed" false @@ -113,7 +113,7 @@ test_expect_success 'update should work when path is an empty dir' ' rm -rf lib && mkdir lib && git-submodule update && - head=$(cd lib && git-rev-parse HEAD) && + head=$(cd lib && git rev-parse HEAD) && if test -z "$head" then echo "[OOPS] Failed to obtain submodule head" @@ -132,13 +132,13 @@ test_expect_success 'status should be "up-to-date" after update' ' test_expect_success 'status should be "modified" after submodule commit' ' cd lib && echo b >b && - git-add b && + git add b && git-commit -m "submodule commit 2" && - rev2=$(git-rev-parse HEAD) && + rev2=$(git rev-parse HEAD) && cd .. && if test -z "$rev2" then - echo "[OOPS] submodule git-rev-parse returned nothing" + echo "[OOPS] submodule git rev-parse returned nothing" false fi && git-submodule status | grep "^+$rev2" @@ -150,10 +150,10 @@ test_expect_success 'the --cached sha1 should be rev1' ' test_expect_success 'update should checkout rev1' ' git-submodule update && - head=$(cd lib && git-rev-parse HEAD) && + head=$(cd lib && git rev-parse HEAD) && if test -z "$head" then - echo "[OOPS] submodule git-rev-parse returned nothing" + echo "[OOPS] submodule git rev-parse returned nothing" false elif test "$head" != "$rev1" then diff --git a/t/t8001-annotate.sh b/t/t8001-annotate.sh index 3a6490e8f8..eabec2e06e 100755 --- a/t/t8001-annotate.sh +++ b/t/t8001-annotate.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-annotate' +test_description='git annotate' . ./test-lib.sh PROG='git annotate' diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh index 9777393996..92ece30fa9 100755 --- a/t/t8002-blame.sh +++ b/t/t8002-blame.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-blame' +test_description='git blame' . ./test-lib.sh PROG='git blame -c' diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index 70c3669ee8..614cf50d19 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -86,10 +86,10 @@ test_expect_failure "$name" " rm -f '$GIT_DIR'/index && git checkout -f -b mybranch3 remotes/git-svn && rm bar/zzz && - git-update-index --remove bar/zzz && + git update-index --remove bar/zzz && mkdir bar/zzz && echo yyy > bar/zzz/yyy && - git-update-index --add bar/zzz/yyy && + git update-index --add bar/zzz/yyy && git commit -m '$name' && git-svn set-tree --find-copies-harder --rmdir \ remotes/git-svn..mybranch3" || true @@ -191,8 +191,8 @@ GIT_SVN_ID=alt export GIT_SVN_ID test_expect_success "$name" \ "git-svn init $svnrepo && git-svn fetch && - git-rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a && - git-rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b && + git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a && + git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b && git diff a b" name='check imported tree checksums expected tree checksums' @@ -214,7 +214,7 @@ EOF test_expect_success "$name" "git diff a expected" test_expect_failure 'exit if remote refs are ambigious' " - git-config --add svn-remote.svn.fetch \ + git config --add svn-remote.svn.fetch \ bar:refs/remotes/git-svn && git-svn migrate " @@ -222,7 +222,7 @@ test_expect_failure 'exit if remote refs are ambigious' " test_expect_failure 'exit if init-ing a would clobber a URL' " svnadmin create ${PWD}/svnrepo2 && svn mkdir -m 'mkdir bar' ${svnrepo}2/bar && - git-config --unset svn-remote.svn.fetch \ + git config --unset svn-remote.svn.fetch \ '^bar:refs/remotes/git-svn$' && git-svn init ${svnrepo}2/bar " diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index 35aa45cb9a..d8f9cab35d 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -30,31 +30,31 @@ test_expect_success 'initialize repo' " test_expect_success 'init and fetch a moved directory' " git-svn init --minimize-url -i thunk $svnrepo/thunk && git-svn fetch -i thunk && - test \"\`git-rev-parse --verify refs/remotes/thunk@2\`\" \ - = \"\`git-rev-parse --verify refs/remotes/thunk~1\`\" && - test \"\`git-cat-file blob refs/remotes/thunk:readme |\ + test \"\`git rev-parse --verify refs/remotes/thunk@2\`\" \ + = \"\`git rev-parse --verify refs/remotes/thunk~1\`\" && + test \"\`git cat-file blob refs/remotes/thunk:readme |\ sed -n -e '3p'\`\" = goodbye && - test -z \"\`git-config --get svn-remote.svn.fetch \ + test -z \"\`git config --get svn-remote.svn.fetch \ '^trunk:refs/remotes/thunk@2$'\`\" " test_expect_success 'init and fetch from one svn-remote' " - git-config svn-remote.svn.url $svnrepo && - git-config --add svn-remote.svn.fetch \ + git config svn-remote.svn.url $svnrepo && + git config --add svn-remote.svn.fetch \ trunk:refs/remotes/svn/trunk && - git-config --add svn-remote.svn.fetch \ + git config --add svn-remote.svn.fetch \ thunk:refs/remotes/svn/thunk && git-svn fetch -i svn/thunk && - test \"\`git-rev-parse --verify refs/remotes/svn/trunk\`\" \ - = \"\`git-rev-parse --verify refs/remotes/svn/thunk~1\`\" && - test \"\`git-cat-file blob refs/remotes/svn/thunk:readme |\ + test \"\`git rev-parse --verify refs/remotes/svn/trunk\`\" \ + = \"\`git rev-parse --verify refs/remotes/svn/thunk~1\`\" && + test \"\`git cat-file blob refs/remotes/svn/thunk:readme |\ sed -n -e '3p'\`\" = goodbye " test_expect_success 'follow deleted parent' " svn cp -m 'resurrecting trunk as junk' \ -r2 $svnrepo/trunk $svnrepo/junk && - git-config --add svn-remote.svn.fetch \ + git config --add svn-remote.svn.fetch \ junk:refs/remotes/svn/junk && git-svn fetch -i svn/thunk && git-svn fetch -i svn/junk && @@ -71,13 +71,13 @@ test_expect_success 'follow larger parent' " git-svn init --minimize-url -i larger \ $svnrepo/another-larger/trunk/thunk/bump/thud && git-svn fetch -i larger && - git-rev-parse --verify refs/remotes/larger && - git-rev-parse --verify \ + git rev-parse --verify refs/remotes/larger && + git rev-parse --verify \ refs/remotes/larger-parent/trunk/thunk/bump/thud && - test \"\`git-merge-base \ + test \"\`git merge-base \ refs/remotes/larger-parent/trunk/thunk/bump/thud \ refs/remotes/larger\`\" = \ - \"\`git-rev-parse refs/remotes/larger\`\" + \"\`git rev-parse refs/remotes/larger\`\" true " diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh index d549665400..67fdf7023f 100755 --- a/t/t9107-git-svn-migrate.sh +++ b/t/t9107-git-svn-migrate.sh @@ -19,9 +19,9 @@ test_expect_success 'setup old-looking metadata' " mv $GIT_DIR/svn/* $GIT_DIR/ && mv $GIT_DIR/svn/.metadata $GIT_DIR/ && rmdir $GIT_DIR/svn && - git-update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn && - git-update-ref refs/heads/svn-HEAD refs/remotes/git-svn && - git-update-ref -d refs/remotes/git-svn refs/remotes/git-svn + git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn && + git update-ref refs/heads/svn-HEAD refs/remotes/git-svn && + git update-ref -d refs/remotes/git-svn refs/remotes/git-svn " head=`git rev-parse --verify refs/heads/git-svn-HEAD^0` @@ -33,8 +33,8 @@ test_expect_success 'initialize old-style (v0) git-svn layout' " echo $svnrepo > $GIT_DIR/svn/info/url && git-svn migrate && ! test -d $GIT_DIR/git-svn && - git-rev-parse --verify refs/remotes/git-svn^0 && - git-rev-parse --verify refs/remotes/svn^0 && + git rev-parse --verify refs/remotes/git-svn^0 && + git rev-parse --verify refs/remotes/svn^0 && test \`git config --get svn-remote.svn.url\` = '$svnrepo' && test \`git config --get svn-remote.svn.fetch\` = \ ':refs/remotes/git-svn' @@ -42,20 +42,20 @@ test_expect_success 'initialize old-style (v0) git-svn layout' " test_expect_success 'initialize a multi-repository repo' " git-svn init $svnrepo -T trunk -t tags -b branches && - git-config --get-all svn-remote.svn.fetch > fetch.out && + git config --get-all svn-remote.svn.fetch > fetch.out && grep '^trunk:refs/remotes/trunk$' fetch.out && - test -n \"\`git-config --get svn-remote.svn.branches \ + test -n \"\`git config --get svn-remote.svn.branches \ '^branches/\*:refs/remotes/\*$'\`\" && - test -n \"\`git-config --get svn-remote.svn.tags \ + test -n \"\`git config --get svn-remote.svn.tags \ '^tags/\*:refs/remotes/tags/\*$'\`\" && git config --unset svn-remote.svn.branches \ '^branches/\*:refs/remotes/\*$' && git config --unset svn-remote.svn.tags \ '^tags/\*:refs/remotes/tags/\*$' && - git-config --add svn-remote.svn.fetch 'branches/a:refs/remotes/a' && - git-config --add svn-remote.svn.fetch 'branches/b:refs/remotes/b' && + git config --add svn-remote.svn.fetch 'branches/a:refs/remotes/a' && + git config --add svn-remote.svn.fetch 'branches/b:refs/remotes/b' && for i in tags/0.1 tags/0.2 tags/0.3; do - git-config --add svn-remote.svn.fetch \ + git config --add svn-remote.svn.fetch \ \$i:refs/remotes/\$i || exit 1; done " @@ -86,8 +86,8 @@ test_expect_success 'migrate --minimize on old inited layout' " echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1; done && git-svn migrate --minimize && - test -z \"\`git-config -l |grep -v '^svn-remote\.git-svn\.'\`\" && - git-config --get-all svn-remote.svn.fetch > fetch.out && + test -z \"\`git config -l |grep -v '^svn-remote\.git-svn\.'\`\" && + git config --get-all svn-remote.svn.fetch > fetch.out && grep '^trunk:refs/remotes/trunk$' fetch.out && grep '^branches/a:refs/remotes/a$' fetch.out && grep '^branches/b:refs/remotes/b$' fetch.out && diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh index 59e17f2663..6235af4db8 100755 --- a/t/t9110-git-svn-use-svm-props.sh +++ b/t/t9110-git-svn-use-svm-props.sh @@ -13,7 +13,7 @@ test_expect_success 'load svm repo' " git-svn init --minimize-url -R argh -i dir $svnrepo/mirror/argh && git-svn init --minimize-url -R argh -i e \ $svnrepo/mirror/argh/a/b/c/d/e && - git-config svn.useSvmProps true && + git config svn.useSvmProps true && git-svn fetch --all " @@ -21,31 +21,31 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89 bar_url=http://mayonaise/svnrepo/bar test_expect_success 'verify metadata for /bar' " - git-cat-file commit refs/remotes/bar | \ + git cat-file commit refs/remotes/bar | \ grep '^git-svn-id: $bar_url@12 $uuid$' && - git-cat-file commit refs/remotes/bar~1 | \ + git cat-file commit refs/remotes/bar~1 | \ grep '^git-svn-id: $bar_url@11 $uuid$' && - git-cat-file commit refs/remotes/bar~2 | \ + git cat-file commit refs/remotes/bar~2 | \ grep '^git-svn-id: $bar_url@10 $uuid$' && - git-cat-file commit refs/remotes/bar~3 | \ + git cat-file commit refs/remotes/bar~3 | \ grep '^git-svn-id: $bar_url@9 $uuid$' && - git-cat-file commit refs/remotes/bar~4 | \ + git cat-file commit refs/remotes/bar~4 | \ grep '^git-svn-id: $bar_url@6 $uuid$' && - git-cat-file commit refs/remotes/bar~5 | \ + git cat-file commit refs/remotes/bar~5 | \ grep '^git-svn-id: $bar_url@1 $uuid$' " e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e test_expect_success 'verify metadata for /dir/a/b/c/d/e' " - git-cat-file commit refs/remotes/e | \ + git cat-file commit refs/remotes/e | \ grep '^git-svn-id: $e_url@1 $uuid$' " dir_url=http://mayonaise/svnrepo/dir test_expect_success 'verify metadata for /dir' " - git-cat-file commit refs/remotes/dir | \ + git cat-file commit refs/remotes/dir | \ grep '^git-svn-id: $dir_url@2 $uuid$' && - git-cat-file commit refs/remotes/dir~1 | \ + git cat-file commit refs/remotes/dir~1 | \ grep '^git-svn-id: $dir_url@1 $uuid$' " diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh index e52321471a..ec7dedd48b 100755 --- a/t/t9111-git-svn-use-svnsync-props.sh +++ b/t/t9111-git-svn-use-svnsync-props.sh @@ -12,7 +12,7 @@ test_expect_success 'load svnsync repo' " git-svn init --minimize-url -R arr -i bar $svnrepo/bar && git-svn init --minimize-url -R argh -i dir $svnrepo/dir && git-svn init --minimize-url -R argh -i e $svnrepo/dir/a/b/c/d/e && - git-config svn.useSvnsyncProps true && + git config svn.useSvnsyncProps true && git-svn fetch --all " @@ -20,31 +20,31 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89 bar_url=http://mayonaise/svnrepo/bar test_expect_success 'verify metadata for /bar' " - git-cat-file commit refs/remotes/bar | \ + git cat-file commit refs/remotes/bar | \ grep '^git-svn-id: $bar_url@12 $uuid$' && - git-cat-file commit refs/remotes/bar~1 | \ + git cat-file commit refs/remotes/bar~1 | \ grep '^git-svn-id: $bar_url@11 $uuid$' && - git-cat-file commit refs/remotes/bar~2 | \ + git cat-file commit refs/remotes/bar~2 | \ grep '^git-svn-id: $bar_url@10 $uuid$' && - git-cat-file commit refs/remotes/bar~3 | \ + git cat-file commit refs/remotes/bar~3 | \ grep '^git-svn-id: $bar_url@9 $uuid$' && - git-cat-file commit refs/remotes/bar~4 | \ + git cat-file commit refs/remotes/bar~4 | \ grep '^git-svn-id: $bar_url@6 $uuid$' && - git-cat-file commit refs/remotes/bar~5 | \ + git cat-file commit refs/remotes/bar~5 | \ grep '^git-svn-id: $bar_url@1 $uuid$' " e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e test_expect_success 'verify metadata for /dir/a/b/c/d/e' " - git-cat-file commit refs/remotes/e | \ + git cat-file commit refs/remotes/e | \ grep '^git-svn-id: $e_url@1 $uuid$' " dir_url=http://mayonaise/svnrepo/dir test_expect_success 'verify metadata for /dir' " - git-cat-file commit refs/remotes/dir | \ + git cat-file commit refs/remotes/dir | \ grep '^git-svn-id: $dir_url@2 $uuid$' && - git-cat-file commit refs/remotes/dir~1 | \ + git cat-file commit refs/remotes/dir~1 | \ grep '^git-svn-id: $dir_url@1 $uuid$' " diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 72e49f5d3b..53774c8325 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -60,10 +60,10 @@ INPUT_END test_expect_success \ 'A: create pack from stdin' \ 'git-fast-import --export-marks=marks.out expect < $GIT_COMMITTER_DATE @@ -73,7 +73,7 @@ initial EOF test_expect_success \ 'A: verify commit' \ - 'git-cat-file commit master | sed 1d >actual && + 'git cat-file commit master | sed 1d >actual && git diff expect actual' cat >expect <expect <actual && + 'git cat-file -p master^{tree} | sed "s/ [0-9a-f]* / /" >actual && git diff expect actual' echo "$file2_data" >expect test_expect_success \ 'A: verify file2' \ - 'git-cat-file blob master:file2 >actual && git diff expect actual' + 'git cat-file blob master:file2 >actual && git diff expect actual' echo "$file3_data" >expect test_expect_success \ 'A: verify file3' \ - 'git-cat-file blob master:file3 >actual && git diff expect actual' + 'git cat-file blob master:file3 >actual && git diff expect actual' printf "$file4_data" >expect test_expect_success \ 'A: verify file4' \ - 'git-cat-file blob master:file4 >actual && git diff expect actual' + 'git cat-file blob master:file4 >actual && git diff expect actual' cat >expect <expect <actual +git diff-tree -M -r master verify--import-marks >actual test_expect_success \ 'A: verify diff' \ 'compare_diff_raw expect actual && - test `git-rev-parse --verify master:file2` \ - = `git-rev-parse --verify verify--import-marks:copy-of-file2`' + test `git rev-parse --verify master:file2` \ + = `git rev-parse --verify verify--import-marks:copy-of-file2`' ### ### series B @@ -175,7 +175,7 @@ rm -f .git/objects/pack_* .git/objects/index_* ### newf=`echo hi newf | git-hash-object -w --stdin` -oldf=`git-rev-parse --verify master:file2` +oldf=`git rev-parse --verify master:file2` test_tick cat >input <expect < $GIT_COMMITTER_DATE committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE @@ -211,7 +211,7 @@ second EOF test_expect_success \ 'C: verify commit' \ - 'git-cat-file commit branch | sed 1d >actual && + 'git cat-file commit branch | sed 1d >actual && git diff expect actual' cat >expect <expect <actual +git diff-tree -M -r master branch >actual test_expect_success \ 'C: validate rename result' \ 'compare_diff_raw expect actual' @@ -251,16 +251,16 @@ INPUT_END test_expect_success \ 'D: inline data in commit' \ 'git-fast-import expect <actual +git diff-tree -M -r branch^ branch >actual test_expect_success \ 'D: validate new files added' \ 'compare_diff_raw expect actual' @@ -268,13 +268,13 @@ test_expect_success \ echo "$file5_data" >expect test_expect_success \ 'D: verify file5' \ - 'git-cat-file blob branch:newdir/interesting >actual && + 'git cat-file blob branch:newdir/interesting >actual && git diff expect actual' echo "$file6_data" >expect test_expect_success \ 'D: verify file6' \ - 'git-cat-file blob branch:newdir/exec.sh >actual && + 'git cat-file blob branch:newdir/exec.sh >actual && git diff expect actual' ### @@ -300,7 +300,7 @@ test_expect_success \ 'git-fast-import --date-format=rfc2822 expect < 1170778938 -0500 @@ -310,14 +310,14 @@ RFC 2822 type date EOF test_expect_success \ 'E: verify commit' \ - 'git-cat-file commit branch | sed 1,2d >actual && + 'git cat-file commit branch | sed 1,2d >actual && git diff expect actual' ### ### series F ### -old_branch=`git-rev-parse --verify branch^0` +old_branch=`git rev-parse --verify branch^0` test_tick cat >input <expect < $GIT_COMMITTER_DATE committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE @@ -363,14 +363,14 @@ losing things already? EOF test_expect_success \ 'F: verify other commit' \ - 'git-cat-file commit other >actual && + 'git cat-file commit other >actual && git diff expect actual' ### ### series G ### -old_branch=`git-rev-parse --verify branch^0` +old_branch=`git rev-parse --verify branch^0` test_tick cat >input <expect <expect <actual +git diff-tree -M -r H^ H >actual test_expect_success \ 'H: validate old files removed, new files added' \ 'compare_diff_raw expect actual' @@ -441,7 +441,7 @@ test_expect_success \ echo "$file5_data" >expect test_expect_success \ 'H: verify file' \ - 'git-cat-file blob H:h/e/l/lo >actual && + 'git cat-file blob H:h/e/l/lo >actual && git diff expect actual' ### @@ -463,7 +463,7 @@ test_expect_success \ 'git-fast-import --export-pack-edges=edges.list expect <output && + git diff --raw L^ L >output && git diff expect output' test_done From fcb10a964875a987f764af401537689e4aea82c6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 2 Jul 2007 23:15:45 -0700 Subject: [PATCH 041/213] git-stash: make "save" the default action again. Signed-off-by: Junio C Hamano --- Documentation/git-stash.txt | 7 ++++--- git-stash.sh | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index b7d263d650..35888b43c8 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -13,7 +13,7 @@ SYNOPSIS DESCRIPTION ----------- -Use 'git-stash save' when you want to record the current state of the +Use 'git-stash' when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the `HEAD` commit. @@ -22,7 +22,7 @@ The modifications stashed away by this command can be listed with `git-stash list`, inspected with `git-stash show`, and restored (potentially on top of a different commit) with `git-stash apply`. Calling git-stash without any arguments is equivalent to `git-stash -list`. +save`. The latest stash you created is stored in `$GIT_DIR/refs/stash`; older stashes are found in the reflog of this reference and can be named using @@ -36,7 +36,8 @@ OPTIONS save:: Save your local modifications to a new 'stash', and run `git-reset - --hard` to revert them. + --hard` to revert them. This is the default action when no + subcommand is given. list:: diff --git a/git-stash.sh b/git-stash.sh index 777d1e1351..16979ab41f 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -137,8 +137,8 @@ apply_stash () { # Main command set case "$1" in -list | '') - test $# -gt 0 && shift +list) + shift if test $# = 0 then set x -n 10 @@ -157,7 +157,7 @@ apply) clear) clear_stash ;; -save) +save | '') save_stash && git-reset --hard ;; *) From 2ecf3cee0754961401200e9f35071001ccdbbce3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 2 Jul 2007 23:29:54 -0700 Subject: [PATCH 042/213] Mark disused commit walkers officially deprecated. Signed-off-by: Junio C Hamano --- Documentation/git-local-fetch.txt | 2 ++ Documentation/git-ssh-fetch.txt | 2 ++ Documentation/git-ssh-upload.txt | 2 ++ 3 files changed, 6 insertions(+) diff --git a/Documentation/git-local-fetch.txt b/Documentation/git-local-fetch.txt index 19b5f8895c..141b76768c 100644 --- a/Documentation/git-local-fetch.txt +++ b/Documentation/git-local-fetch.txt @@ -14,6 +14,8 @@ SYNOPSIS DESCRIPTION ----------- +THIS COMMAND IS DEPRECATED. + Duplicates another git repository on a local system. OPTIONS diff --git a/Documentation/git-ssh-fetch.txt b/Documentation/git-ssh-fetch.txt index aaf3db06da..8d3e2ffb2c 100644 --- a/Documentation/git-ssh-fetch.txt +++ b/Documentation/git-ssh-fetch.txt @@ -13,6 +13,8 @@ SYNOPSIS DESCRIPTION ----------- +THIS COMMAND IS DEPRECATED. + Pulls from a remote repository over ssh connection, invoking git-ssh-upload on the other end. It functions identically to git-ssh-upload, aside from which end you run it on. diff --git a/Documentation/git-ssh-upload.txt b/Documentation/git-ssh-upload.txt index 4796224244..5e2ca8dccf 100644 --- a/Documentation/git-ssh-upload.txt +++ b/Documentation/git-ssh-upload.txt @@ -12,6 +12,8 @@ SYNOPSIS DESCRIPTION ----------- +THIS COMMAND IS DEPRECATED. + Pushes from a remote repository over ssh connection, invoking git-ssh-fetch on the other end. It functions identically to git-ssh-fetch, aside from which end you run it on. From 14a4091c16d14fd461f576e4bf1395da65e5d95e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 3 Jul 2007 12:04:24 -0700 Subject: [PATCH 043/213] Update draft Release Notes for 1.5.3 Signed-off-by: Junio C Hamano --- .mailmap | 1 + Documentation/RelNotes-1.5.3.txt | 61 ++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/.mailmap b/.mailmap index aa8ee6b3f1..71ec16acca 100644 --- a/.mailmap +++ b/.mailmap @@ -26,6 +26,7 @@ Lars Doelle Lukas Sandström Martin Langhoff Michele Ballabio +Nanako Shiraishi Nguyễn Thái Ngọc Duy Ramsay Allan Jones René Scharfe diff --git a/Documentation/RelNotes-1.5.3.txt b/Documentation/RelNotes-1.5.3.txt index ef2f95b3c5..e2e809e3c8 100644 --- a/Documentation/RelNotes-1.5.3.txt +++ b/Documentation/RelNotes-1.5.3.txt @@ -4,14 +4,16 @@ GIT v1.5.3 Release Notes Updates since v1.5.2 -------------------- -* An initial interation of Porcelain level superproject support - started to take shape. +* The commit walkers other than http are officially deprecated, + but still supported for now. -* Thee are a handful pack-objects changes to help you cope better with - repositories with pathologically large blobs in them. +* The submodule support has Porcelain layer. + +* There are a handful pack-objects changes to help you cope better + with repositories with pathologically large blobs in them. * For people who need to import from Perforce, a front-end for - fast-import is in contrib/fast-import/ now. + fast-import is in contrib/fast-import/. * Comes with git-gui 0.8.0. @@ -19,10 +21,25 @@ Updates since v1.5.2 * New commands and options. - - "git log" learned a new option '--follow', to follow + - "git stash" allows you to quickly save away your work in + progress and replay it later on an updated state. + + - "git rebase" learned an "interactive" mode that let you + pick and reorder which commits to rebuild. + + - "git fsck" can save its findings in $GIT_DIR/lost-found, + without a separate invocation of "git lost-found" command. + + - $GIT_WORK_TREE environment variable can be used together with + $GIT_DIR to work in a subdirectory of a working tree that is + not located at "$GIT_DIR/..". + + - "git log" learned a new option "--follow", to follow renaming history of a single file. - - "git-filter-branch" is a reborn cg-admin-rewritehist. + - "git-filter-branch" lets you rewrite the revision history of + the current branch, creating a new branch. You can specify a + number of filters to modify the commits, files and trees. - "git-cvsserver" learned new options (--base-path, --export-all, --strict-paths) inspired by git-daemon. @@ -58,11 +75,15 @@ Updates since v1.5.2 - "git format-patch" learned --numbered-files option. This may be useful for MH users. + - "git format-patch" learned format.subjectprefix configuration + variable, which serves the same purpose as "--subject-prefix" + option. + - "git tag -n -l" shows tag annotations while listing tags. - "git cvsimport" can optionally use the separate-remote layout. - - "git blame" can be told to see through commits that changes + - "git blame" can be told to see through commits that change whitespaces and indentation levels with "-w" option. - "git send-email" can be told not to thread the messages when @@ -71,8 +92,18 @@ Updates since v1.5.2 - "git config" learned NUL terminated output format via -z to help scripts. + - "git init -q" makes the command quieter. + * Updated behavior of existing commands. + - "git svn dcommit" retains local merge information. + + - "git config" to set values also honors type flags like --bool + and --int. + + - core.quotepath configuration can be used to make textual git + output to emit most of the characters in the path literally. + - "git mergetool" chooses its backend more wisely, taking notice of its environment such as use of X, Gnome/KDE, etc. @@ -84,7 +115,7 @@ Updates since v1.5.2 $path/$project/.git are more useful. We use $project part in the filename, which we used to discard. - - "git cvsimort" creates lightweight tag; there is not any + - "git cvsimport" creates lightweight tags; there is no interesting information we can record in an annotated tag, and the handcrafted ones the old code created was not properly formed anyway. @@ -99,9 +130,9 @@ Updates since v1.5.2 - "git-apply --whitespace=strip" removes blank lines added at the end of the file. - - "git-fetch" over git native protocols with -v shows connection - status, and the IP address of the other end, to help - diagnosing problems. + - "git-fetch" over git native protocols with "-v" option shows + connection status, and the IP address of the other end, to + help diagnosing problems. - We used to have core.legacyheaders configuration, when set to false, allowed git to write loose objects in a format @@ -124,8 +155,8 @@ Updates since v1.5.2 .gitattributes. It does not attempt to deltify blobs that come from paths with delta attribute set to false. - - new-workdir script (in contrib) can now be used with a bare - repository. + - "new-workdir" script (in contrib) can now be used with a + bare repository. - "git-mergetool" learned to use gvimdiff. @@ -179,6 +210,6 @@ this release, unless otherwise noted. -- exec >/var/tmp/1 -O=v1.5.2.2-603-g7c85173 +O=v1.5.3-rc0 echo O=`git describe refs/heads/master` git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint From 843103d69388a5c74ed99753e1c162a66835b04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 3 Jul 2007 10:59:06 +0200 Subject: [PATCH 044/213] stash: end commit log with a newline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If I do git cat-file commit $commitid for a commit created by stash, the next prompt starts directly after the shortlog of HEAD. Signed-off-by: Uwe Kleine-König Signed-off-by: Junio C Hamano --- git-stash.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-stash.sh b/git-stash.sh index 16979ab41f..9deda443ed 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -67,7 +67,7 @@ save_stash () { die "Cannot save the current worktree state" # create the stash - w_commit=$(printf 'WIP on %s' "$msg" | + w_commit=$(printf 'WIP on %s\n' "$msg" | git commit-tree $w_tree -p $b_commit -p $i_commit) || die "Cannot record working tree state" From c401b33c349beaf4c218c6441c3e2b58a958de6f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 4 Jul 2007 00:41:55 +0100 Subject: [PATCH 045/213] Document git-filter-branch This moves the documentation in git-filter-branch.sh to its own man page, with a few touch ups (incorporating comments by Frank Lichtenheld). Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/cmd-list.perl | 1 + Documentation/git-filter-branch.txt | 262 ++++++++++++++++++++++++++++ git-filter-branch.sh | 187 +------------------- 3 files changed, 266 insertions(+), 184 deletions(-) create mode 100644 Documentation/git-filter-branch.txt diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl index f50f613879..2143995ece 100755 --- a/Documentation/cmd-list.perl +++ b/Documentation/cmd-list.perl @@ -105,6 +105,7 @@ git-diff-tree plumbinginterrogators git-fast-import ancillarymanipulators git-fetch mainporcelain git-fetch-pack synchingrepositories +git-filter-branch ancillarymanipulators git-fmt-merge-msg purehelpers git-for-each-ref plumbinginterrogators git-format-patch mainporcelain diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt new file mode 100644 index 0000000000..2074f319a0 --- /dev/null +++ b/Documentation/git-filter-branch.txt @@ -0,0 +1,262 @@ +git-filter-branch(1) +==================== + +NAME +---- +git-filter-branch - Rewrite branches + +SYNOPSIS +-------- +[verse] +'git-filter-branch' [--env-filter ] [--tree-filter ] + [--index-filter ] [--parent-filter ] + [--msg-filter ] [--commit-filter ] + [--tag-name-filter ] [--subdirectory-filter ] + [-d ] [...] + +DESCRIPTION +----------- +Lets you rewrite git revision history by creating a new branch from +your current branch, applying custom filters on each revision. +Those filters can modify each tree (e.g. removing a file or running +a perl rewrite on all files) or information about each commit. +Otherwise, all information (including original commit times or merge +information) will be preserved. + +The command takes the new branch name as a mandatory argument and +the filters as optional arguments. If you specify no filters, the +commits will be recommitted without any changes, which would normally +have no effect and result in the new branch pointing to the same +branch as your current branch. Nevertheless, this may be useful in +the future for compensating for some git bugs or such, therefore +such a usage is permitted. + +WARNING! The rewritten history will have different object names for all +the objects and will not converge with the original branch. You will not +be able to easily push and distribute the rewritten branch on top of the +original branch. Please do not use this command if you do not know the +full implications, and avoid using it anyway, if a simple single commit +would suffice to fix your problem. + +Always verify that the rewritten version is correct before disposing +the original branch. + +Note that since this operation is extensively I/O expensive, it might +be a good idea to redirect the temporary directory off-disk, e.g. on +tmpfs. Reportedly the speedup is very noticeable. + + +Filters +~~~~~~~ + +The filters are applied in the order as listed below. The +argument is always evaluated in shell using the 'eval' command. +Prior to that, the $GIT_COMMIT environment variable will be set to contain +the id of the commit being rewritten. Also, GIT_AUTHOR_NAME, +GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, +and GIT_COMMITTER_DATE is set according to the current commit. + +A 'map' function is available that takes an "original sha1 id" argument +and outputs a "rewritten sha1 id" if the commit has been already +rewritten, fails otherwise; the 'map' function can return several +ids on separate lines if your commit filter emitted multiple commits. + + +OPTIONS +------- + +--env-filter :: + This is the filter for modifying the environment in which + the commit will be performed. Specifically, you might want + to rewrite the author/committer name/email/time environment + variables (see gitlink:git-commit[1] for details). Do not forget + to re-export the variables. + +--tree-filter :: + This is the filter for rewriting the tree and its contents. + The argument is evaluated in shell with the working + directory set to the root of the checked out tree. The new tree + is then used as-is (new files are auto-added, disappeared files + are auto-removed - neither .gitignore files nor any other ignore + rules HAVE ANY EFFECT!). + +--index-filter :: + This is the filter for rewriting the index. It is similar to the + tree filter but does not check out the tree, which makes it much + faster. For hairy cases, see gitlink:git-update-index[1]. + +--parent-filter :: + This is the filter for rewriting the commit's parent list. + It will receive the parent string on stdin and shall output + the new parent string on stdout. The parent string is in + a format accepted by gitlink:git-commit-tree[1]: empty for + the initial commit, "-p parent" for a normal commit and + "-p parent1 -p parent2 -p parent3 ..." for a merge commit. + +--msg-filter :: + This is the filter for rewriting the commit messages. + The argument is evaluated in the shell with the original + commit message on standard input; its standard output is + used as the new commit message. + +--commit-filter :: + This is the filter for performing the commit. + If this filter is specified, it will be called instead of the + gitlink:git-commit-tree[1] command, with arguments of the form + " [-p ]..." and the log message on + stdin. The commit id is expected on stdout. ++ +As a special extension, the commit filter may emit multiple +commit ids; in that case, ancestors of the original commit will +have all of them as parents. + +--tag-name-filter :: + This is the filter for rewriting tag names. When passed, + it will be called for every tag ref that points to a rewritten + object (or to a tag object which points to a rewritten object). + The original tag name is passed via standard input, and the new + tag name is expected on standard output. ++ +The original tags are not deleted, but can be overwritten; +use "--tag-name-filter=cat" to simply update the tags. In this +case, be very careful and make sure you have the old tags +backed up in case the conversion has run afoul. ++ +Note that there is currently no support for proper rewriting of +tag objects; in layman terms, if the tag has a message or signature +attached, the rewritten tag won't have it. Sorry. (It is by +definition impossible to preserve signatures at any rate.) + +--subdirectory-filter :: + Only ever look at the history, which touches the given subdirectory. + The result will contain that directory as its project root. + +-d :: + Use this option to set the path to the temporary directory used for + rewriting. When applying a tree filter, the command needs to + temporary checkout the tree to some directory, which may consume + considerable space in case of large projects. By default it + does this in the '.git-rewrite/' directory but you can override + that choice by this parameter. + +:: + When options are given after the new branch name, they will + be passed to gitlink:git-rev-list[1]. Only commits in the resulting + output will be filtered, although the filtered commits can still + reference parents which are outside of that set. + + +Examples +-------- + +Suppose you want to remove a file (containing confidential information +or copyright violation) from all commits: + +------------------------------------------------------- +git filter-branch --tree-filter 'rm filename' newbranch +------------------------------------------------------- + +A significantly faster version: + +------------------------------------------------------------------------------- +git filter-branch --index-filter 'git update-index --remove filename' newbranch +------------------------------------------------------------------------------- + +Now, you will get the rewritten history saved in the branch 'newbranch' +(your current branch is left untouched). + +To "etch-graft" a commit to the revision history (set a commit to be +the parent of the current initial commit and propagate that): + +---------------------------------------------------------------------- +git filter-branch --parent-filter sed\ 's/^$/-p /' newbranch +---------------------------------------------------------------------- + +(if the parent string is empty - therefore we are dealing with the +initial commit - add graftcommit as a parent). Note that this assumes +history with a single root (that is, no merge without common ancestors +happened). If this is not the case, use: + +------------------------------------------------------------------------------- +git filter-branch --parent-filter \ + 'cat; test $GIT_COMMIT = && echo "-p "' newbranch +------------------------------------------------------------------------------- + +To remove commits authored by "Darl McBribe" from the history: + +------------------------------------------------------------------------------ +git filter-branch --commit-filter ' + if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ]; + then + shift; + while [ -n "$1" ]; + do + shift; + echo "$1"; + shift; + done; + else + git commit-tree "$@"; + fi' newbranch +------------------------------------------------------------------------------ + +The shift magic first throws away the tree id and then the -p +parameters. Note that this handles merges properly! In case Darl +committed a merge between P1 and P2, it will be propagated properly +and all children of the merge will become merge commits with P1,P2 +as their parents instead of the merge commit. + +To restrict rewriting to only part of the history, specify a revision +range in addition to the new branch name. The new branch name will +point to the top-most revision that a 'git rev-list' of this range +will print. + +Note that the changes introduced by the commits, and not reverted by +subsequent commits, will still be in the rewritten branch. If you want +to throw out _changes_ together with the commits, you should use the +interactive mode of gitlink:git-rebase[1]. + +Consider this history: + +------------------ + D--E--F--G--H + / / +A--B-----C +------------------ + +To rewrite only commits D,E,F,G,H, but leave A, B and C alone, use: + +-------------------------------- +git filter-branch ... new-H C..H +-------------------------------- + +To rewrite commits E,F,G,H, use one of these: + +---------------------------------------- +git filter-branch ... new-H C..H --not D +git filter-branch ... new-H D..H --not C +---------------------------------------- + +To move the whole tree into a subdirectory, or remove it from there: + +--------------------------------------------------------------- +git filter-branch --index-filter \ + 'git ls-files -s | sed "s-\t-&newsubdir/-" | + GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ + git update-index --index-info && + mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' directorymoved +--------------------------------------------------------------- + + +Author +------ +Written by Petr "Pasky" Baudis , +and the git list + +Documentation +-------------- +Documentation by Petr Baudis and the git list. + +GIT +--- +Part of the gitlink:git[7] suite diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 3772951aa7..22fb5bf6ad 100644 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -4,190 +4,9 @@ # Copyright (c) Petr Baudis, 2006 # Minimal changes to "port" it to core-git (c) Johannes Schindelin, 2007 # -# Lets you rewrite GIT revision history by creating a new branch from -# your current branch by applying custom filters on each revision. -# Those filters can modify each tree (e.g. removing a file or running -# a perl rewrite on all files) or information about each commit. -# Otherwise, all information (including original commit times or merge -# information) will be preserved. -# -# The command takes the new branch name as a mandatory argument and -# the filters as optional arguments. If you specify no filters, the -# commits will be recommitted without any changes, which would normally -# have no effect and result with the new branch pointing to the same -# branch as your current branch. (Nevertheless, this may be useful in -# the future for compensating for some Git bugs or such, therefore -# such a usage is permitted.) -# -# WARNING! The rewritten history will have different ids for all the -# objects and will not converge with the original branch. You will not -# be able to easily push and distribute the rewritten branch. Please do -# not use this command if you do not know the full implications, and -# avoid using it anyway - do not do what a simple single commit on top -# of the current version would fix. -# -# Always verify that the rewritten version is correct before disposing -# the original branch. -# -# Note that since this operation is extensively I/O expensive, it might -# be a good idea to do it off-disk, e.g. on tmpfs. Reportedly the speedup -# is very noticeable. -# -# OPTIONS -# ------- -# -d TEMPDIR:: The path to the temporary tree used for rewriting -# When applying a tree filter, the command needs to temporary -# checkout the tree to some directory, which may consume -# considerable space in case of large projects. By default it -# does this in the '.git-rewrite/' directory but you can override -# that choice by this parameter. -# -# Filters -# ~~~~~~~ -# The filters are applied in the order as listed below. The COMMAND -# argument is always evaluated in shell using the 'eval' command. -# The $GIT_COMMIT environment variable is permanently set to contain -# the id of the commit being rewritten. The author/committer environment -# variables are set before the first filter is run. -# -# A 'map' function is available that takes an "original sha1 id" argument -# and outputs a "rewritten sha1 id" if the commit has been already -# rewritten, fails otherwise; the 'map' function can return several -# ids on separate lines if your commit filter emitted multiple commits -# (see below). -# -# --env-filter COMMAND:: The filter for modifying environment -# This is the filter for modifying the environment in which -# the commit will be performed. Specifically, you might want -# to rewrite the author/committer name/email/time environment -# variables (see `git-commit` for details). Do not forget to -# re-export the variables. -# -# --tree-filter COMMAND:: The filter for rewriting tree (and its contents) -# This is the filter for rewriting the tree and its contents. -# The COMMAND argument is evaluated in shell with the working -# directory set to the root of the checked out tree. The new tree -# is then used as-is (new files are auto-added, disappeared files -# are auto-removed - .gitignore files nor any other ignore rules -# HAVE NO EFFECT!). -# -# --index-filter COMMAND:: The filter for rewriting index -# This is the filter for rewriting the Git's directory index. -# It is similar to the tree filter but does not check out the -# tree, which makes it much faster. However, you must use the -# lowlevel Git index manipulation commands to do your work. -# -# --parent-filter COMMAND:: The filter for rewriting parents -# This is the filter for rewriting the commit's parent list. -# It will receive the parent string on stdin and shall output -# the new parent string on stdout. The parent string is in -# format accepted by `git commit-tree`: empty for initial -# commit, "-p parent" for a normal commit and "-p parent1 -# -p parent2 -p parent3 ..." for a merge commit. -# -# --msg-filter COMMAND:: The filter for rewriting commit message -# This is the filter for rewriting the commit messages. -# The COMMAND argument is evaluated in shell with the original -# commit message on standard input; its standard output is -# is used as the new commit message. -# -# --commit-filter COMMAND:: The filter for performing the commit -# If this filter is passed, it will be called instead of the -# `git commit-tree` command, with those arguments: -# -# TREE_ID [-p PARENT_COMMIT_ID]... -# -# and the log message on stdin. The commit id is expected on -# stdout. As a special extension, the commit filter may emit -# multiple commit ids; in that case, all of them will be used -# as parents instead of the original commit in further commits. -# -# --tag-name-filter COMMAND:: The filter for rewriting tag names. -# If this filter is passed, it will be called for every tag ref -# that points to a rewritten object (or to a tag object which -# points to a rewritten object). The original tag name is passed -# via standard input, and the new tag name is expected on standard -# output. -# -# The original tags are not deleted, but can be overwritten; -# use "--tag-name-filter=cat" to simply update the tags. In this -# case, be very careful and make sure you have the old tags -# backed up in case the conversion has run afoul. -# -# Note that there is currently no support for proper rewriting of -# tag objects; in layman terms, if the tag has a message or signature -# attached, the rewritten tag won't have it. Sorry. (It is by -# definition impossible to preserve signatures at any rate, though.) -# -# --subdirectory-filter DIRECTORY:: Only regard the history, as seen by -# the given subdirectory. The result will contain that directory as -# its project root. -# -# EXAMPLE USAGE -# ------------- -# Suppose you want to remove a file (containing confidential information -# or copyright violation) from all commits: -# -# git-filter-branch --tree-filter 'rm filename' newbranch -# -# A significantly faster version: -# -# git-filter-branch --index-filter 'git update-index --remove filename' newbranch -# -# Now, you will get the rewritten history saved in the branch 'newbranch' -# (your current branch is left untouched). -# -# To "etch-graft" a commit to the revision history (set a commit to be -# the parent of the current initial commit and propagate that): -# -# git-filter-branch --parent-filter sed\ 's/^$/-p graftcommitid/' newbranch -# -# (if the parent string is empty - therefore we are dealing with the -# initial commit - add graftcommit as a parent). Note that this assumes -# history with a single root (that is, no git-merge without common ancestors -# happened). If this is not the case, use: -# -# git-filter-branch --parent-filter 'cat; [ "$GIT_COMMIT" = "COMMIT" ] && echo "-p GRAFTCOMMIT"' newbranch -# -# To remove commits authored by "Darl McBribe" from the history: -# -# git-filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ]; then shift; while [ -n "$1" ]; do shift; echo "$1"; shift; done; else git commit-tree "$@"; fi' newbranch -# -# (the shift magic first throws away the tree id and then the -p -# parameters). Note that this handles merges properly! In case Darl -# committed a merge between P1 and P2, it will be propagated properly -# and all children of the merge will become merge commits with P1,P2 -# as their parents instead of the merge commit. -# -# To restrict rewriting to only part of the history, specify a revision -# range in addition to the new branch name. The new branch name will -# point to the top-most revision that a 'git rev-list' of this range -# will print. -# -# Consider this history: -# -# D--E--F--G--H -# / / -# A--B-----C -# -# To rewrite commits D,E,F,G,H, use: -# -# git-filter-branch ... new-H C..H -# -# To rewrite commits E,F,G,H, use one of these: -# -# git-filter-branch ... new-H C..H --not D -# git-filter-branch ... new-H D..H --not C -# -# To move the whole tree into a subdirectory, or remove it from there: -# -# git-filter-branch --index-filter \ -# 'git ls-files -s | sed "s-\t-&newsubdir/-" | -# GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ -# git update-index --index-info && -# mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' directorymoved - -# Testsuite: TODO +# Lets you rewrite the revision history of the current branch, creating +# a new branch. You can specify a number of filters to modify the commits, +# files and trees. set -e From 72909befaa043fcc975115bb56d25a6e7dc65fb6 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 30 Jun 2007 18:47:07 +0100 Subject: [PATCH 046/213] Add diff-option --ext-diff To prevent funky games with external diff engines, git-log and friends prevent external diff engines from being called. That makes sense in the context of git-format-patch or git-rebase. However, for "git log -p" it is not so nice to get the message that binary files cannot be compared, while "git diff" has no problems with them, if you provided an external diff driver. With this patch, "git log --ext-diff -p" will do what you expect, and the option "--no-ext-diff" can be used to override that setting. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/diff-options.txt | 8 ++++++++ diff.c | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 0f07c9c4a8..3d2b9d0a06 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -168,5 +168,13 @@ --quiet:: Disable all output of the program. Implies --exit-code. +--ext-diff:: + Allow an external diff helper to be executed. If you set an + external diff driver with gitlink:gitattributes(5), you need + to use this option with gitlink:git-log(1) and friends. + +--no-ext-diff:: + Disallow external diff drivers. + For more detailed explanation on these common options, see also link:diffcore.html[diffcore documentation]. diff --git a/diff.c b/diff.c index 93eca79c17..b6eb72be02 100644 --- a/diff.c +++ b/diff.c @@ -2241,6 +2241,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->exit_with_status = 1; else if (!strcmp(arg, "--quiet")) options->quiet = 1; + else if (!strcmp(arg, "--ext-diff")) + options->allow_external = 1; + else if (!strcmp(arg, "--no-ext-diff")) + options->allow_external = 0; else return 0; return 1; From e4465f0e71cc389a26bcf7474ad12112f683f633 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Wed, 4 Jul 2007 03:33:11 +0200 Subject: [PATCH 047/213] fsck --lost-found writes to subdirectories in .git/lost-found/ Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- Documentation/git-fsck.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt index 08512e0b8f..1a432f2319 100644 --- a/Documentation/git-fsck.txt +++ b/Documentation/git-fsck.txt @@ -65,8 +65,8 @@ index file and all SHA1 references in .git/refs/* as heads. Be chatty. --lost-found:: - Write dangling refs into .git/commit/ or .git/other/, depending - on type. + Write dangling refs into .git/lost-found/commit/ or + .git/lost-found/other/, depending on type. It tests SHA1 and general object sanity, and it does full tracking of the resulting reachability and everything else. It prints out any From f6b78c6eb626d477b252d39ef2801d4670675a2b Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 3 Jul 2007 17:50:19 +0100 Subject: [PATCH 048/213] filter-branch: add a test for the commit removal example In the man page, there is an example which describes how to remove single commits (although it keeps the changes which were not reverted in the next non-removed commit). Better make sure that it works as expected. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t7003-filter-branch.sh | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 21f9bc5dd6..451ac861af 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -107,4 +107,39 @@ test_expect_success 'use index-filter to move into a subdirectory' ' mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved && test -z "$(git diff HEAD directorymoved:newsubdir)"' +test_expect_success 'author information is preserved' ' + : > i && + git add i && + test_tick && + GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips && + git-filter-branch --msg-filter "cat; \ + test \$GIT_COMMIT = $(git rev-parse master) && \ + echo Hallo" \ + preserved-author && + test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l) +' + +test_expect_success "remove a certain author's commits" ' + echo i > i && + test_tick && + git commit -m i i && + git-filter-branch --commit-filter "\ + if [ \"\$GIT_AUTHOR_NAME\" = \"B V Uips\" ];\ + then\ + shift;\ + while [ -n \"\$1\" ];\ + do\ + shift;\ + echo \"\$1\";\ + shift;\ + done;\ + else\ + git commit-tree \"\$@\";\ + fi" removed-author && + cnt1=$(git rev-list master | wc -l) && + cnt2=$(git rev-list removed-author | wc -l) && + test $cnt1 -eq $(($cnt2 + 1)) && + test 0 = $(git rev-list --author="B V Uips" removed-author | wc -l) +' + test_done From c1fd897a25d85424a2ee93a8ae2eb247ba7c2558 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 22 Jun 2007 01:29:20 -0400 Subject: [PATCH 049/213] git-gui: Start blame windows as tall as possible Most users these days are using a windowing system attached to a monitor that has more than 600 pixels worth of vertical space available for application use. As most files stored by Git are longer than they are wide (have more lines than columns) we want to dedicate as much vertical space as we can to the viewer. Instead of always starting the window at ~600 pixels high we now start the window 100 pixels shorter than the screen claims it has available to it. This -100 rule is used because some popular OSen add menu bars at the top of the monitor, and docks on the bottom (e.g. Mac OS X, CDE, KDE). We want to avoid making our window too big and causing the window's resize control from being out of reach of the user. Signed-off-by: Shawn O. Pearce --- lib/blame.tcl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/blame.tcl b/lib/blame.tcl index b523654815..77abd8291d 100644 --- a/lib/blame.tcl +++ b/lib/blame.tcl @@ -304,8 +304,9 @@ constructor new {i_commit i_path} { set req_w [winfo reqwidth $top] set req_h [winfo reqheight $top] + set scr_h [expr {[winfo screenheight $top] - 100}] if {$req_w < 600} {set req_w 600} - if {$req_h < 400} {set req_h 400} + if {$req_h < $scr_h} {set req_h $scr_h} set g "${req_w}x${req_h}" wm geometry $top $g update From 4fb0fa197e14c82d64adb292320f9444d7ac46c5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 4 Jul 2007 19:43:51 +1000 Subject: [PATCH 050/213] gitk: Fix the find and highlight functions This reworks the way that the "Find" button (and the /, ?, ^F, and ^G keys) works. Previously, pressing the "Find" button would cause gitk to go off and scan through every commit to see which commits matched, and the user interface was completely unreponsive during that time. Now the searching is done in chunks using the scheduler, so the UI still responds, and the search stops as soon as a matching commit is found. The highlighting of matches using a yellow background is now done in the commit-drawing code and the highlighting code. This ensures that all the commits that are visible that match are highlighted without the search code having to find them all. This also fixes a bug where previously-drawn commits that need to be highlighted were not being highlighted. Signed-off-by: Paul Mackerras --- gitk | 331 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 189 insertions(+), 142 deletions(-) diff --git a/gitk b/gitk index 2d6a6ef9ce..d509145490 100755 --- a/gitk +++ b/gitk @@ -1758,7 +1758,7 @@ proc showview {n} { global colormap rowtextx commitrow nextcolor canvxmax global numcommits rowrangelist commitlisted idrowranges rowchk global selectedline currentid canv canvy0 - global matchinglines treediffs + global treediffs global pending_select phase global commitidx rowlaidout rowoptim global commfd @@ -1802,7 +1802,6 @@ proc showview {n} { [list {} $rowidlist $rowoffsets $rowrangelist] } } - catch {unset matchinglines} catch {unset treediffs} clear_display if {[info exists hlview] && $hlview == $n} { @@ -2132,7 +2131,7 @@ proc readfhighlight {} { proc find_change {name ix op} { global nhighlights mainfont boldnamerows - global findstring findpattern findtype + global findstring findpattern findtype markingmatches # delete previous highlights, if any foreach row $boldnamerows { @@ -2141,17 +2140,32 @@ proc find_change {name ix op} { set boldnamerows {} catch {unset nhighlights} unbolden + unmarkmatches if {$findtype ne "Regexp"} { set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \ $findstring] set findpattern "*$e*" } + set markingmatches [expr {$findstring ne {}}] drawvisible } +proc doesmatch {f} { + global findtype findstring findpattern + + if {$findtype eq "Regexp"} { + return [regexp $findstring $f] + } elseif {$findtype eq "IgnCase"} { + return [string match -nocase $findpattern $f] + } else { + return [string match $findpattern $f] + } +} + proc askfindhighlight {row id} { global nhighlights commitinfo iddrawn mainfont - global findstring findtype findloc findpattern + global findloc + global markingmatches if {![info exists commitinfo($id)]} { getcommit $id @@ -2160,35 +2174,47 @@ proc askfindhighlight {row id} { set isbold 0 set fldtypes {Headline Author Date Committer CDate Comments} foreach f $info ty $fldtypes { - if {$findloc ne "All fields" && $findloc ne $ty} { - continue - } - if {$findtype eq "Regexp"} { - set doesmatch [regexp $findstring $f] - } elseif {$findtype eq "IgnCase"} { - set doesmatch [string match -nocase $findpattern $f] - } else { - set doesmatch [string match $findpattern $f] - } - if {$doesmatch} { + if {($findloc eq "All fields" || $findloc eq $ty) && + [doesmatch $f]} { if {$ty eq "Author"} { set isbold 2 - } else { - set isbold 1 + break } + set isbold 1 } } - if {[info exists iddrawn($id)]} { - if {$isbold && ![ishighlighted $row]} { - bolden $row [concat $mainfont bold] + if {$isbold && [info exists iddrawn($id)]} { + set f [concat $mainfont bold] + if {![ishighlighted $row]} { + bolden $row $f + if {$isbold > 1} { + bolden_name $row $f + } } - if {$isbold >= 2} { - bolden_name $row [concat $mainfont bold] + if {$markingmatches} { + markrowmatches $row [lindex $info 0] [lindex $info 1] } } set nhighlights($row) $isbold } +proc markrowmatches {row headline author} { + global canv canv2 linehtag linentag + + $canv delete match$row + $canv2 delete match$row + set m [findmatches $headline] + if {$m ne {}} { + markmatches $canv $row $headline $linehtag($row) $m \ + [$canv itemcget $linehtag($row) -font] + } + set m [findmatches $author] + if {$m ne {}} { + markmatches $canv2 $row $author $linentag($row) $m \ + [$canv2 itemcget $linentag($row) -font] + } +} + proc vrel_change {name ix op} { global highlight_related @@ -3309,7 +3335,7 @@ proc drawcmittext {id row col} { global linespc canv canv2 canv3 canvy0 fgcolor global commitlisted commitinfo rowidlist parentlist global rowtextx idpos idtags idheads idotherrefs - global linehtag linentag linedtag + global linehtag linentag linedtag markingmatches global mainfont canvxmax boldrows boldnamerows fgcolor nullid if {$id eq $nullid} { @@ -3366,6 +3392,9 @@ proc drawcmittext {id row col} { set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \ -text $date -font $mainfont -tags text] set xr [expr {$xt + [font measure $mainfont $headline]}] + if {$markingmatches} { + markrowmatches $row $headline $name + } if {$xr > $canvxmax} { set canvxmax $xr setcanvscroll @@ -3436,9 +3465,7 @@ proc drawcommits {row {endrow {}}} { for {} {$r <= $er} {incr r} { set id [lindex $displayorder $r] set wasdrawn [info exists iddrawn($id)] - if {!$wasdrawn} { - drawcmitrow $r - } + drawcmitrow $r if {$r == $er} break set nextid [lindex $displayorder [expr {$r + 1}]] if {$wasdrawn && [info exists iddrawn($nextid)]} { @@ -3889,101 +3916,166 @@ proc notbusy {what} { } proc findmatches {f} { - global findtype foundstring foundstrlen + global findtype findstring if {$findtype == "Regexp"} { - set matches [regexp -indices -all -inline $foundstring $f] + set matches [regexp -indices -all -inline $findstring $f] } else { + set fs $findstring if {$findtype == "IgnCase"} { - set str [string tolower $f] - } else { - set str $f + set f [string tolower $f] + set fs [string tolower $fs] } set matches {} set i 0 - while {[set j [string first $foundstring $str $i]] >= 0} { - lappend matches [list $j [expr {$j+$foundstrlen-1}]] - set i [expr {$j + $foundstrlen}] + set l [string length $fs] + while {[set j [string first $fs $f $i]] >= 0} { + lappend matches [list $j [expr {$j+$l-1}]] + set i [expr {$j + $l}] } } return $matches } -proc dofind {} { - global findtype findloc findstring markedmatches commitinfo - global numcommits displayorder linehtag linentag linedtag - global mainfont canv canv2 canv3 selectedline - global matchinglines foundstring foundstrlen matchstring - global commitdata +proc dofind {{rev 0}} { + global findstring findstartline findcurline selectedline numcommits stopfindproc unmarkmatches cancel_next_highlight focus . - set matchinglines {} - if {$findtype == "IgnCase"} { - set foundstring [string tolower $findstring] - } else { - set foundstring $findstring - } - set foundstrlen [string length $findstring] - if {$foundstrlen == 0} return - regsub -all {[*?\[\\]} $foundstring {\\&} matchstring - set matchstring "*$matchstring*" + if {$findstring eq {} || $numcommits == 0} return if {![info exists selectedline]} { - set oldsel -1 + set findstartline [lindex [visiblerows] $rev] } else { - set oldsel $selectedline + set findstartline $selectedline } - set didsel 0 - set fldtypes {Headline Author Date Committer CDate Comments} - set l -1 - foreach id $displayorder { - set d $commitdata($id) - incr l - if {$findtype == "Regexp"} { - set doesmatch [regexp $foundstring $d] - } elseif {$findtype == "IgnCase"} { - set doesmatch [string match -nocase $matchstring $d] - } else { - set doesmatch [string match $matchstring $d] + set findcurline $findstartline + nowbusy finding + if {!$rev} { + run findmore + } else { + set findcurline $findstartline + if {$findcurline == 0} { + set findcurline $numcommits } - if {!$doesmatch} continue + incr findcurline -1 + run findmorerev + } +} + +proc findnext {restart} { + global findcurline + if {![info exists findcurline]} { + if {$restart} { + dofind + } else { + bell + } + } else { + run findmore + nowbusy finding + } +} + +proc findprev {} { + global findcurline + if {![info exists findcurline]} { + dofind 1 + } else { + run findmorerev + nowbusy finding + } +} + +proc findmore {} { + global commitdata commitinfo numcommits findstring findpattern findloc + global findstartline findcurline markingmatches displayorder + + set fldtypes {Headline Author Date Committer CDate Comments} + set l [expr {$findcurline + 1}] + if {$l >= $numcommits} { + set l 0 + } + if {$l <= $findstartline} { + set lim [expr {$findstartline + 1}] + } else { + set lim $numcommits + } + if {$lim - $l > 500} { + set lim [expr {$l + 500}] + } + set last 0 + for {} {$l < $lim} {incr l} { + set id [lindex $displayorder $l] + if {![doesmatch $commitdata($id)]} continue if {![info exists commitinfo($id)]} { getcommit $id } set info $commitinfo($id) - set doesmatch 0 foreach f $info ty $fldtypes { - if {$findloc != "All fields" && $findloc != $ty} { - continue - } - set matches [findmatches $f] - if {$matches == {}} continue - set doesmatch 1 - if {$ty == "Headline"} { - drawcommits $l - markmatches $canv $l $f $linehtag($l) $matches $mainfont - } elseif {$ty == "Author"} { - drawcommits $l - markmatches $canv2 $l $f $linentag($l) $matches $mainfont - } elseif {$ty == "Date"} { - drawcommits $l - markmatches $canv3 $l $f $linedtag($l) $matches $mainfont - } - } - if {$doesmatch} { - lappend matchinglines $l - if {!$didsel && $l > $oldsel} { + if {($findloc eq "All fields" || $findloc eq $ty) && + [doesmatch $f]} { + set markingmatches 1 findselectline $l - set didsel 1 + notbusy finding + return 0 } } } - if {$matchinglines == {}} { + if {$l == $findstartline + 1} { bell - } elseif {!$didsel} { - findselectline [lindex $matchinglines 0] + unset findcurline + notbusy finding + return 0 } + set findcurline [expr {$l - 1}] + return 1 +} + +proc findmorerev {} { + global commitdata commitinfo numcommits findstring findpattern findloc + global findstartline findcurline markingmatches displayorder + + set fldtypes {Headline Author Date Committer CDate Comments} + set l $findcurline + if {$l == 0} { + set l $numcommits + } + incr l -1 + if {$l >= $findstartline} { + set lim [expr {$findstartline - 1}] + } else { + set lim -1 + } + if {$l - $lim > 500} { + set lim [expr {$l - 500}] + } + set last 0 + for {} {$l > $lim} {incr l -1} { + set id [lindex $displayorder $l] + if {![doesmatch $commitdata($id)]} continue + if {![info exists commitinfo($id)]} { + getcommit $id + } + set info $commitinfo($id) + foreach f $info ty $fldtypes { + if {($findloc eq "All fields" || $findloc eq $ty) && + [doesmatch $f]} { + set markingmatches 1 + findselectline $l + notbusy finding + return 0 + } + } + } + if {$l == -1} { + bell + unset findcurline + notbusy finding + return 0 + } + set findcurline [expr {$l + 1}] + return 1 } proc findselectline {l} { @@ -4001,43 +4093,6 @@ proc findselectline {l} { } } -proc findnext {restart} { - global matchinglines selectedline - if {![info exists matchinglines]} { - if {$restart} { - dofind - } - return - } - if {![info exists selectedline]} return - foreach l $matchinglines { - if {$l > $selectedline} { - findselectline $l - return - } - } - bell -} - -proc findprev {} { - global matchinglines selectedline - if {![info exists matchinglines]} { - dofind - return - } - if {![info exists selectedline]} return - set prev {} - foreach l $matchinglines { - if {$l >= $selectedline} break - set prev $l - } - if {$prev != {}} { - findselectline $prev - } else { - bell - } -} - proc stopfindproc {{done 0}} { global findprocpid findprocfile findids global ctext findoldcursor phase maincursor textcursor @@ -4055,18 +4110,7 @@ proc stopfindproc {{done 0}} { notbusy find } -# mark a commit as matching by putting a yellow background -# behind the headline -proc markheadline {l id} { - global canv mainfont linehtag - - drawcommits $l - set bbox [$canv bbox $linehtag($l)] - set t [$canv create rect $bbox -outline {} -tags matches -fill yellow] - $canv lower $t -} - -# mark the bits of a headline, author or date that match a find string +# mark the bits of a headline or author that match a find string proc markmatches {canv l str tag matches font} { set bbox [$canv bbox $tag] set x0 [lindex $bbox 0] @@ -4080,16 +4124,18 @@ proc markmatches {canv l str tag matches font} { set xlen [font measure $font [string range $str 0 [expr {$end}]]] set t [$canv create rect [expr {$x0+$xoff}] $y0 \ [expr {$x0+$xlen+2}] $y1 \ - -outline {} -tags matches -fill yellow] + -outline {} -tags [list match$l matches] -fill yellow] $canv lower $t } } proc unmarkmatches {} { - global matchinglines findids + global findids markingmatches findcurline + allcanvs delete matches - catch {unset matchinglines} catch {unset findids} + set markingmatches 0 + catch {unset findcurline} } proc selcanvline {w x y} { @@ -7471,6 +7517,7 @@ set searchdirn -forwards set boldrows {} set boldnamerows {} set diffelide {0 0} +set markingmatches 0 set optim_delay 16 From 69c0b5d2408cfe207f2976fc99cbe71208ba83ad Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 4 Jul 2007 21:57:04 +1000 Subject: [PATCH 051/213] gitk: Fix bug in the anc_or_desc routine I missed the case where both nodes have no children and therefore have no incoming arcs. This fixes it. Signed-off-by: Paul Mackerras --- gitk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gitk b/gitk index d509145490..767b0ed8b8 100755 --- a/gitk +++ b/gitk @@ -6261,7 +6261,8 @@ proc anc_or_desc {a b} { # Both are on the same arc(s); either both are the same BMP, # or if one is not a BMP, the other is also not a BMP or is # the BMP at end of the arc (and it only has 1 incoming arc). - if {$a eq $b} { + # Or both can be BMPs with no incoming arcs. + if {$a eq $b || $arcnos($a) eq {}} { return 0 } # assert {[llength $arcnos($a)] == 1} From d36d385efd89d79c9d1f95ab79849ff1478dc425 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 4 Jul 2007 22:41:19 +1000 Subject: [PATCH 052/213] gitk: Remove the unused stopfindproc function This was a hangover from before the "Files" and "Pickaxe" parts of the Find function were moved to the highlight facility in commit 60f7a7dc4904ba4baab44b70e2675a01e6172f54. It serves no useful purpose any more, so this removes it. Signed-off-by: Paul Mackerras --- gitk | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/gitk b/gitk index 767b0ed8b8..45e16e4fd5 100755 --- a/gitk +++ b/gitk @@ -1786,7 +1786,6 @@ proc showview {n} { } unselectline normalline - stopfindproc if {$curview >= 0} { set vparentlist($curview) $parentlist set vdisporder($curview) $displayorder @@ -3939,7 +3938,6 @@ proc findmatches {f} { proc dofind {{rev 0}} { global findstring findstartline findcurline selectedline numcommits - stopfindproc unmarkmatches cancel_next_highlight focus . @@ -4093,23 +4091,6 @@ proc findselectline {l} { } } -proc stopfindproc {{done 0}} { - global findprocpid findprocfile findids - global ctext findoldcursor phase maincursor textcursor - global findinprogress - - catch {unset findids} - if {[info exists findprocpid]} { - if {!$done} { - catch {exec kill $findprocpid} - } - catch {close $findprocfile} - unset findprocpid - } - catch {unset findinprogress} - notbusy find -} - # mark the bits of a headline or author that match a find string proc markmatches {canv l str tag matches font} { set bbox [$canv bbox $tag] From 41c7c1bd6f151f351365451acbf9fade6eb6044c Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Wed, 4 Jul 2007 18:22:14 +0200 Subject: [PATCH 053/213] git-submodule: Fix two instances of the same typo They break the output of git submodule status. Signed-off-by: Junio C Hamano --- git-submodule.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index 0ba016135f..1f0cb99dcb 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -234,7 +234,7 @@ modules_list() continue; fi revname=$(unset GIT_DIR && cd "$path" && git describe --tags $sha1) - set_name_rev "$path" $"sha1" + set_name_rev "$path" "$sha1" if git diff-files --quiet -- "$path" then say " $sha1 $path$revname" @@ -242,7 +242,7 @@ modules_list() if test -z "$cached" then sha1=$(unset GIT_DIR && cd "$path" && git rev-parse --verify HEAD) - set_name_rev "$path" $"sha1" + set_name_rev "$path" "$sha1" fi say "+$sha1 $path$revname" fi From 54adf3706c5c799584c1bcdcac96fb3285b97de4 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Tue, 3 Jul 2007 14:18:11 -0400 Subject: [PATCH 054/213] Add core.pager config variable. This adds a configuration variable that performs the same function as, but is overridden by, GIT_PAGER. Signed-off-by: Brian Gernhardt Acked-by: Johannes E. Schindelin Signed-off-by: Junio C Hamano --- Documentation/config.txt | 4 ++++ cache.h | 1 + config.c | 5 +++++ environment.c | 1 + pager.c | 2 ++ 5 files changed, 13 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 1d96adf30b..66a55b0514 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -281,6 +281,10 @@ core.excludesfile:: of files which are not meant to be tracked. See gitlink:gitignore[5]. +core.pager:: + The command that git will use to paginate output. Can be overridden + with the `GIT_PAGER` environment variable. + alias.*:: Command aliases for the gitlink:git[1] command wrapper - e.g. after defining "alias.last = cat-file commit HEAD", the invocation diff --git a/cache.h b/cache.h index 0d23a25b1f..e64071e2e3 100644 --- a/cache.h +++ b/cache.h @@ -546,6 +546,7 @@ extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char /* pager.c */ extern void setup_pager(void); +extern char *pager_program; extern int pager_in_use; extern int pager_use_color; diff --git a/config.c b/config.c index 4de8926330..561ee3b576 100644 --- a/config.c +++ b/config.c @@ -387,6 +387,11 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.pager")) { + pager_program = xstrdup(value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } diff --git a/environment.c b/environment.c index 1c2773f1bd..f83fb9e448 100644 --- a/environment.c +++ b/environment.c @@ -30,6 +30,7 @@ int core_compression_seen; size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE; size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT; size_t delta_base_cache_limit = 16 * 1024 * 1024; +char *pager_program; int pager_in_use; int pager_use_color = 1; int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */ diff --git a/pager.c b/pager.c index 5f280ab527..3bfed02599 100644 --- a/pager.c +++ b/pager.c @@ -31,6 +31,8 @@ void setup_pager(void) if (!isatty(1)) return; + if (!pager) + pager = pager_program; if (!pager) pager = getenv("PAGER"); if (!pager) From d9fb395ae30b50e8a1059338884090b574d8a3e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 3 Jul 2007 10:47:58 +0200 Subject: [PATCH 055/213] repack: don't report "Nothing new to pack." if -q is given MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Junio C Hamano --- git-repack.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/git-repack.sh b/git-repack.sh index 3644a5a4d2..b5c667110d 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -66,7 +66,9 @@ args="$args $local $quiet $no_reuse$extra" names=$(git pack-objects --non-empty --all --reflog $args Date: Wed, 4 Jul 2007 12:37:17 -0700 Subject: [PATCH 056/213] Update reflog message created for stashes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A stash is about a change on top of an existing commit, and not about that commit that happened to be on which the change was created. Match the message we see in "git stash list" with the commit log message to make this clear. Signed-off-by: Junio C Hamano Acked-by: Uwe Kleine-König --- git-stash.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-stash.sh b/git-stash.sh index 9deda443ed..fa8ae7bc29 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -71,7 +71,7 @@ save_stash () { git commit-tree $w_tree -p $b_commit -p $i_commit) || die "Cannot record working tree state" - git update-ref -m "$msg" $ref_stash $w_commit || + git update-ref -m "WIP on $msg" $ref_stash $w_commit || die "Cannot save the current status" printf >&2 'Saved WIP on %s\n' "$msg" } From 88c447e8f467c6b2ca09ad91f3fa1d1d662dd04d Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Wed, 4 Jul 2007 12:33:46 +0200 Subject: [PATCH 057/213] Handle missing prefix for "Subject:" as if no prefix given Signed-off-by: Junio C Hamano --- log-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log-tree.c b/log-tree.c index ced3f332ef..8624d5a39c 100644 --- a/log-tree.c +++ b/log-tree.c @@ -200,7 +200,7 @@ void show_log(struct rev_info *opt, const char *sep) digits_in_number(opt->total), opt->nr, opt->total); subject = buffer; - } else if (opt->total == 0) { + } else if (opt->total == 0 && opt->subject_prefix && *opt->subject_prefix) { static char buffer[256]; snprintf(buffer, sizeof(buffer), "Subject: [%s] ", From d54276f207081e35174c5d742e378cfff6e9843f Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Wed, 4 Jul 2007 12:37:27 +0200 Subject: [PATCH 058/213] Handle format.subjectprefix for every command which accepts --pretty Because the --pretty can be given as --pretty=email which historically produced mails with patches. IOW, exactly what git-format-patch does. Signed-off-by: Junio C Hamano --- builtin-log.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/builtin-log.c b/builtin-log.c index 5dc2c1c230..13bae3110e 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -16,6 +16,7 @@ #include "refs.h" static int default_show_root = 1; +static const char *fmt_patch_subject_prefix = "PATCH"; /* this is in builtin-diff.c */ void add_head(struct rev_info *revs); @@ -55,6 +56,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, rev->commit_format = CMIT_FMT_DEFAULT; rev->verbose_header = 1; rev->show_root_diff = default_show_root; + rev->subject_prefix = fmt_patch_subject_prefix; argc = setup_revisions(argc, argv, rev, "HEAD"); if (rev->diffopt.pickaxe || rev->diffopt.filter) rev->always_show_header = 0; @@ -94,6 +96,12 @@ static int cmd_log_walk(struct rev_info *rev) static int git_log_config(const char *var, const char *value) { + if (!strcmp(var, "format.subjectprefix")) { + if (!value) + die("format.subjectprefix without value"); + fmt_patch_subject_prefix = xstrdup(value); + return 0; + } if (!strcmp(var, "log.showroot")) { default_show_root = git_config_bool(var, value); return 0; @@ -265,7 +273,6 @@ static int istitlechar(char c) static char *extra_headers = NULL; static int extra_headers_size = 0; -static const char *fmt_patch_subject_prefix = "PATCH"; static const char *fmt_patch_suffix = ".patch"; static int git_format_config(const char *var, const char *value) @@ -291,12 +298,6 @@ static int git_format_config(const char *var, const char *value) if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) { return 0; } - if (!strcmp(var, "format.subjectprefix")) { - if (!value) - die("format.subjectprefix without value"); - fmt_patch_subject_prefix = xstrdup(value); - return 0; - } return git_log_config(var, value); } From c57a3494c135ffb7ab5d070afecfcc42a3922edc Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Wed, 4 Jul 2007 14:08:17 +0200 Subject: [PATCH 059/213] filter-branch: Avoid an error message in the map function. When the map function didn't find the rewritten commit of the passed in original id, it printed the original id, but it still fell through to the 'cat', which failed with an error message. Signed-off-by: Johannes Sixt Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 22fb5bf6ad..5fa9b61740 100644 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -16,8 +16,12 @@ USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] DESTBRANCH [REV-RANGE]" map() { # if it was not rewritten, take the original - test -r "$workdir/../map/$1" || echo "$1" - cat "$workdir/../map/$1" + if test -r "$workdir/../map/$1" + then + cat "$workdir/../map/$1" + else + echo "$1" + fi } # When piped a commit, output a script to set the ident of either From 586e4ce2487932b2ae770aad17d343b9021080e0 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Wed, 4 Jul 2007 14:06:04 +0200 Subject: [PATCH 060/213] Fix t5516 to create test repo without hooks Otherwise the hooks will be executed on cygwin and the test will fail because of the contributed hooks. Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- t/t5516-fetch-push.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index c0fa2ba404..ca46aafe72 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -11,7 +11,8 @@ mk_empty () { mkdir testrepo && ( cd testrepo && - git init + git init && + mv .git/hooks .git/hooks-disabled ) } From 5efb48b5ed7dd6838962a7b25845c6d8e2d40422 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 4 Jul 2007 15:33:30 +0100 Subject: [PATCH 061/213] filter-branch: make output nicer Instead of filling the screen with progress lines, use \r so that the progress can be seen, but warning messages are more visible. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) mode change 100644 => 100755 git-filter-branch.sh diff --git a/git-filter-branch.sh b/git-filter-branch.sh old mode 100644 new mode 100755 index 5fa9b61740..c22266b486 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -164,7 +164,7 @@ test $commits -eq 0 && die "Found nothing to rewrite" i=0 while read commit parents; do i=$(($i+1)) - printf "$commit ($i/$commits) " + printf "\rRewrite $commit ($i/$commits)" case "$filter_subdir" in "") @@ -207,8 +207,8 @@ while read commit parents; do sed -e '1,/^$/d' <../commit | \ eval "$filter_msg" | \ - sh -c "$filter_commit" "git commit-tree" $(git write-tree) $parentstr | \ - tee ../map/$commit + sh -c "$filter_commit" "git commit-tree" $(git write-tree) \ + $parentstr > ../map/$commit done <../revs src_head=$(tail -n 1 ../revs | sed -e 's/ .*//') @@ -260,6 +260,6 @@ fi cd ../.. rm -rf "$tempdir" -echo "Rewritten history saved to the $dstbranch branch" +printf "\nRewritten history saved to the $dstbranch branch\n" exit $ret From 73616fd3d21ab5eefc912fa886ff8808e59d6e7e Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 4 Jul 2007 15:50:45 +0100 Subject: [PATCH 062/213] filter-branch: a few more touch ups to the man page All based on comments from Frank Lichtenheld. Signed-off-by: Johannes Schindelin Acked-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- Documentation/git-filter-branch.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 2074f319a0..363287d0ab 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -31,7 +31,7 @@ branch as your current branch. Nevertheless, this may be useful in the future for compensating for some git bugs or such, therefore such a usage is permitted. -WARNING! The rewritten history will have different object names for all +*WARNING*! The rewritten history will have different object names for all the objects and will not converge with the original branch. You will not be able to easily push and distribute the rewritten branch on top of the original branch. Please do not use this command if you do not know the @@ -54,7 +54,7 @@ argument is always evaluated in shell using the 'eval' command. Prior to that, the $GIT_COMMIT environment variable will be set to contain the id of the commit being rewritten. Also, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, -and GIT_COMMITTER_DATE is set according to the current commit. +and GIT_COMMITTER_DATE are set according to the current commit. A 'map' function is available that takes an "original sha1 id" argument and outputs a "rewritten sha1 id" if the commit has been already @@ -78,7 +78,7 @@ OPTIONS directory set to the root of the checked out tree. The new tree is then used as-is (new files are auto-added, disappeared files are auto-removed - neither .gitignore files nor any other ignore - rules HAVE ANY EFFECT!). + rules *HAVE ANY EFFECT*!). --index-filter :: This is the filter for rewriting the index. It is similar to the @@ -128,8 +128,9 @@ attached, the rewritten tag won't have it. Sorry. (It is by definition impossible to preserve signatures at any rate.) --subdirectory-filter :: - Only ever look at the history, which touches the given subdirectory. - The result will contain that directory as its project root. + Only look at the history which touches the given subdirectory. + The result will contain that directory (and only that) as its + project root. -d :: Use this option to set the path to the temporary directory used for From f66a4d68d2066998605f5910c3c8dd1e4a25fc7f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 4 Jul 2007 12:45:42 -0700 Subject: [PATCH 063/213] Do not check if getcwd() result begins with a slash. In user space, and for getcwd(), the check to see if the resulting path begins with a '/' does not make sense. This is merely a mistake by Linus who is so used to code for the kernel, where a d_path() return value pathname can be either a real path, or something like "pipe:[8003]", and the difference is the '/' at the beginning. Pointed out by Dscho, Matthias Lederhofer and clarified by Linus. Signed-off-by: Junio C Hamano --- setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.c b/setup.c index 01f74d4644..bb26f3af96 100644 --- a/setup.c +++ b/setup.c @@ -211,7 +211,7 @@ const char *setup_git_directory_gently(int *nongit_ok) if (!gitdirenv) { int len, offset; - if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/') + if (!getcwd(cwd, sizeof(cwd)-1)) die("Unable to read current working directory"); offset = len = strlen(cwd); @@ -271,7 +271,7 @@ const char *setup_git_directory_gently(int *nongit_ok) die("Not a git repository: '%s'", gitdirenv); } - if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/') + if (!getcwd(cwd, sizeof(cwd)-1)) die("Unable to read current working directory"); if (chdir(gitdirenv)) { if (nongit_ok) { @@ -281,7 +281,7 @@ const char *setup_git_directory_gently(int *nongit_ok) die("Cannot change directory to $%s '%s'", GIT_DIR_ENVIRONMENT, gitdirenv); } - if (!getcwd(gitdir, sizeof(gitdir)-1) || gitdir[0] != '/') + if (!getcwd(gitdir, sizeof(gitdir)-1)) die("Unable to read current working directory"); if (chdir(cwd)) die("Cannot come back to cwd"); @@ -340,7 +340,7 @@ const char *setup_git_directory_gently(int *nongit_ok) die("Cannot change directory to working tree '%s'", gitworktree); } - if (!getcwd(worktree, sizeof(worktree)-1) || worktree[0] != '/') + if (!getcwd(worktree, sizeof(worktree)-1)) die("Unable to read current working directory"); strcat(worktree, "/"); inside_work_tree = !prefixcmp(cwd, worktree); From ef6f0af2b6975e6568542123d015aa7e39bea0c3 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Wed, 4 Jul 2007 00:49:19 +0200 Subject: [PATCH 064/213] git-init: set core.worktree if GIT_WORK_TREE is specified Now you can do the following to create a repository which has a separate working tree: /tmp/foo$ export GIT_DIR=/tmp/bar /tmp/foo$ git --work-tree . init Initialized empty Git repository in /tmp/bar/ /tmp/foo$ git config core.worktree /tmp/foo Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- builtin-init-db.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/builtin-init-db.c b/builtin-init-db.c index d429ceda36..66ddaebcc5 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -174,7 +174,36 @@ static void copy_templates(const char *git_dir, int len, const char *template_di closedir(dir); } -static int create_default_files(const char *git_dir, const char *template_path) +/* + * Get the full path to the working tree specified in $GIT_WORK_TREE + * or NULL if no working tree is specified. + */ +static const char *get_work_tree(void) +{ + const char *git_work_tree; + char cwd[PATH_MAX]; + static char worktree[PATH_MAX]; + + git_work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT); + if (!git_work_tree) + return NULL; + if (!getcwd(cwd, sizeof(cwd))) + die("Unable to read current working directory"); + if (chdir(git_work_tree)) + die("Cannot change directory to specified working tree '%s'", + git_work_tree); + if (git_work_tree[0] != '/') { + if (!getcwd(worktree, sizeof(worktree))) + die("Unable to read current working directory"); + git_work_tree = worktree; + } + if (chdir(cwd)) + die("Cannot come back to cwd"); + return git_work_tree; +} + +static int create_default_files(const char *git_dir, const char *git_work_tree, + const char *template_path) { unsigned len = strlen(git_dir); static char path[PATH_MAX]; @@ -253,7 +282,7 @@ static int create_default_files(const char *git_dir, const char *template_path) } git_config_set("core.filemode", filemode ? "true" : "false"); - if (is_bare_repository()) { + if (is_bare_repository() && !git_work_tree) { git_config_set("core.bare", "true"); } else { @@ -261,6 +290,8 @@ static int create_default_files(const char *git_dir, const char *template_path) /* allow template config file to override the default */ if (log_all_ref_updates == -1) git_config_set("core.logallrefupdates", "true"); + if (git_work_tree) + git_config_set("core.worktree", git_work_tree); } return reinit; } @@ -277,6 +308,7 @@ static const char init_db_usage[] = int cmd_init_db(int argc, const char **argv, const char *prefix) { const char *git_dir; + const char *git_work_tree; const char *sha1_dir; const char *template_dir = NULL; char *path; @@ -297,6 +329,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) usage(init_db_usage); } + git_work_tree = get_work_tree(); + /* * Set up the default .git directory contents */ @@ -312,7 +346,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) */ check_repository_format(); - reinit = create_default_files(git_dir, template_dir); + reinit = create_default_files(git_dir, git_work_tree, template_dir); /* * And set up the object store. From 49aba0bb3a85a4364cf3f0f73b3b6ddf98f7e037 Mon Sep 17 00:00:00 2001 From: Sean Date: Wed, 4 Jul 2007 04:33:36 -0400 Subject: [PATCH 065/213] Alter git-checkout reflog message to include "from" branch As suggested by Junio, adding the current branch name to the reflog message for git-checkout would be helpful. For example: "checkout: moving from next to master" Signed-off-by: Sean Estabrooks Signed-off-by: Junio C Hamano --- git-checkout.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git-checkout.sh b/git-checkout.sh index e00b697fef..17f43927aa 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -259,7 +259,8 @@ if [ "$?" -eq 0 ]; then fi if test -n "$branch" then - GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving to $branch" HEAD "refs/heads/$branch" + old_branch_name=`expr "z$oldbranch" : 'zrefs/heads/\(.*\)'` + GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving from $old_branch_name to $branch" HEAD "refs/heads/$branch" if test -n "$quiet" then true # nothing From b5669a05043e402f2f41636c1b18e7865f41b9c0 Mon Sep 17 00:00:00 2001 From: Steffen Prohaska Date: Wed, 4 Jul 2007 10:36:24 +0200 Subject: [PATCH 066/213] filter-branch: added missing warn function --tag-name-filter may have failed before because warn is used for reporting but was not available. Signed-off-by: Steffen Prohaska Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 4 ++++ 1 file changed, 4 insertions(+) mode change 100755 => 100644 git-filter-branch.sh diff --git a/git-filter-branch.sh b/git-filter-branch.sh old mode 100755 new mode 100644 index c22266b486..6cf67df5d6 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -13,6 +13,10 @@ set -e USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] DESTBRANCH [REV-RANGE]" . git-sh-setup +warn () { + echo "$*" >&2 +} + map() { # if it was not rewritten, take the original From 32c37c123741bee79617a6830257519c53681704 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Wed, 4 Jul 2007 09:32:47 +0200 Subject: [PATCH 067/213] filter-branch documentation: some more touch-ups. - The map function used to fail, but no longer does (since 3520e1e8687.) - Fix the "edge-graft" example. - Show the same using .git/info/grafts. Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- Documentation/git-filter-branch.txt | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 363287d0ab..219a81db0c 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -58,8 +58,9 @@ and GIT_COMMITTER_DATE are set according to the current commit. A 'map' function is available that takes an "original sha1 id" argument and outputs a "rewritten sha1 id" if the commit has been already -rewritten, fails otherwise; the 'map' function can return several -ids on separate lines if your commit filter emitted multiple commits. +rewritten, and "original sha1 id" otherwise; the 'map' function can +return several ids on separate lines if your commit filter emitted +multiple commits. OPTIONS @@ -166,12 +167,13 @@ git filter-branch --index-filter 'git update-index --remove filename' newbranch Now, you will get the rewritten history saved in the branch 'newbranch' (your current branch is left untouched). -To "etch-graft" a commit to the revision history (set a commit to be -the parent of the current initial commit and propagate that): +To set a commit (which typically is at the tip of another +history) to be the parent of the current initial commit, in +order to paste the other history behind the current history: ----------------------------------------------------------------------- -git filter-branch --parent-filter sed\ 's/^$/-p /' newbranch ----------------------------------------------------------------------- +------------------------------------------------------------------------ +git filter-branch --parent-filter 'sed "s/^\$/-p /"' newbranch +------------------------------------------------------------------------ (if the parent string is empty - therefore we are dealing with the initial commit - add graftcommit as a parent). Note that this assumes @@ -183,6 +185,13 @@ git filter-branch --parent-filter \ 'cat; test $GIT_COMMIT = && echo "-p "' newbranch ------------------------------------------------------------------------------- +or even simpler: + +----------------------------------------------- +echo "$commit-id $graft-id" >> .git/info/grafts +git filter-branch newbranch $graft-id.. +----------------------------------------------- + To remove commits authored by "Darl McBribe" from the history: ------------------------------------------------------------------------------ From 1eb96a25c9e76b70ca3f335bce7e60d66220eaa9 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 4 Jul 2007 14:06:28 -0400 Subject: [PATCH 068/213] git-gui: Correct resizing of remote branch delete dialog The status field of the remote branch delete dialog was marked to expand, which meant that if the user grew the window vertically most of the new vertical height was given to the status field and not to the branch list. Since the status field is just a single line of text there is no reason for it to gain additional height, instead we should make sure all additional height goes to the branch list. Signed-off-by: Shawn O. Pearce --- lib/remote_branch_delete.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/remote_branch_delete.tcl b/lib/remote_branch_delete.tcl index b83e1b6315..d7e2b8db45 100644 --- a/lib/remote_branch_delete.tcl +++ b/lib/remote_branch_delete.tcl @@ -98,10 +98,10 @@ constructor dialog {} { button $w.heads.footer.rescan \ -text {Rescan} \ -command [cb _rescan] - pack $w.heads.footer.status -side left -fill x -expand 1 + pack $w.heads.footer.status -side left -fill x pack $w.heads.footer.rescan -side right - pack $w.heads.footer -side bottom -fill x -expand 1 + pack $w.heads.footer -side bottom -fill x pack $w.heads.sby -side right -fill y pack $w.heads.l -side left -fill both -expand 1 pack $w.heads -fill both -expand 1 -pady 5 -padx 5 From 7730fbe62490f9e6ee33f6136ecd0e75869894e3 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 4 Jul 2007 14:07:42 -0700 Subject: [PATCH 069/213] git-svn: fix blocking with svn:// servers after do_switch We now explicitly disconnect before starting new SVN::Ra connections. SVN::Ra objects will automatically be disconnected from the server on DESTROY. SVN servers seem to have problems accepting multiple connections from one client, and the SVN library has trouble being connected to multiple servers at once. This appears to cause opening the second connection to block, and cause git-svn to be unusable after using the do_switch() function. git-svn opens another connection because a workaround is necesary for the buggy reparent function handling on certain versions of svn:// and svn+ssh:// servers. Instead of using the reparent function (analogous to chdir), it will reopen a new connection to a different URL on the SVN server. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 1 + 1 file changed, 1 insertion(+) diff --git a/git-svn.perl b/git-svn.perl index 51979f9639..b3dffccf38 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3002,6 +3002,7 @@ sub new { \&Git::SVN::Prompt::username, 2), ]); my $config = SVN::Core::config_get_config($config_dir); + $RA = undef; my $self = SVN::Ra->new(url => $url, auth => $baton, config => $config, pool => SVN::Pool->new, From d97bc5de929e525add9977a9c1ab3834b8c04657 Mon Sep 17 00:00:00 2001 From: Andrew Ruder Date: Wed, 4 Jul 2007 17:21:49 -0500 Subject: [PATCH 070/213] Remove USE_PAGER from git-pickaxe and git-annotate git-blame (and friends) specifically leave the pager turned off in the case that --incremental is specified as this isn't for human consumption. git-pickaxe and git-annotate will turn it on themselves otherwise. Signed-off-by: Andrew Ruder Signed-off-by: Junio C Hamano --- git.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git.c b/git.c index 727aabcbbe..a647f9c61e 100644 --- a/git.c +++ b/git.c @@ -303,7 +303,7 @@ static void handle_internal_command(int argc, const char **argv) const char *cmd = argv[0]; static struct cmd_struct commands[] = { { "add", cmd_add, RUN_SETUP | NEED_WORK_TREE }, - { "annotate", cmd_annotate, RUN_SETUP | USE_PAGER }, + { "annotate", cmd_annotate, RUN_SETUP }, { "apply", cmd_apply }, { "archive", cmd_archive }, { "blame", cmd_blame, RUN_SETUP }, @@ -345,7 +345,7 @@ static void handle_internal_command(int argc, const char **argv) { "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE }, { "name-rev", cmd_name_rev, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, - { "pickaxe", cmd_blame, RUN_SETUP | USE_PAGER }, + { "pickaxe", cmd_blame, RUN_SETUP }, { "prune", cmd_prune, RUN_SETUP }, { "prune-packed", cmd_prune_packed, RUN_SETUP }, { "push", cmd_push, RUN_SETUP }, From 1308c17b3e6bd3f5636f5b9bcadb2fbdf559009d Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Wed, 4 Jul 2007 22:09:10 +0200 Subject: [PATCH 071/213] Allow rebase to run if upstream is completely merged Consider this history: o--o-...-B <- origin \ \ x--x--M--x--x <- master In this situation, rebase considers master fully up-to-date and would not do anything. However, if there were additional commits on origin, the rebase would run and move the commits x on top of origin. Here we change rebase to short-circuit out only if the history since origin is strictly linear. Consequently, the above as well as a history like this would be linearized: o--o <- origin \ x--x \ \ x--M--x--x <- master Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- git-rebase.sh | 8 +++++--- t/t3400-rebase.sh | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/git-rebase.sh b/git-rebase.sh index c590661179..7a02f2975d 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -305,10 +305,12 @@ branch=$(git rev-parse --verify "${branch_name}^0") || exit # Now we are rebasing commits $upstream..$branch on top of $onto -# Check if we are already based on $onto, but this should be -# done only when upstream and onto are the same. +# Check if we are already based on $onto with linear history, +# but this should be done only when upstream and onto are the same. mb=$(git merge-base "$onto" "$branch") -if test "$upstream" = "$onto" && test "$mb" = "$onto" +if test "$upstream" = "$onto" && test "$mb" = "$onto" && + # linear history? + ! git rev-list --parents "$onto".."$branch" | grep " .* " > /dev/null then echo >&2 "Current branch $branch_name is up to date." exit 0 diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 95f3a2a556..62205b2531 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -12,7 +12,7 @@ This test runs git rebase and checks that the author information is not lost. export GIT_AUTHOR_EMAIL=bogus_email_address test_expect_success \ - 'prepare repository with topic branch, then rebase against master' \ + 'prepare repository with topic branches' \ 'echo First > A && git update-index --add A && git-commit -m "Add A." && @@ -24,11 +24,48 @@ test_expect_success \ echo Third >> A && git update-index A && git-commit -m "Modify A." && + git checkout -b side my-topic-branch && + echo Side >> C && + git add C && + git commit -m "Add C" && + git checkout -b nonlinear my-topic-branch && + echo Edit >> B && + git add B && + git commit -m "Modify B" && + git merge side && + git checkout -b upstream-merged-nonlinear && + git merge master && git checkout -f my-topic-branch && + git tag topic +' + +test_expect_success 'rebase against master' ' git rebase master' test_expect_failure \ 'the rebase operation should not have destroyed author information' \ 'git log | grep "Author:" | grep "<>"' +test_expect_success 'rebase after merge master' ' + git reset --hard topic && + git merge master && + git rebase master && + ! git show | grep "^Merge:" +' + +test_expect_success 'rebase of history with merges is linearized' ' + git checkout nonlinear && + test 4 = $(git rev-list master.. | wc -l) && + git rebase master && + test 3 = $(git rev-list master.. | wc -l) +' + +test_expect_success \ + 'rebase of history with merges after upstream merge is linearized' ' + git checkout upstream-merged-nonlinear && + test 5 = $(git rev-list master.. | wc -l) && + git rebase master && + test 3 = $(git rev-list master.. | wc -l) +' + test_done From 114fd812f78ea375ee6782d4ff0203f3ae20b076 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 4 Jul 2007 22:09:20 -0700 Subject: [PATCH 072/213] Fix git-stash(1) markup. Noticed by Randal L. Schwartz. Signed-off-by: Junio C Hamano --- Documentation/git-stash.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 35888b43c8..ad95ed9ce1 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -85,7 +85,7 @@ the `HEAD` commit. The ancestry graph looks like this: .----W / / - ...--H----I + -----H----I where `H` is the `HEAD` commit, `I` is a commit that records the state of the index, and `W` is a commit that records the state of the working From 37ba05619c76f9dbde35c418c6fc8af7bcda24c8 Mon Sep 17 00:00:00 2001 From: Andrew Ruder Date: Wed, 4 Jul 2007 17:21:36 -0500 Subject: [PATCH 073/213] Add urls.txt to git-clone man page Since git-clone is one of the many commands taking URLs to remote repositories as an argument, it should include the URL-types list from urls.txt. Split up urls.txt into urls.txt and urls-remotes.txt. The latter should be used by anything besides git-clone where a discussion of using .git/config and .git/remotes/ to name URLs just doesn't make as much sense. Signed-off-by: Andrew Ruder Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 7 +++-- Documentation/git-fetch.txt | 2 +- Documentation/git-pull.txt | 2 +- Documentation/git-push.txt | 2 +- Documentation/urls-remotes.txt | 55 ++++++++++++++++++++++++++++++++++ Documentation/urls.txt | 54 --------------------------------- 6 files changed, 63 insertions(+), 59 deletions(-) create mode 100644 Documentation/urls-remotes.txt diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 4a5bab510e..2f39864b8e 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -106,8 +106,9 @@ OPTIONS as patches. :: - The (possibly remote) repository to clone from. It can - be any URL git-fetch supports. + The (possibly remote) repository to clone from. See the + <> section below for more information on specifying + repositories. :: The name of a new directory to clone into. The "humanish" @@ -116,6 +117,8 @@ OPTIONS for "host.xz:foo/.git"). Cloning into an existing directory is not allowed. +include::urls.txt[] + Examples -------- diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt index 5fbeab76b7..9003473596 100644 --- a/Documentation/git-fetch.txt +++ b/Documentation/git-fetch.txt @@ -35,7 +35,7 @@ include::fetch-options.txt[] include::pull-fetch-param.txt[] -include::urls.txt[] +include::urls-remotes.txt[] SEE ALSO -------- diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index 84693f8b10..e1eb2c1d00 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -29,7 +29,7 @@ include::fetch-options.txt[] include::pull-fetch-param.txt[] -include::urls.txt[] +include::urls-remotes.txt[] include::merge-strategies.txt[] diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 665f6dc709..74a0da1ed4 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -95,7 +95,7 @@ the remote repository. -v:: Run verbosely. -include::urls.txt[] +include::urls-remotes.txt[] Examples diff --git a/Documentation/urls-remotes.txt b/Documentation/urls-remotes.txt new file mode 100644 index 0000000000..5dd1f836c6 --- /dev/null +++ b/Documentation/urls-remotes.txt @@ -0,0 +1,55 @@ +include::urls.txt[] + +REMOTES +------- + +In addition to the above, as a short-hand, the name of a +file in `$GIT_DIR/remotes` directory can be given; the +named file should be in the following format: + +------------ + URL: one of the above URL format + Push: + Pull: + +------------ + +Then such a short-hand is specified in place of + without parameters on the command +line, specified on `Push:` lines or `Pull:` +lines are used for `git-push` and `git-fetch`/`git-pull`, +respectively. Multiple `Push:` and `Pull:` lines may +be specified for additional branch mappings. + +Or, equivalently, in the `$GIT_DIR/config` (note the use +of `fetch` instead of `Pull:`): + +------------ + [remote ""] + url = + push = + fetch = + +------------ + +The name of a file in `$GIT_DIR/branches` directory can be +specified as an older notation short-hand; the named +file should contain a single line, a URL in one of the +above formats, optionally followed by a hash `#` and the +name of remote head (URL fragment notation). +`$GIT_DIR/branches/` file that stores a +without the fragment is equivalent to have this in the +corresponding file in the `$GIT_DIR/remotes/` directory. + +------------ + URL: + Pull: refs/heads/master: + +------------ + +while having `#` is equivalent to + +------------ + URL: + Pull: refs/heads/: +------------ diff --git a/Documentation/urls.txt b/Documentation/urls.txt index 745f9677d0..781df4174b 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.txt @@ -32,57 +32,3 @@ To sync with a local directory, use: =============================================================== - /path/to/repo.git/ =============================================================== - -REMOTES -------- - -In addition to the above, as a short-hand, the name of a -file in `$GIT_DIR/remotes` directory can be given; the -named file should be in the following format: - ------------- - URL: one of the above URL format - Push: - Pull: - ------------- - -Then such a short-hand is specified in place of - without parameters on the command -line, specified on `Push:` lines or `Pull:` -lines are used for `git-push` and `git-fetch`/`git-pull`, -respectively. Multiple `Push:` and `Pull:` lines may -be specified for additional branch mappings. - -Or, equivalently, in the `$GIT_DIR/config` (note the use -of `fetch` instead of `Pull:`): - ------------- - [remote ""] - url = - push = - fetch = - ------------- - -The name of a file in `$GIT_DIR/branches` directory can be -specified as an older notation short-hand; the named -file should contain a single line, a URL in one of the -above formats, optionally followed by a hash `#` and the -name of remote head (URL fragment notation). -`$GIT_DIR/branches/` file that stores a -without the fragment is equivalent to have this in the -corresponding file in the `$GIT_DIR/remotes/` directory. - ------------- - URL: - Pull: refs/heads/master: - ------------- - -while having `#` is equivalent to - ------------- - URL: - Pull: refs/heads/: ------------- From 9f62e18a60dd2f636bbdf849f66a00a5906b1cea Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 4 Jul 2007 22:46:09 -0700 Subject: [PATCH 074/213] git-stash: allow more descriptive reminder message when saving This allows you to say: $ git stash starting to implement X while creating a stash, and the resulting "stash list entry would read as: $ git stash list stash@{0}: On master: starting to implement X instead of the default message which talks about the commit the stash happens to be based on (hence does not have much to do with what the stashed change is trying to do). Signed-off-by: Junio C Hamano --- git-stash.sh | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/git-stash.sh b/git-stash.sh index fa8ae7bc29..f01494dc1b 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -23,6 +23,8 @@ clear_stash () { } save_stash () { + stash_msg="$1" + if no_changes then echo >&2 'No local changes to save' @@ -67,13 +69,19 @@ save_stash () { die "Cannot save the current worktree state" # create the stash - w_commit=$(printf 'WIP on %s\n' "$msg" | + if test -z "$stash_msg" + then + stash_msg=$(printf 'WIP on %s' "$msg") + else + stash_msg=$(printf 'On %s: %s' "$branch" "$stash_msg") + fi + w_commit=$(printf '%s\n' "$stash_msg" | git commit-tree $w_tree -p $b_commit -p $i_commit) || die "Cannot record working tree state" - git update-ref -m "WIP on $msg" $ref_stash $w_commit || + git update-ref -m "$stash_msg" $ref_stash $w_commit || die "Cannot save the current status" - printf >&2 'Saved WIP on %s\n' "$msg" + printf >&2 'Saved "%s"\n' "$stash_msg" } have_stash () { @@ -157,9 +165,14 @@ apply) clear) clear_stash ;; -save | '') - save_stash && git-reset --hard +help | usage) + usage ;; *) - usage + if test $# -gt 0 && test "$1" = save + then + shift + fi + save_stash "$*" && git-reset --hard + ;; esac From 6cb93bf478e7dd6253c9a644aff8758ce9aacf49 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Thu, 5 Jul 2007 17:07:48 +0100 Subject: [PATCH 075/213] filter-branch documentation: clarify which filters are eval'ed All filters, except the commit filter, are evaluated. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-filter-branch.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 219a81db0c..eaea82d0a6 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -50,7 +50,8 @@ Filters ~~~~~~~ The filters are applied in the order as listed below. The -argument is always evaluated in shell using the 'eval' command. +argument is always evaluated in shell using the 'eval' command (with the +notable exception of the commit filter, for technical reasons). Prior to that, the $GIT_COMMIT environment variable will be set to contain the id of the commit being rewritten. Also, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, From 09ff69bb39b386e24a39723d9e20263a915bc6d6 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Fri, 6 Jul 2007 00:06:56 +0200 Subject: [PATCH 076/213] Add -v|--verbose to git remote to show remote url Many other commands already have such an option, and I find it practical to see where all the remotes actually come from. Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- git-remote.perl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/git-remote.perl b/git-remote.perl index b59cafdf87..01cf480221 100755 --- a/git-remote.perl +++ b/git-remote.perl @@ -319,9 +319,21 @@ sub add_usage { exit(1); } +local $VERBOSE = 0; +@ARGV = grep { + if ($_ eq '-v' or $_ eq '--verbose') { + $VERBOSE=1; + 0 + } else { + 1 + } +} @ARGV; + if (!@ARGV) { for (sort keys %$remote) { - print "$_\n"; + print "$_"; + print "\t$remote->{$_}->{URL}" if $VERBOSE; + print "\n"; } } elsif ($ARGV[0] eq 'show') { From 8c1ce0f46b85d40f215084eed7313896300082df Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 4 Jul 2007 15:36:01 +0100 Subject: [PATCH 077/213] filter-branch: fail gracefully when a filter fails A common mistake is to provide a filter which fails unwantedly. For example, this will stop in the middle: git filter-branch --env-filter ' test $GIT_COMMITTER_EMAIL = xyz && export GIT_COMMITTER_EMAIL = abc' rewritten When $GIT_COMMITTER_EMAIL is not "xyz", the test fails, and consequently the whole filter has a non-zero exit status. However, as demonstrated in this example, filter-branch would just stop, and the user would be none the wiser. Also, a failing msg-filter would not have been caught, as was the case with one of the tests. This patch fixes both issues, by paying attention to the exit status of msg-filter, and by saying what failed before exiting. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 39 +++++++++++++++++++++++++++++---------- t/t7003-filter-branch.sh | 8 +++++++- 2 files changed, 36 insertions(+), 11 deletions(-) mode change 100644 => 100755 git-filter-branch.sh diff --git a/git-filter-branch.sh b/git-filter-branch.sh old mode 100644 new mode 100755 index 6cf67df5d6..d77902d34d --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -28,6 +28,16 @@ map() fi } +# override die(): this version puts in an extra line break, so that +# the progress is still visible + +die() +{ + echo >&2 + echo "$*" >&2 + exit 1 +} + # When piped a commit, output a script to set the ident of either # "author" or "committer @@ -181,23 +191,29 @@ while read commit parents; do export GIT_COMMIT=$commit git cat-file commit "$commit" >../commit - eval "$(set_ident AUTHOR <../commit)" - eval "$(set_ident COMMITTER <../commit)" - eval "$filter_env" < /dev/null + eval "$(set_ident AUTHOR <../commit)" || + die "setting author failed for commit $commit" + eval "$(set_ident COMMITTER <../commit)" || + die "setting committer failed for commit $commit" + eval "$filter_env" < /dev/null || + die "env filter failed: $filter_env" if [ "$filter_tree" ]; then git checkout-index -f -u -a # files that $commit removed are now still in the working tree; # remove them, else they would be added again git ls-files -z --others | xargs -0 rm -f - eval "$filter_tree" < /dev/null + eval "$filter_tree" < /dev/null || + die "tree filter failed: $filter_tree" + git diff-index -r $commit | cut -f 2- | tr '\n' '\0' | \ xargs -0 git update-index --add --replace --remove git ls-files -z --others | \ xargs -0 git update-index --add --replace --remove fi - eval "$filter_index" < /dev/null + eval "$filter_index" < /dev/null || + die "index filter failed: $filter_index" parentstr= for parent in $parents; do @@ -206,13 +222,15 @@ while read commit parents; do done done if [ "$filter_parent" ]; then - parentstr="$(echo "$parentstr" | eval "$filter_parent")" + parentstr="$(echo "$parentstr" | eval "$filter_parent")" || + die "parent filter failed: $filter_parent" fi sed -e '1,/^$/d' <../commit | \ - eval "$filter_msg" | \ - sh -c "$filter_commit" "git commit-tree" $(git write-tree) \ - $parentstr > ../map/$commit + eval "$filter_msg" > ../message || + die "msg filter failed: $filter_msg" + sh -c "$filter_commit" "git commit-tree" \ + $(git write-tree) $parentstr < ../message > ../map/$commit done <../revs src_head=$(tail -n 1 ../revs | sed -e 's/ .*//') @@ -249,7 +267,8 @@ if [ "$filter_tag_name" ]; then [ -f "../map/$sha1" ] || continue new_sha1="$(cat "../map/$sha1")" export GIT_COMMIT="$sha1" - new_ref="$(echo "$ref" | eval "$filter_tag_name")" + new_ref="$(echo "$ref" | eval "$filter_tag_name")" || + die "tag name filter failed: $filter_tag_name" echo "$ref -> $new_ref ($sha1 -> $new_sha1)" diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 451ac861af..4ddd656e84 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -107,13 +107,19 @@ test_expect_success 'use index-filter to move into a subdirectory' ' mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved && test -z "$(git diff HEAD directorymoved:newsubdir)"' +test_expect_success 'stops when msg filter fails' ' + ! git-filter-branch --msg-filter false nonono && + rm -rf .git-rewrite && + ! git rev-parse nonono +' + test_expect_success 'author information is preserved' ' : > i && git add i && test_tick && GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips && git-filter-branch --msg-filter "cat; \ - test \$GIT_COMMIT = $(git rev-parse master) && \ + test \$GIT_COMMIT != $(git rev-parse master) || \ echo Hallo" \ preserved-author && test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l) From 8960b5a7dfb160be65dc9122df8c7603a5f8aced Mon Sep 17 00:00:00 2001 From: Alecs King Date: Fri, 6 Jul 2007 00:21:16 +0800 Subject: [PATCH 078/213] fix remote.origin.url in tutorial.txt Bob cloned from Alice. The origin url is actually Alice's repo. Signed-off-by: Alecs King Signed-off-by: Junio C Hamano --- Documentation/tutorial.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt index 118ff72869..53403c6db3 100644 --- a/Documentation/tutorial.txt +++ b/Documentation/tutorial.txt @@ -354,7 +354,7 @@ used for pulls: ------------------------------------- $ git config --get remote.origin.url -/home/bob/myrepo +/home/alice/project ------------------------------------- (The complete configuration created by git-clone is visible using From 68ad8910f7b090a431b2da4e5f7be3de96112fa7 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Fri, 6 Jul 2007 00:54:33 +0200 Subject: [PATCH 079/213] git-clone: split up long &&-command-chain and use a function for cleanup Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- git-clone.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/git-clone.sh b/git-clone.sh index 48dafa21cf..4ca91009dd 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -187,15 +187,24 @@ dir="$2" # Try using "humanish" part of source repo if user didn't specify one [ -z "$dir" ] && dir=$(echo "$repo" | sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g') [ -e "$dir" ] && die "destination directory '$dir' already exists." -mkdir -p "$dir" && -D=$(cd "$dir" && pwd) && -trap 'err=$?; cd ..; rm -rf "$D"; exit $err' 0 +D= +cleanup() { + err=$? + test -z "$D" && rm -rf "$dir" + cd .. + test -n "$D" && rm -rf "$D" + exit $err +} +trap cleanup 0 +mkdir -p "$dir" && D=$(cd "$dir" && pwd) || usage case "$bare" in yes) GIT_DIR="$D" ;; *) GIT_DIR="$D/.git" ;; -esac && export GIT_DIR && git init $quiet ${template+"$template"} || usage +esac && +export GIT_DIR && +git-init $quiet ${template+"$template"} || usage if test -n "$reference" then From 20ccef49689b3f4dc7510c63d9867e1969eed1e3 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Fri, 6 Jul 2007 01:10:44 +0200 Subject: [PATCH 080/213] make git-clone GIT_WORK_TREE aware If GIT_WORK_TREE is set git-clone will use that path for the working tree. Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- git-clone.sh | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/git-clone.sh b/git-clone.sh index 4ca91009dd..09225540e6 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -187,22 +187,29 @@ dir="$2" # Try using "humanish" part of source repo if user didn't specify one [ -z "$dir" ] && dir=$(echo "$repo" | sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g') [ -e "$dir" ] && die "destination directory '$dir' already exists." +[ yes = "$bare" ] && unset GIT_WORK_TREE +[ -n "$GIT_WORK_TREE" ] && [ -e "$GIT_WORK_TREE" ] && +die "working tree '$GIT_WORK_TREE' already exists." D= +W= cleanup() { err=$? test -z "$D" && rm -rf "$dir" + test -z "$W" && test -n "$GIT_WORK_TREE" && rm -rf "$GIT_WORK_TREE" cd .. test -n "$D" && rm -rf "$D" + test -n "$W" && rm -rf "$W" exit $err } trap cleanup 0 mkdir -p "$dir" && D=$(cd "$dir" && pwd) || usage -case "$bare" in -yes) - GIT_DIR="$D" ;; -*) - GIT_DIR="$D/.git" ;; -esac && +test -n "$GIT_WORK_TREE" && mkdir -p "$GIT_WORK_TREE" && +W=$(cd "$GIT_WORK_TREE" && pwd) && export GIT_WORK_TREE="$W" +if test yes = "$bare" || test -n "$GIT_WORK_TREE"; then + GIT_DIR="$D" +else + GIT_DIR="$D/.git" +fi && export GIT_DIR && git-init $quiet ${template+"$template"} || usage @@ -358,7 +365,11 @@ then done < "$GIT_DIR/CLONE_HEAD" fi -cd "$D" || exit +if test -n "$W"; then + cd "$W" || exit +else + cd "$D" || exit +fi if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD" then From 46f74f007b86452c4b4135f5145f94eefc994ea2 Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Thu, 5 Jul 2007 17:29:41 -0700 Subject: [PATCH 081/213] Prefer EMAIL to username@hostname. The environment variable $EMAIL gives a better default of user's preferred e-mail address than the hardcoded "username@hostname", as it is understood by many existing programs. We still honor GIT_*_EMAIL environment variables and user.email configuration variable give them higher precedence, so that the user can override $EMAIL or "username@hostname", as they are likely to be more specific to the context of working on a particular project. Signed-off-by: Matt Kraai Signed-off-by: Junio C Hamano --- ident.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ident.c b/ident.c index 3d49608e6f..6612d17eba 100644 --- a/ident.c +++ b/ident.c @@ -83,11 +83,18 @@ static void setup_ident(void) } if (!git_default_email[0]) { - if (!pw) - pw = getpwuid(getuid()); - if (!pw) - die("You don't exist. Go away!"); - copy_email(pw); + const char *email = getenv("EMAIL"); + + if (email && email[0]) + strlcpy(git_default_email, email, + sizeof(git_default_email)); + else { + if (!pw) + pw = getpwuid(getuid()); + if (!pw) + die("You don't exist. Go away!"); + copy_email(pw); + } } /* And set the default date */ @@ -197,8 +204,6 @@ const char *fmt_ident(const char *name, const char *email, name = git_default_name; if (!email) email = git_default_email; - if (!email) - email = getenv("EMAIL"); if (!*name) { struct passwd *pw; From 29a3eefde111f6a24292163c4308f00ab3572627 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 6 Jul 2007 00:18:54 -0700 Subject: [PATCH 082/213] Introduce diff_filespec_is_binary() This replaces an explicit initialization of filespec->is_binary field used for rename/break followed by direct access to that field with a wrapper function that lazily iniaitlizes and accesses the field. We would add more attribute accesses for the use of diff routines, and it would be better to make this abstraction earlier. Signed-off-by: Junio C Hamano --- diff.c | 71 ++++++++++++++++++++++++------------------------ diffcore-delta.c | 2 +- diffcore.h | 2 ++ 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/diff.c b/diff.c index 19589707c4..16ea7100df 100644 --- a/diff.c +++ b/diff.c @@ -1102,30 +1102,45 @@ static void setup_diff_attr_check(struct git_attr_check *check) { static struct git_attr *attr_diff; - if (!attr_diff) + if (!attr_diff) { attr_diff = git_attr("diff", 4); - check->attr = attr_diff; + } + check[0].attr = attr_diff; } -static int file_is_binary(struct diff_filespec *one) +static void diff_filespec_check_attr(struct diff_filespec *one) { - struct git_attr_check attr_diff_check; + struct git_attr_check attr_diff_check[1]; - setup_diff_attr_check(&attr_diff_check); - if (!git_checkattr(one->path, 1, &attr_diff_check)) { - const char *value = attr_diff_check.value; + if (one->checked_attr) + return; + + setup_diff_attr_check(attr_diff_check); + one->is_binary = 0; + + if (!git_checkattr(one->path, ARRAY_SIZE(attr_diff_check), attr_diff_check)) { + const char *value; + + /* binaryness */ + value = attr_diff_check[0].value; if (ATTR_TRUE(value)) - return 0; + ; else if (ATTR_FALSE(value)) - return 1; + one->is_binary = 1; } - if (!one->data) { - if (!DIFF_FILE_VALID(one)) - return 0; + if (!one->data && DIFF_FILE_VALID(one)) diff_populate_filespec(one, 0); - } - return buffer_is_binary(one->data, one->size); + + if (one->data) + one->is_binary = buffer_is_binary(one->data, one->size); + +} + +int diff_filespec_is_binary(struct diff_filespec *one) +{ + diff_filespec_check_attr(one); + return one->is_binary; } static void builtin_diff(const char *name_a, @@ -1182,7 +1197,8 @@ static void builtin_diff(const char *name_a, if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); - if (!o->text && (file_is_binary(one) || file_is_binary(two))) { + if (!o->text && + (diff_filespec_is_binary(one) || diff_filespec_is_binary(two))) { /* Quite common confusing case */ if (mf1.size == mf2.size && !memcmp(mf1.ptr, mf2.ptr, mf1.size)) @@ -1260,7 +1276,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); - if (file_is_binary(one) || file_is_binary(two)) { + if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) { data->is_binary = 1; data->added = mf2.size; data->deleted = mf1.size; @@ -1302,7 +1318,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b, if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); - if (file_is_binary(two)) + if (diff_filespec_is_binary(two)) goto free_and_return; else { /* Crazy xdl interfaces.. */ @@ -1880,8 +1896,8 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) if (o->binary) { mmfile_t mf; - if ((!fill_mmfile(&mf, one) && file_is_binary(one)) || - (!fill_mmfile(&mf, two) && file_is_binary(two))) + if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || + (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) abbrev = 40; } len += snprintf(msg + len, sizeof(msg) - len, @@ -2783,7 +2799,7 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1) return error("unable to read files to diff"); /* Maybe hash p->two? into the patch id? */ - if (file_is_binary(p->two)) + if (diff_filespec_is_binary(p->two)) continue; len1 = remove_space(p->one->path, strlen(p->one->path)); @@ -3011,21 +3027,6 @@ void diffcore_std(struct diff_options *options) if (options->quiet) return; - /* - * break/rename count similarity differently depending on - * the binary-ness. - */ - if ((options->break_opt != -1) || (options->detect_rename)) { - struct diff_queue_struct *q = &diff_queued_diff; - int i; - - for (i = 0; i < q->nr; i++) { - struct diff_filepair *p = q->queue[i]; - p->one->is_binary = file_is_binary(p->one); - p->two->is_binary = file_is_binary(p->two); - } - } - if (options->break_opt != -1) diffcore_break(options->break_opt); if (options->detect_rename) diff --git a/diffcore-delta.c b/diffcore-delta.c index a038b166c5..d9729e5ec2 100644 --- a/diffcore-delta.c +++ b/diffcore-delta.c @@ -129,7 +129,7 @@ static struct spanhash_top *hash_chars(struct diff_filespec *one) struct spanhash_top *hash; unsigned char *buf = one->data; unsigned int sz = one->size; - int is_text = !one->is_binary; + int is_text = !diff_filespec_is_binary(one); i = INITIAL_HASH_SIZE; hash = xmalloc(sizeof(*hash) + sizeof(struct spanhash) * (1<mode) != 0) unsigned should_free : 1; /* data should be free()'ed */ unsigned should_munmap : 1; /* data should be munmap()'ed */ + unsigned checked_attr : 1; unsigned is_binary : 1; /* data should be considered "binary" */ }; @@ -46,6 +47,7 @@ extern void fill_filespec(struct diff_filespec *, const unsigned char *, extern int diff_populate_filespec(struct diff_filespec *, int); extern void diff_free_filespec_data(struct diff_filespec *); +extern int diff_filespec_is_binary(struct diff_filespec *); struct diff_filepair { struct diff_filespec *one; From 30b250104d9307e1225031c7fc39b66643265ed1 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 4 Jul 2007 19:05:46 +0100 Subject: [PATCH 083/213] Future-proof source for changes in xdemitconf_t The instances of xdemitconf_t were initialized member by member. Instead, initialize them to all zero, so we do not have to update those places each time we introduce a new member. [jc: minimally fixed by getting rid of a new global] Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-blame.c | 2 +- builtin-rerere.c | 2 +- combine-diff.c | 3 +-- diff.c | 10 +++++----- merge-file.c | 1 + merge-tree.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/builtin-blame.c b/builtin-blame.c index da23a6f9c9..0519339098 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -518,8 +518,8 @@ static struct patch *compare_buffer(mmfile_t *file_p, mmfile_t *file_o, xdemitcb_t ecb; xpp.flags = xdl_opts; + memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = context; - xecfg.flags = 0; ecb.outf = xdiff_outf; ecb.priv = &state; memset(&state, 0, sizeof(state)); diff --git a/builtin-rerere.c b/builtin-rerere.c index 29fb075d29..01f3848f14 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -282,8 +282,8 @@ static int diff_two(const char *file1, const char *label1, printf("--- a/%s\n+++ b/%s\n", label1, label2); fflush(stdout); xpp.flags = XDF_NEED_MINIMAL; + memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = 3; - xecfg.flags = 0; ecb.outf = outf; xdl_diff(&minus, &plus, &xpp, &xecfg, &ecb); diff --git a/combine-diff.c b/combine-diff.c index ea3ca5f950..ef622340a5 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -215,8 +215,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file, parent_file.ptr = grab_blob(parent, &sz); parent_file.size = sz; xpp.flags = XDF_NEED_MINIMAL; - xecfg.ctxlen = 0; - xecfg.flags = 0; + memset(&xecfg, 0, sizeof(xecfg)); ecb.outf = xdiff_outf; ecb.priv = &state; memset(&state, 0, sizeof(state)); diff --git a/diff.c b/diff.c index 16ea7100df..d10e848c79 100644 --- a/diff.c +++ b/diff.c @@ -390,6 +390,7 @@ static void diff_words_show(struct diff_words_data *diff_words) mmfile_t minus, plus; int i; + memset(&xecfg, 0, sizeof(xecfg)); minus.size = diff_words->minus.text.size; minus.ptr = xmalloc(minus.size); memcpy(minus.ptr, diff_words->minus.text.ptr, minus.size); @@ -408,7 +409,6 @@ static void diff_words_show(struct diff_words_data *diff_words) xpp.flags = XDF_NEED_MINIMAL; xecfg.ctxlen = diff_words->minus.alloc + diff_words->plus.alloc; - xecfg.flags = 0; ecb.outf = xdiff_outf; ecb.priv = diff_words; diff_words->xm.consume = fn_out_diff_words_aux; @@ -1218,6 +1218,7 @@ static void builtin_diff(const char *name_a, xdemitcb_t ecb; struct emit_callback ecbdata; + memset(&xecfg, 0, sizeof(xecfg)); memset(&ecbdata, 0, sizeof(ecbdata)); ecbdata.label_path = lbl; ecbdata.color_diff = o->color_diff; @@ -1286,9 +1287,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b, xdemitconf_t xecfg; xdemitcb_t ecb; + memset(&xecfg, 0, sizeof(xecfg)); xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; - xecfg.ctxlen = 0; - xecfg.flags = 0; ecb.outf = xdiff_outf; ecb.priv = diffstat; xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); @@ -1326,9 +1326,8 @@ static void builtin_checkdiff(const char *name_a, const char *name_b, xdemitconf_t xecfg; xdemitcb_t ecb; + memset(&xecfg, 0, sizeof(xecfg)); xpp.flags = XDF_NEED_MINIMAL; - xecfg.ctxlen = 0; - xecfg.flags = 0; ecb.outf = xdiff_outf; ecb.priv = &data; xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); @@ -2780,6 +2779,7 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1) struct diff_filepair *p = q->queue[i]; int len1, len2; + memset(&xecfg, 0, sizeof(xecfg)); if (p->status == 0) return error("internal diff status error"); if (p->status == DIFF_STATUS_UNKNOWN) diff --git a/merge-file.c b/merge-file.c index 748d15c0e0..1e031eafe0 100644 --- a/merge-file.c +++ b/merge-file.c @@ -62,6 +62,7 @@ static int generate_common_file(mmfile_t *res, mmfile_t *f1, mmfile_t *f2) xdemitcb_t ecb; xpp.flags = XDF_NEED_MINIMAL; + memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = 3; xecfg.flags = XDL_EMIT_COMMON; ecb.outf = common_outf; diff --git a/merge-tree.c b/merge-tree.c index 3b8d9e6887..7d4f628444 100644 --- a/merge-tree.c +++ b/merge-tree.c @@ -106,8 +106,8 @@ static void show_diff(struct merge_list *entry) xdemitcb_t ecb; xpp.flags = XDF_NEED_MINIMAL; + memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = 3; - xecfg.flags = 0; ecb.outf = show_outf; ecb.priv = NULL; From f258475a6ede3617ae768b69e33f78cbab8312de Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 6 Jul 2007 00:45:10 -0700 Subject: [PATCH 084/213] Per-path attribute based hunk header selection. This makes"diff -p" hunk headers customizable via gitattributes mechanism. It is based on Johannes's earlier patch that allowed to define a single regexp to be used for everything. The mechanism to arrive at the regexp that is used to define hunk header is the same as other use of gitattributes. You assign an attribute, funcname (because "diff -p" typically uses the name of the function the patch is about as the hunk header), a simple string value. This can be one of the names of built-in pattern (currently, "java" is defined) or a custom pattern name, to be looked up from the configuration file. (in .gitattributes) *.java funcname=java *.perl funcname=perl (in .git/config) [funcname] java = ... # ugly and complicated regexp to override the built-in one. perl = ... # another ugly and complicated regexp to define a new one. Signed-off-by: Junio C Hamano --- diff.c | 96 +++++++++++++++++++++++++++++++++++++++- diffcore.h | 1 + t/t4018-diff-funcname.sh | 60 +++++++++++++++++++++++++ xdiff-interface.c | 71 +++++++++++++++++++++++++++++ xdiff-interface.h | 2 + xdiff/xdiff.h | 4 ++ xdiff/xemit.c | 37 ++++++++++------ 7 files changed, 256 insertions(+), 15 deletions(-) create mode 100644 t/t4018-diff-funcname.sh diff --git a/diff.c b/diff.c index d10e848c79..04e7e91adf 100644 --- a/diff.c +++ b/diff.c @@ -1101,22 +1101,26 @@ static void emit_binary_diff(mmfile_t *one, mmfile_t *two) static void setup_diff_attr_check(struct git_attr_check *check) { static struct git_attr *attr_diff; + static struct git_attr *attr_diff_func_name; if (!attr_diff) { attr_diff = git_attr("diff", 4); + attr_diff_func_name = git_attr("funcname", 8); } check[0].attr = attr_diff; + check[1].attr = attr_diff_func_name; } static void diff_filespec_check_attr(struct diff_filespec *one) { - struct git_attr_check attr_diff_check[1]; + struct git_attr_check attr_diff_check[2]; if (one->checked_attr) return; setup_diff_attr_check(attr_diff_check); one->is_binary = 0; + one->hunk_header_ident = NULL; if (!git_checkattr(one->path, ARRAY_SIZE(attr_diff_check), attr_diff_check)) { const char *value; @@ -1127,6 +1131,13 @@ static void diff_filespec_check_attr(struct diff_filespec *one) ; else if (ATTR_FALSE(value)) one->is_binary = 1; + + /* hunk header ident */ + value = attr_diff_check[1].value; + if (ATTR_TRUE(value) || ATTR_FALSE(value) || ATTR_UNSET(value)) + ; + else + one->hunk_header_ident = value; } if (!one->data && DIFF_FILE_VALID(one)) @@ -1143,6 +1154,82 @@ int diff_filespec_is_binary(struct diff_filespec *one) return one->is_binary; } +static struct hunk_header_regexp { + char *name; + char *regexp; + struct hunk_header_regexp *next; +} *hunk_header_regexp_list, **hunk_header_regexp_tail; + +static int hunk_header_config(const char *var, const char *value) +{ + static const char funcname[] = "funcname."; + struct hunk_header_regexp *hh; + + if (prefixcmp(var, funcname)) + return 0; + var += strlen(funcname); + for (hh = hunk_header_regexp_list; hh; hh = hh->next) + if (!strcmp(var, hh->name)) { + free(hh->regexp); + hh->regexp = xstrdup(value); + return 0; + } + hh = xcalloc(1, sizeof(*hh)); + hh->name = xstrdup(var); + hh->regexp = xstrdup(value); + hh->next = NULL; + *hunk_header_regexp_tail = hh; + return 0; +} + +static const char *hunk_header_regexp(const char *ident) +{ + struct hunk_header_regexp *hh; + + if (!hunk_header_regexp_tail) { + hunk_header_regexp_tail = &hunk_header_regexp_list; + git_config(hunk_header_config); + } + for (hh = hunk_header_regexp_list; hh; hh = hh->next) + if (!strcmp(ident, hh->name)) + return hh->regexp; + return NULL; +} + +static const char *diff_hunk_header_regexp(struct diff_filespec *one) +{ + const char *ident, *regexp; + + diff_filespec_check_attr(one); + ident = one->hunk_header_ident; + + if (!ident) + /* + * If the config file has "funcname.default" defined, that + * regexp is used; otherwise NULL is returned and xemit uses + * the built-in default. + */ + return hunk_header_regexp("default"); + + /* Look up custom "funcname.$ident" regexp from config. */ + regexp = hunk_header_regexp(ident); + if (regexp) + return regexp; + + /* + * And define built-in fallback patterns here. Note that + * these can be overriden by the user's config settings. + */ + if (!strcmp(ident, "java")) + return "!^[ ]*\\(catch\\|do\\|for\\|if\\|instanceof\\|" + "new\\|return\\|switch\\|throw\\|while\\)\n" + "^[ ]*\\(\\([ ]*" + "[A-Za-z_][A-Za-z_0-9]*\\)\\{2,\\}" + "[ ]*([^;]*$\\)"; + + return NULL; +} + static void builtin_diff(const char *name_a, const char *name_b, struct diff_filespec *one, @@ -1217,6 +1304,11 @@ static void builtin_diff(const char *name_a, xdemitconf_t xecfg; xdemitcb_t ecb; struct emit_callback ecbdata; + const char *hunk_header_regexp; + + hunk_header_regexp = diff_hunk_header_regexp(one); + if (!hunk_header_regexp) + hunk_header_regexp = diff_hunk_header_regexp(two); memset(&xecfg, 0, sizeof(xecfg)); memset(&ecbdata, 0, sizeof(ecbdata)); @@ -1226,6 +1318,8 @@ static void builtin_diff(const char *name_a, xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = o->context; xecfg.flags = XDL_EMIT_FUNCNAMES; + if (hunk_header_regexp) + xdiff_set_find_func(&xecfg, hunk_header_regexp); if (!diffopts) ; else if (!prefixcmp(diffopts, "--unified=")) diff --git a/diffcore.h b/diffcore.h index dcab7e20bf..05985147ea 100644 --- a/diffcore.h +++ b/diffcore.h @@ -27,6 +27,7 @@ struct diff_filespec { char *path; void *data; void *cnt_data; + const void *hunk_header_ident; unsigned long size; int xfrm_flags; /* for use by the xfrm */ unsigned short mode; /* file mode */ diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh new file mode 100644 index 0000000000..dc7a47b3f1 --- /dev/null +++ b/t/t4018-diff-funcname.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='Test custom diff function name patterns' + +. ./test-lib.sh + +LF=' +' + +cat > Beer.java << EOF +public class Beer +{ + int special; + public static void main(String args[]) + { + String s=" "; + for(int x = 99; x > 0; x--) + { + System.out.print(x + " bottles of beer on the wall " + + x + " bottles of beer\n" + + "Take one down, pass it around, " + (x - 1) + + " bottles of beer on the wall.\n"); + } + System.out.print("Go to the store, buy some more,\n" + + "99 bottles of beer on the wall.\n"); + } +} +EOF + +sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java + +test_expect_success 'default behaviour' ' + git diff Beer.java Beer-correct.java | + grep "^@@.*@@ public class Beer" +' + +test_expect_success 'preset java pattern' ' + echo "*.java funcname=java" >.gitattributes && + git diff Beer.java Beer-correct.java | + grep "^@@.*@@ public static void main(" +' + +git config funcname.java '!static +!String +[^ ].*s.*' + +test_expect_success 'custom pattern' ' + git diff Beer.java Beer-correct.java | + grep "^@@.*@@ int special;$" +' + +test_expect_success 'last regexp must not be negated' ' + git config diff.functionnameregexp "!static" && + ! git diff Beer.java Beer-correct.java +' + +test_done diff --git a/xdiff-interface.c b/xdiff-interface.c index e407cf11b1..be866d12d3 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -129,3 +129,74 @@ int buffer_is_binary(const char *ptr, unsigned long size) size = FIRST_FEW_BYTES; return !!memchr(ptr, 0, size); } + +struct ff_regs { + int nr; + struct ff_reg { + regex_t re; + int negate; + } *array; +}; + +static long ff_regexp(const char *line, long len, + char *buffer, long buffer_size, void *priv) +{ + char *line_buffer = xstrndup(line, len); /* make NUL terminated */ + struct ff_regs *regs = priv; + regmatch_t pmatch[2]; + int result = 0, i; + + for (i = 0; i < regs->nr; i++) { + struct ff_reg *reg = regs->array + i; + if (reg->negate ^ !!regexec(®->re, + line_buffer, 2, pmatch, 0)) { + free(line_buffer); + return -1; + } + } + i = pmatch[1].rm_so >= 0 ? 1 : 0; + line += pmatch[i].rm_so; + result = pmatch[i].rm_eo - pmatch[i].rm_so; + if (result > buffer_size) + result = buffer_size; + else + while (result > 0 && (isspace(line[result - 1]) || + line[result - 1] == '\n')) + result--; + memcpy(buffer, line, result); + free(line_buffer); + return result; +} + +void xdiff_set_find_func(xdemitconf_t *xecfg, const char *value) +{ + int i; + struct ff_regs *regs; + + xecfg->find_func = ff_regexp; + regs = xecfg->find_func_priv = xmalloc(sizeof(struct ff_regs)); + for (i = 0, regs->nr = 1; value[i]; i++) + if (value[i] == '\n') + regs->nr++; + regs->array = xmalloc(regs->nr * sizeof(struct ff_reg)); + for (i = 0; i < regs->nr; i++) { + struct ff_reg *reg = regs->array + i; + const char *ep = strchr(value, '\n'), *expression; + char *buffer = NULL; + + reg->negate = (*value == '!'); + if (reg->negate && i == regs->nr - 1) + die("Last expression must not be negated: %s", value); + if (*value == '!') + value++; + if (ep) + expression = buffer = xstrndup(value, ep - value); + else + expression = value; + if (regcomp(®->re, expression, 0)) + die("Invalid regexp to look for hunk header: %s", expression); + if (buffer) + free(buffer); + value = ep + 1; + } +} diff --git a/xdiff-interface.h b/xdiff-interface.h index 536f4e4d97..fb742dbb6b 100644 --- a/xdiff-interface.h +++ b/xdiff-interface.h @@ -20,4 +20,6 @@ int parse_hunk_header(char *line, int len, int read_mmfile(mmfile_t *ptr, const char *filename); int buffer_is_binary(const char *ptr, unsigned long size); +extern void xdiff_set_find_func(xdemitconf_t *xecfg, const char *line); + #endif diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 9402bb0799..c00ddaa6e9 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -73,9 +73,13 @@ typedef struct s_xdemitcb { int (*outf)(void *, mmbuffer_t *, int); } xdemitcb_t; +typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv); + typedef struct s_xdemitconf { long ctxlen; unsigned long flags; + find_func_t find_func; + void *find_func_priv; } xdemitconf_t; typedef struct s_bdiffparam { diff --git a/xdiff/xemit.c b/xdiff/xemit.c index 4b6e639112..d3d9c845c6 100644 --- a/xdiff/xemit.c +++ b/xdiff/xemit.c @@ -69,7 +69,24 @@ static xdchange_t *xdl_get_hunk(xdchange_t *xscr, xdemitconf_t const *xecfg) { } -static void xdl_find_func(xdfile_t *xf, long i, char *buf, long sz, long *ll) { +static long def_ff(const char *rec, long len, char *buf, long sz, void *priv) +{ + if (len > 0 && + (isalpha((unsigned char)*rec) || /* identifier? */ + *rec == '_' || /* also identifier? */ + *rec == '$')) { /* identifiers from VMS and other esoterico */ + if (len > sz) + len = sz; + while (0 < len && isspace((unsigned char)rec[len - 1])) + len--; + memcpy(buf, rec, len); + return len; + } + return -1; +} + +static void xdl_find_func(xdfile_t *xf, long i, char *buf, long sz, long *ll, + find_func_t ff, void *ff_priv) { /* * Be quite stupid about this for now. Find a line in the old file @@ -80,22 +97,12 @@ static void xdl_find_func(xdfile_t *xf, long i, char *buf, long sz, long *ll) { const char *rec; long len; - *ll = 0; while (i-- > 0) { len = xdl_get_rec(xf, i, &rec); - if (len > 0 && - (isalpha((unsigned char)*rec) || /* identifier? */ - *rec == '_' || /* also identifier? */ - *rec == '$')) { /* mysterious GNU diff's invention */ - if (len > sz) - len = sz; - while (0 < len && isspace((unsigned char)rec[len - 1])) - len--; - memcpy(buf, rec, len); - *ll = len; + if ((*ll = ff(rec, len, buf, sz, ff_priv)) >= 0) return; - } } + *ll = 0; } @@ -120,6 +127,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, xdchange_t *xch, *xche; char funcbuf[80]; long funclen = 0; + find_func_t ff = xecfg->find_func ? xecfg->find_func : def_ff; if (xecfg->flags & XDL_EMIT_COMMON) return xdl_emit_common(xe, xscr, ecb, xecfg); @@ -143,7 +151,8 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, if (xecfg->flags & XDL_EMIT_FUNCNAMES) { xdl_find_func(&xe->xdf1, s1, funcbuf, - sizeof(funcbuf), &funclen); + sizeof(funcbuf), &funclen, + ff, xecfg->find_func_priv); } if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2, funcbuf, funclen, ecb) < 0) From 150937c42591b0e9fb6c17f96c459d57b5f3bfdb Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 2 Jul 2007 12:14:49 +0100 Subject: [PATCH 085/213] Teach git-stash to "apply --index" When given this subcommand, git-stash will try to merge the stashed index into the current one. Only trivial merges are possible, since we have no index for the index ;-) If a trivial merge is not possible, git-stash will bail out with a hint to skip the --index option. For good measure, finally include a test case. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-stash.sh | 21 ++++++++++++++- t/t3903-stash.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100755 t/t3903-stash.sh diff --git a/git-stash.sh b/git-stash.sh index f01494dc1b..5c63ca5bce 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -111,6 +111,13 @@ apply_stash () { git diff-files --quiet || die 'Cannot restore on top of a dirty state' + unstash_index= + case "$1" in + --index) + unstash_index=t + shift + esac + # current index state c_tree=$(git write-tree) || die 'Cannot apply a stash in the middle of a merge' @@ -120,6 +127,15 @@ apply_stash () { b_tree=$(git rev-parse --verify "$s^:") || die "$*: no valid stashed state found" + test -z "$unstash_index" || { + git diff --binary $s^2^..$s^2 | git apply --cached + test $? -ne 0 && + die 'Conflicts in index. Try without --index.' + unstashed_index_tree=$(git-write-tree) || + die 'Could not save index tree' + git reset + } + eval " GITHEAD_$w_tree='Stashed changes' && GITHEAD_$c_tree='Updated upstream' && @@ -137,9 +153,12 @@ apply_stash () { die "Cannot unstage modified files" git-status rm -f "$a" + test -z "$unstash_index" || git read-tree $unstashed_index_tree else # Merge conflict; keep the exit status from merge-recursive - exit + status=$? + test -z "$unstash_index" || echo 'Index was not unstashed.' >&2 + exit $status fi } diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh new file mode 100755 index 0000000000..392ac1c5c5 --- /dev/null +++ b/t/t3903-stash.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E Schindelin +# + +test_description='Test git-stash' + +. ./test-lib.sh + +test_expect_success 'stash some dirty working directory' ' + echo 1 > file && + git add file && + test_tick && + git commit -m initial && + echo 2 > file && + git add file && + echo 3 > file && + test_tick && + git stash && + git diff-files --quiet && + git diff-index --cached --quiet HEAD +' + +cat > expect << EOF +diff --git a/file b/file +index 0cfbf08..00750ed 100644 +--- a/file ++++ b/file +@@ -1 +1 @@ +-2 ++3 +EOF + +test_expect_success 'parents of stash' ' + test $(git rev-parse stash^) = $(git rev-parse HEAD) && + git diff stash^2..stash > output && + diff -u output expect +' + +test_expect_success 'apply needs clean working directory' ' + echo 4 > other-file && + git add other-file && + echo 5 > other-file + ! git stash apply +' + +test_expect_success 'apply stashed changes' ' + git add other-file && + test_tick && + git commit -m other-file && + git stash apply && + test 3 = $(cat file) && + test 1 = $(git show :file) && + test 1 = $(git show HEAD:file) +' + +test_expect_success 'apply stashed changes (including index)' ' + git reset --hard HEAD^ && + echo 6 > other-file && + git add other-file && + test_tick && + git commit -m other-file && + git stash apply --index && + test 3 = $(cat file) && + test 2 = $(git show :file) && + test 1 = $(git show HEAD:file) +' + +test_done From 483891810c5f814ede2407999a0d0b961def246c Mon Sep 17 00:00:00 2001 From: Marcus Fritzsch Date: Fri, 6 Jul 2007 09:02:20 +0200 Subject: [PATCH 086/213] Fixed a formulation mistake in Documentation/user-manual.txt This one fixes a small formulation weirdness in Documentation/user-manual.txt Signed-off-by: Marcus Fritzsch Signed-off-by: Junio C Hamano --- Documentation/user-manual.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index ff7c71d4fb..c23077c724 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -2957,13 +2957,13 @@ developed. If you blow the directory cache away entirely, you generally haven't lost any information as long as you have the name of the tree that it described. -At the same time, the index is at the same time also the -staging area for creating new trees, and creating a new tree always -involves a controlled modification of the index file. In particular, -the index file can have the representation of an intermediate tree that -has not yet been instantiated. So the index can be thought of as a -write-back cache, which can contain dirty information that has not yet -been written back to the backing store. +At the same time, the index is also the staging area for creating +new trees, and creating a new tree always involves a controlled +modification of the index file. In particular, the index file can +have the representation of an intermediate tree that has not yet been +instantiated. So the index can be thought of as a write-back cache, +which can contain dirty information that has not yet been written back +to the backing store. From 95fd73ab22f9a9a1b7a1275c934991340eeb8839 Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Fri, 6 Jul 2007 18:23:54 -0700 Subject: [PATCH 087/213] Change "added.moved or removed" to "added, moved or removed" in Signed-off-by: Matt Kraai Signed-off-by: Junio C Hamano --- Documentation/core-intro.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/core-intro.txt b/Documentation/core-intro.txt index eea44d9d56..f3cc2238c7 100644 --- a/Documentation/core-intro.txt +++ b/Documentation/core-intro.txt @@ -528,7 +528,7 @@ paths that have been trivially merged. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sadly, many merges aren't trivial. If there are files that have -been added.moved or removed, or if both branches have modified the +been added, moved or removed, or if both branches have modified the same file, you will be left with an index tree that contains "merge entries" in it. Such an index tree can 'NOT' be written out to a tree object, and you will have to resolve any such merge clashes using From b2493649fe41f8a0db48ff4e809ea53c8a304a61 Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Fri, 6 Jul 2007 17:56:31 -0700 Subject: [PATCH 088/213] Add [verse] to the SYNOPSIS section of git-submodule.txt. The SYNOPSIS section of git-submodule.txt contains two forms. Since it doesn't use the verse style, the line boundary between them is not preserved and the second form can appear on the same line as the first form. Adding [verse] enables the verse style, which preserves the line boundary between them. Signed-off-by: Matt Kraai Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 7f0904e293..d76ae473bc 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -8,6 +8,7 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- +[verse] 'git-submodule' [--quiet] [-b branch] add [] 'git-submodule' [--quiet] [--cached] [status|init|update] [--] [...] From b4372ef136b0a5a2c1dbd88a11dd72b478d0e0a5 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 6 Jul 2007 13:05:59 +0100 Subject: [PATCH 089/213] Enable "git rerere" by the config variable rerere.enabled Earlier, "git rerere" was enabled by creating the directory .git/rr-cache. That is definitely not in line with most other features, which are enabled by a config variable. So, check the config variable "rerere.enabled". If it is set to "false" explicitely, do not activate rerere, even if .git/rr-cache exists. This should help when you want to disable rerere temporarily. If "rerere.enabled" is not set at all, fall back to detection of the directory .git/rr-cache. [jc: with minimum tweaks] Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/config.txt | 5 +++++ Documentation/git-rerere.txt | 4 ++-- builtin-rerere.c | 32 ++++++++++++++++++++++++++++---- contrib/emacs/git.el | 3 +-- git-am.sh | 15 +++------------ git-commit.sh | 5 +---- git-merge.sh | 5 +---- git-rebase.sh | 12 +++--------- t/t4200-rerere.sh | 23 ++++++++++++++++++++--- 9 files changed, 64 insertions(+), 40 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 66a55b0514..4b67f0adf7 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -448,6 +448,11 @@ gc.rerereunresolved:: kept for this many days when `git rerere gc` is run. The default is 15 days. See gitlink:git-rerere[1]. +rerere.enabled:: + Activate recording of resolved conflicts, so that identical + conflict hunks can be resolved automatically, should they + be encountered again. See gitlink:git-rerere[1]. + gitcvs.enabled:: Whether the cvs server interface is enabled for this repository. See gitlink:git-cvsserver[1]. diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index 7ff9b05e68..c4d4263238 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -23,7 +23,7 @@ initial manual merge, and later by noticing the same automerge results and applying the previously recorded hand resolution. [NOTE] -You need to create `$GIT_DIR/rr-cache` directory to enable this +You need to set the config variable rerere.enabled to enable this command. @@ -171,7 +171,7 @@ records it if it is a new conflict, or reuses the earlier hand resolve when it is not. `git-commit` also invokes `git-rerere` when recording a merge result. What this means is that you do not have to do anything special yourself (Note: you still have -to create `$GIT_DIR/rr-cache` directory to enable this command). +to set the config variable rerere.enabled to enable this command). In our example, when you did the test merge, the manual resolution is recorded, and it will be reused when you do the diff --git a/builtin-rerere.c b/builtin-rerere.c index 29fb075d29..3196151cc4 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -12,6 +12,9 @@ static const char git_rerere_usage[] = static int cutoff_noresolve = 15; static int cutoff_resolve = 60; +/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */ +static int rerere_enabled = -1; + static char *merge_rr_path; static const char *rr_path(const char *name, const char *file) @@ -387,21 +390,41 @@ static int git_rerere_config(const char *var, const char *value) cutoff_resolve = git_config_int(var, value); else if (!strcmp(var, "gc.rerereunresolved")) cutoff_noresolve = git_config_int(var, value); + else if (!strcmp(var, "rerere.enabled")) + rerere_enabled = git_config_bool(var, value); else return git_default_config(var, value); return 0; } +static int is_rerere_enabled(void) +{ + struct stat st; + const char *rr_cache; + int rr_cache_exists; + + if (!rerere_enabled) + return 0; + + rr_cache = git_path("rr-cache"); + rr_cache_exists = !stat(rr_cache, &st) && S_ISDIR(st.st_mode); + if (rerere_enabled < 0) + return rr_cache_exists; + + if (!rr_cache_exists && + (mkdir(rr_cache, 0777) || adjust_shared_perm(rr_cache))) + die("Could not create directory %s", rr_cache); + return 1; +} + int cmd_rerere(int argc, const char **argv, const char *prefix) { struct path_list merge_rr = { NULL, 0, 0, 1 }; int i, fd = -1; - struct stat st; - - if (stat(git_path("rr-cache"), &st) || !S_ISDIR(st.st_mode)) - return 0; git_config(git_rerere_config); + if (!is_rerere_enabled()) + return 0; merge_rr_path = xstrdup(git_path("rr-cache/MERGE_RR")); fd = hold_lock_file_for_update(&write_lock, merge_rr_path, 1); @@ -411,6 +434,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix) return do_plain_rerere(&merge_rr, fd); else if (!strcmp(argv[1], "clear")) { for (i = 0; i < merge_rr.nr; i++) { + struct stat st; const char *name = (const char *)merge_rr.items[i].util; if (!stat(git_path("rr-cache/%s", name), &st) && S_ISDIR(st.st_mode) && diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el index f60017948f..457f95fc05 100644 --- a/contrib/emacs/git.el +++ b/contrib/emacs/git.el @@ -681,8 +681,7 @@ and returns the process output as a string." (condition-case nil (delete-file ".git/MERGE_MSG") (error nil)) (with-current-buffer buffer (erase-buffer)) (git-set-files-state files 'uptodate) - (when (file-directory-p ".git/rr-cache") - (git-run-command nil nil "rerere")) + (git-run-command nil nil "rerere") (git-refresh-files) (git-refresh-ewoc-hf git-status) (message "Committed %s." commit) diff --git a/git-am.sh b/git-am.sh index d57a3e2d09..e5e6f2c91c 100755 --- a/git-am.sh +++ b/git-am.sh @@ -95,10 +95,7 @@ It does not apply to blobs recorded in its index." eval GITHEAD_$his_tree='"$SUBJECT"' export GITHEAD_$his_tree git-merge-recursive $orig_tree -- HEAD $his_tree || { - if test -d "$GIT_DIR/rr-cache" - then - git rerere - fi + git rerere echo Failed to merge in the changes. exit 1 } @@ -252,10 +249,7 @@ 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 + git rerere clear this=`expr "$this" + 1` resume= fi @@ -420,10 +414,7 @@ do stop_here_user_resolve $this fi apply_status=0 - if test -d "$GIT_DIR/rr-cache" - then - git rerere - fi + git rerere ;; esac diff --git a/git-commit.sh b/git-commit.sh index f866f957c4..9106a743cc 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -610,10 +610,7 @@ rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG" cd_to_toplevel -if test -d "$GIT_DIR/rr-cache" -then - git rerere -fi +git rerere if test "$ret" = 0 then diff --git a/git-merge.sh b/git-merge.sh index 485253032a..5ccf28251d 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -496,9 +496,6 @@ Conflicts: sed -e 's/^[^ ]* / /' | uniq } >>"$GIT_DIR/MERGE_MSG" - if test -d "$GIT_DIR/rr-cache" - then - git rerere - fi + git rerere die "Automatic merge failed; fix conflicts and then commit the result." fi diff --git a/git-rebase.sh b/git-rebase.sh index 7a02f2975d..cbafa14ed5 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -101,7 +101,7 @@ call_merge () { return ;; 1) - test -d "$GIT_DIR/rr-cache" && git rerere + git rerere die "$RESOLVEMSG" ;; 2) @@ -160,10 +160,7 @@ do --skip) if test -d "$dotest" then - if test -d "$GIT_DIR/rr-cache" - then - git rerere clear - fi + git rerere clear prev_head="`cat $dotest/prev_head`" end="`cat $dotest/end`" msgnum="`cat $dotest/msgnum`" @@ -181,10 +178,7 @@ do exit ;; --abort) - if test -d "$GIT_DIR/rr-cache" - then - git rerere clear - fi + git rerere clear if test -d "$dotest" then rm -r "$dotest" diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 71d364ab79..6f55ba03bd 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -39,15 +39,32 @@ sed -e 's/To die, t/To die! T/' > a1 echo "* END *" >>a1 git commit -q -a -m second -# activate rerere -mkdir .git/rr-cache +test_expect_success 'nothing recorded without rerere' ' + (rm -rf .git/rr-cache; git config rerere.enabled false) && + ! git merge first && + ! test -d .git/rr-cache +' -test_expect_failure 'conflicting merge' 'git pull . first' +# activate rerere, old style +test_expect_success 'conflicting merge' ' + git reset --hard && + mkdir .git/rr-cache && + git config --unset rerere.enabled && + ! git merge first +' sha1=$(sed -e 's/ .*//' .git/rr-cache/MERGE_RR) rr=.git/rr-cache/$sha1 test_expect_success 'recorded preimage' "grep ======= $rr/preimage" +test_expect_success 'rerere.enabled works, too' ' + rm -rf .git/rr-cache && + git config rerere.enabled true && + git reset --hard && + ! git merge first && + grep ======= $rr/preimage +' + test_expect_success 'no postimage or thisimage yet' \ "test ! -f $rr/postimage -a ! -f $rr/thisimage" From 813a0bd8a4b074f7ea0094c065b211873bd86c19 Mon Sep 17 00:00:00 2001 From: Lars Hjemli Date: Fri, 6 Jul 2007 19:38:38 +0200 Subject: [PATCH 090/213] git-submodule(1): update description and key names When git-submodule was updated to allow mapping between submodule name and submodule path, the documentation was left untouched. Signed-off-by: Lars Hjemli Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index d76ae473bc..2c48936fcd 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -33,8 +33,8 @@ status:: init:: Initialize the submodules, i.e. register in .git/config each submodule - path and url found in .gitmodules. The key used in git/config is - `submodule.$path.url`. This command does not alter existing information + name and url found in .gitmodules. The key used in .git/config is + `submodule.$name.url`. This command does not alter existing information in .git/config. update:: @@ -65,7 +65,7 @@ FILES When initializing submodules, a .gitmodules file in the top-level directory of the containing repository is used to find the url of each submodule. This file should be formatted in the same way as $GIR_DIR/config. The key -to each submodule url is "module.$path.url". +to each submodule url is "submodule.$name.url". AUTHOR From 3cd2491aa2e5f07fa7fbeaa529b77de8c005a01c Mon Sep 17 00:00:00 2001 From: James Bowes Date: Fri, 6 Jul 2007 15:57:47 -0400 Subject: [PATCH 091/213] stash: allow running from a subdirectory Signed-off-by: James Bowes Signed-off-by: Junio C Hamano --- git-stash.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/git-stash.sh b/git-stash.sh index f01494dc1b..7b1638c68c 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -3,6 +3,7 @@ USAGE='[ | list | show | apply | clear]' +SUBDIRECTORY_OK=Yes . git-sh-setup require_work_tree From 1e76b702c1e754c7e6df1ced9ce6f1863cb7e092 Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Sun, 17 Jun 2007 10:31:02 +0200 Subject: [PATCH 092/213] cvsserver: always initialize state in argsplit() Other code assumes that this is initialized, so do it even if there were no arguments given. Signed-off-by: Dirk Koopman Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 5cbf27eebc..10aba507d7 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -1813,14 +1813,14 @@ sub req_annotate # the second is $state->{files} which is everything after it. sub argsplit { - return unless( defined($state->{arguments}) and ref $state->{arguments} eq "ARRAY" ); - - my $type = shift; - $state->{args} = []; $state->{files} = []; $state->{opt} = {}; + return unless( defined($state->{arguments}) and ref $state->{arguments} eq "ARRAY" ); + + my $type = shift; + if ( defined($type) ) { my $opt = {}; From ae740a588d581b34d2794a0993ae45cdca6d5ece Mon Sep 17 00:00:00 2001 From: Michael Hendricks Date: Wed, 4 Jul 2007 19:11:36 -0600 Subject: [PATCH 093/213] git-send-email: allow an email alias for --from Signed-off-by: Michael Hendricks Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/git-send-email.perl b/git-send-email.perl index 87f59fa313..89f7c36ee5 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -254,6 +254,8 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) { } } +($from) = expand_aliases($from) if defined $from; + my $prompting = 0; if (!defined $from) { $from = $author || $committer; From 34a3e695497ab2abbf2fc33a46380accaa8c7c15 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 6 Jul 2007 22:54:09 +0100 Subject: [PATCH 094/213] git-branch: default to --track "git branch --track" will setup config variables when branching from a remote branch, so that if you say "git pull" while being on that branch, it automatically fetches the correct remote, and merges the correct branch. Often people complain that this is not the default for "git branch". Make it so. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin-branch.c b/builtin-branch.c index 77b85dde1f..84a8ad7b73 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -22,7 +22,7 @@ static const char builtin_branch_usage[] = static const char *head; static unsigned char head_sha1[20]; -static int branch_track_remotes; +static int branch_track_remotes = 1; static int branch_use_color; static char branch_colors[][COLOR_MAXLEN] = { From e0e324a4dc18a4341e1320a7cfac9733d81f8b0b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 7 Jul 2007 01:49:58 -0700 Subject: [PATCH 095/213] Fix configuration syntax to specify customized hunk header patterns. This updates the hunk header customization syntax. The special case 'funcname' attribute is gone. You assign the name of the type of contents to path's "diff" attribute as a string value in .gitattributes like this: *.java diff=java *.perl diff=perl *.doc diff=doc If you supply "diff..funcname" variable via the configuration mechanism (e.g. in $HOME/.gitconfig), the value is used as the regexp set to find the line to use for the hunk header (the variable is called "funcname" because such a line typically is the one that has the name of the function in programming language source text). If there is no such configuration, built-in default is used, if any. Currently there are two default patterns: default and java. Signed-off-by: Junio C Hamano --- diff.c | 147 +++++++++++++++++++++------------------ diffcore.h | 2 +- t/t4018-diff-funcname.sh | 6 +- 3 files changed, 84 insertions(+), 71 deletions(-) diff --git a/diff.c b/diff.c index 04e7e91adf..21e61af265 100644 --- a/diff.c +++ b/diff.c @@ -56,6 +56,14 @@ static struct ll_diff_driver { char *cmd; } *user_diff, **user_diff_tail; +static void read_config_if_needed(void) +{ + if (!user_diff_tail) { + user_diff_tail = &user_diff; + git_config(git_diff_ui_config); + } +} + /* * Currently there is only "diff..command" variable; * because there are "diff.color." variables, we are parsing @@ -93,6 +101,45 @@ static int parse_lldiff_command(const char *var, const char *ep, const char *val return 0; } +/* + * 'diff..funcname' attribute can be specified in the configuration + * to define a customized regexp to find the beginning of a function to + * be used for hunk header lines of "diff -p" style output. + */ +static struct funcname_pattern { + char *name; + char *pattern; + struct funcname_pattern *next; +} *funcname_pattern_list; + +static int parse_funcname_pattern(const char *var, const char *ep, const char *value) +{ + const char *name; + int namelen; + struct funcname_pattern *pp; + + name = var + 5; /* "diff." */ + namelen = ep - name; + + for (pp = funcname_pattern_list; pp; pp = pp->next) + if (!strncmp(pp->name, name, namelen) && !pp->name[namelen]) + break; + if (!pp) { + char *namebuf; + pp = xcalloc(1, sizeof(*pp)); + namebuf = xmalloc(namelen + 1); + memcpy(namebuf, name, namelen); + namebuf[namelen] = 0; + pp->name = namebuf; + pp->next = funcname_pattern_list; + funcname_pattern_list = pp; + } + if (pp->pattern) + free(pp->pattern); + pp->pattern = xstrdup(value); + return 0; +} + /* * These are to give UI layer defaults. * The core-level commands such as git-diff-files should @@ -122,8 +169,12 @@ int git_diff_ui_config(const char *var, const char *value) if (!prefixcmp(var, "diff.")) { const char *ep = strrchr(var, '.'); - if (ep != var + 4 && !strcmp(ep, ".command")) - return parse_lldiff_command(var, ep, value); + if (ep != var + 4) { + if (!strcmp(ep, ".command")) + return parse_lldiff_command(var, ep, value); + if (!strcmp(ep, ".funcname")) + return parse_funcname_pattern(var, ep, value); + } } if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) { int slot = parse_diff_color_slot(var, 11); @@ -1101,43 +1152,39 @@ static void emit_binary_diff(mmfile_t *one, mmfile_t *two) static void setup_diff_attr_check(struct git_attr_check *check) { static struct git_attr *attr_diff; - static struct git_attr *attr_diff_func_name; if (!attr_diff) { attr_diff = git_attr("diff", 4); - attr_diff_func_name = git_attr("funcname", 8); } check[0].attr = attr_diff; - check[1].attr = attr_diff_func_name; } static void diff_filespec_check_attr(struct diff_filespec *one) { - struct git_attr_check attr_diff_check[2]; + struct git_attr_check attr_diff_check; if (one->checked_attr) return; - setup_diff_attr_check(attr_diff_check); + setup_diff_attr_check(&attr_diff_check); one->is_binary = 0; - one->hunk_header_ident = NULL; + one->funcname_pattern_ident = NULL; - if (!git_checkattr(one->path, ARRAY_SIZE(attr_diff_check), attr_diff_check)) { + if (!git_checkattr(one->path, 1, &attr_diff_check)) { const char *value; /* binaryness */ - value = attr_diff_check[0].value; + value = attr_diff_check.value; if (ATTR_TRUE(value)) ; else if (ATTR_FALSE(value)) one->is_binary = 1; - /* hunk header ident */ - value = attr_diff_check[1].value; + /* funcname pattern ident */ if (ATTR_TRUE(value) || ATTR_FALSE(value) || ATTR_UNSET(value)) ; else - one->hunk_header_ident = value; + one->funcname_pattern_ident = value; } if (!one->data && DIFF_FILE_VALID(one)) @@ -1154,54 +1201,23 @@ int diff_filespec_is_binary(struct diff_filespec *one) return one->is_binary; } -static struct hunk_header_regexp { - char *name; - char *regexp; - struct hunk_header_regexp *next; -} *hunk_header_regexp_list, **hunk_header_regexp_tail; - -static int hunk_header_config(const char *var, const char *value) +static const char *funcname_pattern(const char *ident) { - static const char funcname[] = "funcname."; - struct hunk_header_regexp *hh; + struct funcname_pattern *pp; - if (prefixcmp(var, funcname)) - return 0; - var += strlen(funcname); - for (hh = hunk_header_regexp_list; hh; hh = hh->next) - if (!strcmp(var, hh->name)) { - free(hh->regexp); - hh->regexp = xstrdup(value); - return 0; - } - hh = xcalloc(1, sizeof(*hh)); - hh->name = xstrdup(var); - hh->regexp = xstrdup(value); - hh->next = NULL; - *hunk_header_regexp_tail = hh; - return 0; -} - -static const char *hunk_header_regexp(const char *ident) -{ - struct hunk_header_regexp *hh; - - if (!hunk_header_regexp_tail) { - hunk_header_regexp_tail = &hunk_header_regexp_list; - git_config(hunk_header_config); - } - for (hh = hunk_header_regexp_list; hh; hh = hh->next) - if (!strcmp(ident, hh->name)) - return hh->regexp; + read_config_if_needed(); + for (pp = funcname_pattern_list; pp; pp = pp->next) + if (!strcmp(ident, pp->name)) + return pp->pattern; return NULL; } -static const char *diff_hunk_header_regexp(struct diff_filespec *one) +static const char *diff_funcname_pattern(struct diff_filespec *one) { - const char *ident, *regexp; + const char *ident, *pattern; diff_filespec_check_attr(one); - ident = one->hunk_header_ident; + ident = one->funcname_pattern_ident; if (!ident) /* @@ -1209,12 +1225,12 @@ static const char *diff_hunk_header_regexp(struct diff_filespec *one) * regexp is used; otherwise NULL is returned and xemit uses * the built-in default. */ - return hunk_header_regexp("default"); + return funcname_pattern("default"); /* Look up custom "funcname.$ident" regexp from config. */ - regexp = hunk_header_regexp(ident); - if (regexp) - return regexp; + pattern = funcname_pattern(ident); + if (pattern) + return pattern; /* * And define built-in fallback patterns here. Note that @@ -1304,11 +1320,11 @@ static void builtin_diff(const char *name_a, xdemitconf_t xecfg; xdemitcb_t ecb; struct emit_callback ecbdata; - const char *hunk_header_regexp; + const char *funcname_pattern; - hunk_header_regexp = diff_hunk_header_regexp(one); - if (!hunk_header_regexp) - hunk_header_regexp = diff_hunk_header_regexp(two); + funcname_pattern = diff_funcname_pattern(one); + if (!funcname_pattern) + funcname_pattern = diff_funcname_pattern(two); memset(&xecfg, 0, sizeof(xecfg)); memset(&ecbdata, 0, sizeof(ecbdata)); @@ -1318,8 +1334,8 @@ static void builtin_diff(const char *name_a, xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = o->context; xecfg.flags = XDL_EMIT_FUNCNAMES; - if (hunk_header_regexp) - xdiff_set_find_func(&xecfg, hunk_header_regexp); + if (funcname_pattern) + xdiff_set_find_func(&xecfg, funcname_pattern); if (!diffopts) ; else if (!prefixcmp(diffopts, "--unified=")) @@ -1862,10 +1878,7 @@ static const char *external_diff_attr(const char *name) !ATTR_UNSET(value)) { struct ll_diff_driver *drv; - if (!user_diff_tail) { - user_diff_tail = &user_diff; - git_config(git_diff_ui_config); - } + read_config_if_needed(); for (drv = user_diff; drv; drv = drv->next) if (!strcmp(drv->name, value)) return drv->cmd; diff --git a/diffcore.h b/diffcore.h index 05985147ea..eef17c4ca2 100644 --- a/diffcore.h +++ b/diffcore.h @@ -27,7 +27,7 @@ struct diff_filespec { char *path; void *data; void *cnt_data; - const void *hunk_header_ident; + const char *funcname_pattern_ident; unsigned long size; int xfrm_flags; /* for use by the xfrm */ unsigned short mode; /* file mode */ diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index dc7a47b3f1..f9db81d3ab 100644 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -38,12 +38,12 @@ test_expect_success 'default behaviour' ' ' test_expect_success 'preset java pattern' ' - echo "*.java funcname=java" >.gitattributes && + echo "*.java diff=java" >.gitattributes && git diff Beer.java Beer-correct.java | grep "^@@.*@@ public static void main(" ' -git config funcname.java '!static +git config diff.java.funcname '!static !String [^ ].*s.*' @@ -53,7 +53,7 @@ test_expect_success 'custom pattern' ' ' test_expect_success 'last regexp must not be negated' ' - git config diff.functionnameregexp "!static" && + git config diff.java.funcname "!static" && ! git diff Beer.java Beer-correct.java ' From 4d3f4b80e49275c7eaf6ba0dbddd6180957926b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Sat, 7 Jul 2007 20:19:08 +0200 Subject: [PATCH 096/213] diff-lib.c: don't strdup twice The static function read_directory in diff-lib.c is only ever called with struct path_list lists with .strdup_paths turned on, i.e. path_list_insert will strdup the paths for us (again). Let's take advantage of that and stop doing it twice. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- diff-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diff-lib.c b/diff-lib.c index 7fb19c7b87..92c0e39ad6 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -24,7 +24,7 @@ static int read_directory(const char *path, struct path_list *list) while ((e = readdir(dir))) if (strcmp(".", e->d_name) && strcmp("..", e->d_name)) - path_list_insert(xstrdup(e->d_name), list); + path_list_insert(e->d_name, list); closedir(dir); return 0; From 2c3fa66f3577d1305fb0fac5a181261fb2597859 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 7 Jul 2007 12:25:11 -0700 Subject: [PATCH 097/213] diff: honor binariness specified in attributes The code shuffling mistakenly lost binariness specified with the attribute mecahnism and made it always guess from the data. Noticed by Johannes, with two test cases to t4020. Signed-off-by: Junio C Hamano --- diff.c | 14 +++++++++----- t/t4020-diff-external.sh | 12 ++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/diff.c b/diff.c index 21e61af265..b8473f58fb 100644 --- a/diff.c +++ b/diff.c @@ -1162,6 +1162,7 @@ static void setup_diff_attr_check(struct git_attr_check *check) static void diff_filespec_check_attr(struct diff_filespec *one) { struct git_attr_check attr_diff_check; + int check_from_data = 0; if (one->checked_attr) return; @@ -1179,6 +1180,8 @@ static void diff_filespec_check_attr(struct diff_filespec *one) ; else if (ATTR_FALSE(value)) one->is_binary = 1; + else + check_from_data = 1; /* funcname pattern ident */ if (ATTR_TRUE(value) || ATTR_FALSE(value) || ATTR_UNSET(value)) @@ -1187,12 +1190,13 @@ static void diff_filespec_check_attr(struct diff_filespec *one) one->funcname_pattern_ident = value; } - if (!one->data && DIFF_FILE_VALID(one)) - diff_populate_filespec(one, 0); - - if (one->data) - one->is_binary = buffer_is_binary(one->data, one->size); + if (check_from_data) { + if (!one->data && DIFF_FILE_VALID(one)) + diff_populate_filespec(one, 0); + if (one->data) + one->is_binary = buffer_is_binary(one->data, one->size); + } } int diff_filespec_is_binary(struct diff_filespec *one) diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index f0045cd788..ed3bd5b3fe 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -94,4 +94,16 @@ test_expect_success 'diff attribute should apply only to diff' ' ' +test_expect_success 'no diff with -diff' ' + echo >.gitattributes "file -diff" && + git diff | grep Binary +' + +echo NULZbetweenZwords | tr Z '\0' > file + +test_expect_success 'force diff with "diff"' ' + echo >.gitattributes "file diff" && + git diff | grep -a second +' + test_done From 478524508e2f49af8cc76f2d7294a3b33facf121 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 3 Jul 2007 22:10:42 -0700 Subject: [PATCH 098/213] gitweb: make repeated calls to git_get_project_owner() bearable If repeated calls to git_get_project_owner() are made, we would have read the same file over and over again. Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index dbfb0441a6..d5b8812a12 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1465,12 +1465,12 @@ sub git_get_projects_list { return @list; } -sub git_get_project_owner { - my $project = shift; - my $owner; +our $gitweb_project_owner = undef; +sub git_get_project_list_from_file { - return undef unless $project; + return if (defined $gitweb_project_owner); + $gitweb_project_owner = {}; # read from file (url-encoded): # 'git%2Fgit.git Linus+Torvalds' # 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin' @@ -1482,13 +1482,25 @@ sub git_get_project_owner { my ($pr, $ow) = split ' ', $line; $pr = unescape($pr); $ow = unescape($ow); - if ($pr eq $project) { - $owner = to_utf8($ow); - last; - } + $gitweb_project_owner->{$pr} = to_utf8($ow); } close $fd; } +} + +sub git_get_project_owner { + my $project = shift; + my $owner; + + return undef unless $project; + + if (!defined $gitweb_project_owner) { + git_get_project_list_from_file(); + } + + if (exists $gitweb_project_owner->{$project}) { + $owner = $gitweb_project_owner->{$project}; + } if (!defined $owner) { $owner = get_file_owner("$projectroot/$project"); } From 76e4f5d025d80479c3a01ed9c65b024e9b80d931 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 4 Jul 2007 00:11:23 +0200 Subject: [PATCH 099/213] gitweb: prefer git_get_project_owner() over get_file_owner() This way if $projects_list exists, it'll be used, otherwise get_file_owner() will be used as before. Signed-off-by: Miklos Vajna Acked-by: Luben Tuikov Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index d5b8812a12..9d728d7738 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3178,7 +3178,7 @@ sub git_project_list_body { $pr->{'descr'} = chop_str($descr, 25, 5); } if (!defined $pr->{'owner'}) { - $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || ""; + $pr->{'owner'} = git_get_project_owner("$pr->{'path'}") || ""; } if ($check_forks) { my $pname = $pr->{'path'}; @@ -3602,7 +3602,7 @@ sub git_project_index { foreach my $pr (@projects) { if (!exists $pr->{'owner'}) { - $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}"); + $pr->{'owner'} = git_get_project_owner("$pr->{'path'}"); } my ($path, $owner) = ($pr->{'path'}, $pr->{'owner'}); From 40375a83d2bc3e2c86f998fe47fef573502a9922 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Thu, 28 Jun 2007 14:57:07 -0400 Subject: [PATCH 100/213] gitweb: make search form generate pathinfo-style URLs The search form generated traditional-style URLs with a "p=" parameter even when the pathinfo feature was on. This patch makes it generate pathinfo-style URLs when appropriate. Signed-off-by: Matt McCutchen Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 9d728d7738..4eb7832b4a 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2213,12 +2213,18 @@ EOF } else { $search_hash = "HEAD"; } + my $action = $my_uri; + my ($use_pathinfo) = gitweb_check_feature('pathinfo'); + if ($use_pathinfo) { + $action .= "/$project"; + } else { + $cgi->param("p", $project); + } $cgi->param("a", "search"); $cgi->param("h", $search_hash); - $cgi->param("p", $project); - print $cgi->startform(-method => "get", -action => $my_uri) . + print $cgi->startform(-method => "get", -action => $action) . "
\n" . - $cgi->hidden(-name => "p") . "\n" . + (!$use_pathinfo && $cgi->hidden(-name => "p") . "\n") . $cgi->hidden(-name => "a") . "\n" . $cgi->hidden(-name => "h") . "\n" . $cgi->popup_menu(-name => 'st', -default => 'commit', From c956395e2bf94a50fe843935605914573f4c7787 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Thu, 28 Jun 2007 18:15:22 -0400 Subject: [PATCH 101/213] gitweb: make "No commits" in project list gray, not bold green A missing return statement in git_get_last_activity made gitweb think a project with no commits was in age class "age0", so the "No commits" appeared in bold green, which was ridiculous. I added the return so those projects get "noage" and added a block to gitweb.css to format the "No commits" text gray. Signed-off-by: Matt McCutchen Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 6 ++++++ gitweb/gitweb.perl | 1 + 2 files changed, 7 insertions(+) diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 7908fe3b5f..096313bec0 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -281,6 +281,12 @@ table.diff_tree span.file_status.copied { color: #70a070; } +/* noage: "No commits" */ +table.project_list td.noage { + color: #808080; + font-style: italic; +} + /* age2: 60*60*24*2 <= age */ table.project_list td.age2, table.blame td.age2 { font-style: italic; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 4eb7832b4a..dc609f4f86 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1526,6 +1526,7 @@ sub git_get_last_activity { my $age = time - $timestamp; return ($age, age_string($age)); } + return (undef, undef); } sub git_get_references { From d3a93dc96786847f9d148da42ecadee5f027c9a7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 8 Jul 2007 00:25:59 -0700 Subject: [PATCH 102/213] diff.c: make built-in hunk header pattern a separate table This would hopefully make it easier to maintain. Initially we would have "java" and "tex" defined, as they are the only ones we already have. Signed-off-by: Junio C Hamano --- diff.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/diff.c b/diff.c index b8473f58fb..cd6b0c4e0b 100644 --- a/diff.c +++ b/diff.c @@ -1216,9 +1216,22 @@ static const char *funcname_pattern(const char *ident) return NULL; } +static struct builtin_funcname_pattern { + const char *name; + const char *pattern; +} builtin_funcname_pattern[] = { + { "java", "!^[ ]*\\(catch\\|do\\|for\\|if\\|instanceof\\|" + "new\\|return\\|switch\\|throw\\|while\\)\n" + "^[ ]*\\(\\([ ]*" + "[A-Za-z_][A-Za-z_0-9]*\\)\\{2,\\}" + "[ ]*([^;]*$\\)" }, + { "tex", "^\\(\\\\\\(sub\\)*section{.*\\)$" }, +}; + static const char *diff_funcname_pattern(struct diff_filespec *one) { const char *ident, *pattern; + int i; diff_filespec_check_attr(one); ident = one->funcname_pattern_ident; @@ -1240,12 +1253,9 @@ static const char *diff_funcname_pattern(struct diff_filespec *one) * And define built-in fallback patterns here. Note that * these can be overriden by the user's config settings. */ - if (!strcmp(ident, "java")) - return "!^[ ]*\\(catch\\|do\\|for\\|if\\|instanceof\\|" - "new\\|return\\|switch\\|throw\\|while\\)\n" - "^[ ]*\\(\\([ ]*" - "[A-Za-z_][A-Za-z_0-9]*\\)\\{2,\\}" - "[ ]*([^;]*$\\)"; + for (i = 0; i < ARRAY_SIZE(builtin_funcname_pattern); i++) + if (!strcmp(ident, builtin_funcname_pattern[i].name)) + return builtin_funcname_pattern[i].pattern; return NULL; } From d4c5307701551ec65c10bef0dacc643205313098 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 17:41:24 -0400 Subject: [PATCH 103/213] git-gui: Honor rerere.enabled configuration option Recently in git.git change b4372ef136 Johannes Schindelin taught git-commit.sh to invoke (or skip) calling git-rerere based upon the rerere.enabled configuration setting: So, check the config variable "rerere.enabled". If it is set to "false" explicitely, do not activate rerere, even if .git/rr-cache exists. This should help when you want to disable rerere temporarily. If "rerere.enabled" is not set at all, fall back to detection of the directory .git/rr-cache. We now do the same logic in git-gui's own commit implementation. Signed-off-by: Shawn O. Pearce --- lib/commit.tcl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/commit.tcl b/lib/commit.tcl index f9791f64db..0de2a28fa5 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -331,7 +331,12 @@ A rescan will be automatically started now. # -- Let rerere do its thing. # - if {[file isdirectory [gitdir rr-cache]]} { + if {[get_config rerere.enabled] eq {}} { + set rerere [file isdirectory [gitdir rr-cache]] + } else { + set rerere [is_config_true rerere.enabled] + } + if {$rerere} { catch {git rerere} } From d696702209dd0d4c20d2b87b5bc10cae3d54e839 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 18:48:08 -0400 Subject: [PATCH 104/213] git-gui: New Git version check support routine Some newer features of git-gui want to rely on features that are new to Git 1.5.3. Since they were added as part of the 1.5.3 development series we cannot use those features with versions of Git that are older than 1.5.3, such as from the stable 1.5.2 series. We introduce [git-version >= 1.5.3] to allow the caller to get a response of 0 if the current version of git is < 1.5.3 and 1 if the current version of git is >= 1.5.3. This makes it easy to setup conditional code based upon the version of Git available to us at runtime. Instead of parsing the version text by hand we now use the Tcl [package vcompare] subcommand to compare the two version strings. This works nicely, as Tcl as already done all of the hard work of doing version comparsions. But we do have to remove the Git specific components such as the Git commit SHA-1, commit count and release candidate suffix (rc) as we want only the final release version number. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 77 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 0096f4913a..c36a986b77 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -308,33 +308,76 @@ proc tk_optionMenu {w varName args} { ## ## version check -set req_maj 1 -set req_min 5 - -if {[catch {set v [git --version]} err]} { +if {[catch {set _git_version [git --version]} err]} { catch {wm withdraw .} error_popup "Cannot determine Git version: $err -[appname] requires Git $req_maj.$req_min or later." +[appname] requires Git 1.5.0 or later." exit 1 } -if {[regexp {^git version (\d+)\.(\d+)} $v _junk act_maj act_min]} { - if {$act_maj < $req_maj - || ($act_maj == $req_maj && $act_min < $req_min)} { - catch {wm withdraw .} - error_popup "[appname] requires Git $req_maj.$req_min or later. - -You are using $v." - exit 1 - } -} else { +if {![regsub {^git version } $_git_version {} _git_version]} { catch {wm withdraw .} - error_popup "Cannot parse Git version string:\n\n$v" + error_popup "Cannot parse Git version string:\n\n$_git_version" + exit 1 +} +regsub {\.[0-9]+\.g[0-9a-f]+$} $_git_version {} _git_version +regsub {\.rc[0-9]+$} $_git_version {} _git_version + +proc git-version {args} { + global _git_version + + switch [llength $args] { + 0 { + return $_git_version + } + + 2 { + set op [lindex $args 0] + set vr [lindex $args 1] + set cm [package vcompare $_git_version $vr] + return [expr $cm $op 0] + } + + 4 { + set type [lindex $args 0] + set name [lindex $args 1] + set parm [lindex $args 2] + set body [lindex $args 3] + + if {($type ne {proc} && $type ne {method})} { + error "Invalid arguments to git-version" + } + if {[llength $body] < 2 || [lindex $body end-1] ne {default}} { + error "Last arm of $type $name must be default" + } + + foreach {op vr cb} [lrange $body 0 end-2] { + if {[git-version $op $vr]} { + return [uplevel [list $type $name $parm $cb]] + } + } + + return [uplevel [list $type $name $parm [lindex $body end]]] + } + + default { + error "git-version >= x" + } + + } +} + +if {[git-version < 1.5]} { + catch {wm withdraw .} + error_popup "[appname] requires Git 1.5.0 or later. + +You are using [git-version]: + +[git --version]" exit 1 } -unset -nocomplain v _junk act_maj act_min req_maj req_min ###################################################################### ## From a840566770c262f76e8fd7fb69239fbedd10b259 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 20 Jun 2007 21:44:16 -0700 Subject: [PATCH 105/213] git-gui: use "blame -w -C -C" for "where did it come from, originally?" The blame window shows "who wrote the piece originally" and "who moved it there" in two columns. In order to identify the former more correctly, it helps to use the new -w option. [sp: Minor change to only enable -w if underlying git >= 1.5.3] Signed-off-by: Junio C Hamano Signed-off-by: Shawn O. Pearce --- lib/blame.tcl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/blame.tcl b/lib/blame.tcl index 77abd8291d..dcdb11b1b6 100644 --- a/lib/blame.tcl +++ b/lib/blame.tcl @@ -33,6 +33,13 @@ variable group_colors { #ececec } +# Switches for original location detection +# +variable original_options [list -C -C] +if {[git-version >= 1.5.3]} { + lappend original_options -w ; # ignore indentation changes +} + # Current blame data; cleared/reset on each load # field commit ; # input commit to blame @@ -512,6 +519,7 @@ method _exec_blame {cur_w cur_d options cur_s} { method _read_blame {fd cur_w cur_d cur_s} { upvar #0 $cur_d line_data variable group_colors + variable original_options if {$fd ne $current_fd} { catch {close $fd} @@ -681,7 +689,7 @@ method _read_blame {fd cur_w cur_d cur_s} { close $fd if {$cur_w eq $w_asim} { _exec_blame $this $w_amov @amov_data \ - [list -M -C -C] \ + $original_options \ { original location} } else { set current_fd {} From 6233ab17297684c0049923cb8492393276672b01 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sat, 30 Jun 2007 04:34:59 -0400 Subject: [PATCH 106/213] git-gui: Teach class system to support [$this cmd] syntax Its handy to be able to ask an object to do something for you by handing it a subcommand. For example if we want to get the value of an object's private field the object could expose a method that would return that value. Application level code can then invoke "$inst get" to perform the method call. Tk uses this pattern for all of its widgets, so we'd certainly like to use it for our own mega-widgets that we might develop. Up until now we haven't needed such functionality, but I'm working on a new revision picker mega-widget that would benefit from it. To make this work we have to change the definition of $this to actually be a procedure within the namespace. By making $this a procedure any caller that has $this can call subcommands by passing them as the first argument to $this. That subcommand then needs to call the proper subroutine. Placing the dispatch procedure into the object's variable namespace ensures that it will always be deleted when the object is deleted. Signed-off-by: Shawn O. Pearce --- lib/class.tcl | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/class.tcl b/lib/class.tcl index 9d298d0dcc..24e8cecea4 100644 --- a/lib/class.tcl +++ b/lib/class.tcl @@ -5,7 +5,7 @@ proc class {class body} { if {[namespace exists $class]} { error "class $class already declared" } - namespace eval $class { + namespace eval $class " variable __nextid 0 variable __sealed 0 variable __field_list {} @@ -13,10 +13,9 @@ proc class {class body} { proc cb {name args} { upvar this this - set args [linsert $args 0 $name $this] - return [uplevel [list namespace code $args]] + concat \[list ${class}::\$name \$this\] \$args } - } + " namespace eval $class $body } @@ -51,15 +50,16 @@ proc constructor {name params body} { set mbodyc {} append mbodyc {set this } $class - append mbodyc {::__o[incr } $class {::__nextid]} \; - append mbodyc {namespace eval $this {}} \; + append mbodyc {::__o[incr } $class {::__nextid]::__d} \; + append mbodyc {create_this } $class \; + append mbodyc {set __this [namespace qualifiers $this]} \; if {$__field_list ne {}} { append mbodyc {upvar #0} foreach n $__field_list { set n [lindex $n 0] - append mbodyc { ${this}::} $n { } $n - regsub -all @$n\\M $body "\${this}::$n" body + append mbodyc { ${__this}::} $n { } $n + regsub -all @$n\\M $body "\${__this}::$n" body } append mbodyc \; foreach n $__field_list { @@ -80,10 +80,12 @@ proc method {name params body {deleted {}} {del_body {}}} { set params [linsert $params 0 this] set mbodyc {} + append mbodyc {set __this [namespace qualifiers $this]} \; + switch $deleted { {} {} ifdeleted { - append mbodyc {if {![namespace exists $this]} } + append mbodyc {if {![namespace exists $__this]} } append mbodyc \{ $del_body \; return \} \; } default { @@ -98,10 +100,12 @@ proc method {name params body {deleted {}} {del_body {}}} { if { [regexp -all -- $n\\M $body] == 1 && [regexp -all -- \\\$$n\\M $body] == 1 && [regexp -all -- \\\$$n\\( $body] == 0} { - regsub -all \\\$$n\\M $body "\[set \${this}::$n\]" body + regsub -all \ + \\\$$n\\M $body \ + "\[set \${__this}::$n\]" body } else { - append decl { ${this}::} $n { } $n - regsub -all @$n\\M $body "\${this}::$n" body + append decl { ${__this}::} $n { } $n + regsub -all @$n\\M $body "\${__this}::$n" body } } } @@ -112,11 +116,21 @@ proc method {name params body {deleted {}} {del_body {}}} { namespace eval $class [list proc $name $params $mbodyc] } +proc create_this {class} { + upvar this this + namespace eval [namespace qualifiers $this] [list proc \ + [namespace tail $this] \ + [list name args] \ + "eval \[list ${class}::\$name $this\] \$args" \ + ] +} + proc delete_this {{t {}}} { if {$t eq {}} { upvar this this set t $this } + set t [namespace qualifiers $t] if {[namespace exists $t]} {namespace delete $t} } From b1fa2bfff36933f94dada476ba5b3d3cb894b723 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 3 Jul 2007 22:57:18 -0400 Subject: [PATCH 107/213] git-gui: Abstract the revision picker into a mega widget This rather large change pulls the "Starting Revision" part of the new branch dialog into a mega widget that we can use anytime we need to select a commit SHA-1. To make use of the mega widget I have also refactored the branch dialog to use the class system, much like the delete remote branch dialog already does. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 6 +- lib/branch.tcl | 210 ------------------------------------------ lib/branch_create.tcl | 157 +++++++++++++++++++++++++++++++ lib/choose_rev.tcl | 127 +++++++++++++++++++++++++ 4 files changed, 287 insertions(+), 213 deletions(-) create mode 100644 lib/branch_create.tcl create mode 100644 lib/choose_rev.tcl diff --git a/git-gui.sh b/git-gui.sh index c36a986b77..e07f4babd0 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1496,7 +1496,7 @@ if {[is_enabled branch]} { menu .mbar.branch .mbar.branch add command -label {Create...} \ - -command do_create_branch \ + -command branch_create::dialog \ -accelerator $M1T-N lappend disable_on_lock [list .mbar.branch entryconf \ [.mbar.branch index last] -state] @@ -2221,8 +2221,8 @@ bind $ui_diff {catch {%W yview scroll 1 pages};break} bind $ui_diff {focus %W} if {[is_enabled branch]} { - bind . <$M1B-Key-n> do_create_branch - bind . <$M1B-Key-N> do_create_branch + bind . <$M1B-Key-n> branch_create::dialog + bind . <$M1B-Key-N> branch_create::dialog } if {[is_enabled transport]} { bind . <$M1B-Key-p> do_push_anywhere diff --git a/lib/branch.tcl b/lib/branch.tcl index 4f648b2bc7..e7559f9789 100644 --- a/lib/branch.tcl +++ b/lib/branch.tcl @@ -61,221 +61,11 @@ proc populate_branch_menu {} { } } -proc do_create_branch_action {w} { - global all_heads null_sha1 repo_config - global create_branch_checkout create_branch_revtype - global create_branch_head create_branch_trackinghead - global create_branch_name create_branch_revexp - global create_branch_tag - - set newbranch $create_branch_name - if {$newbranch eq {} - || $newbranch eq $repo_config(gui.newbranchtemplate)} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Please supply a branch name." - focus $w.desc.name_t - return - } - if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Branch '$newbranch' already exists." - focus $w.desc.name_t - return - } - if {[catch {git check-ref-format "heads/$newbranch"}]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "We do not like '$newbranch' as a branch name." - focus $w.desc.name_t - return - } - - set rev {} - switch -- $create_branch_revtype { - head {set rev $create_branch_head} - tracking {set rev $create_branch_trackinghead} - tag {set rev $create_branch_tag} - expression {set rev $create_branch_revexp} - } - if {[catch {set cmt [git rev-parse --verify "${rev}^0"]}]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Invalid starting revision: $rev" - return - } - if {[catch { - git update-ref \ - -m "branch: Created from $rev" \ - "refs/heads/$newbranch" \ - $cmt \ - $null_sha1 - } err]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Failed to create '$newbranch'.\n\n$err" - return - } - - lappend all_heads $newbranch - set all_heads [lsort $all_heads] - populate_branch_menu - destroy $w - if {$create_branch_checkout} { - switch_branch $newbranch - } -} - proc radio_selector {varname value args} { upvar #0 $varname var set var $value } -trace add variable create_branch_head write \ - [list radio_selector create_branch_revtype head] -trace add variable create_branch_trackinghead write \ - [list radio_selector create_branch_revtype tracking] -trace add variable create_branch_tag write \ - [list radio_selector create_branch_revtype tag] - -trace add variable delete_branch_head write \ - [list radio_selector delete_branch_checktype head] -trace add variable delete_branch_trackinghead write \ - [list radio_selector delete_branch_checktype tracking] - -proc do_create_branch {} { - global all_heads current_branch repo_config - global create_branch_checkout create_branch_revtype - global create_branch_head create_branch_trackinghead - global create_branch_name create_branch_revexp - global create_branch_tag - - set w .branch_editor - toplevel $w - wm geometry $w "+[winfo rootx .]+[winfo rooty .]" - - label $w.header -text {Create New Branch} \ - -font font_uibold - pack $w.header -side top -fill x - - frame $w.buttons - button $w.buttons.create -text Create \ - -default active \ - -command [list do_create_branch_action $w] - pack $w.buttons.create -side right - button $w.buttons.cancel -text {Cancel} \ - -command [list destroy $w] - pack $w.buttons.cancel -side right -padx 5 - pack $w.buttons -side bottom -fill x -pady 10 -padx 10 - - labelframe $w.desc -text {Branch Description} - label $w.desc.name_l -text {Name:} - entry $w.desc.name_t \ - -borderwidth 1 \ - -relief sunken \ - -width 40 \ - -textvariable create_branch_name \ - -validate key \ - -validatecommand { - if {%d == 1 && [regexp {[~^:?*\[\0- ]} %S]} {return 0} - return 1 - } - grid $w.desc.name_l $w.desc.name_t -sticky we -padx {0 5} - grid columnconfigure $w.desc 1 -weight 1 - pack $w.desc -anchor nw -fill x -pady 5 -padx 5 - - labelframe $w.from -text {Starting Revision} - if {$all_heads ne {}} { - radiobutton $w.from.head_r \ - -text {Local Branch:} \ - -value head \ - -variable create_branch_revtype - eval tk_optionMenu $w.from.head_m create_branch_head $all_heads - grid $w.from.head_r $w.from.head_m -sticky w - } - set all_trackings [all_tracking_branches] - if {$all_trackings ne {}} { - set create_branch_trackinghead [lindex $all_trackings 0] - radiobutton $w.from.tracking_r \ - -text {Tracking Branch:} \ - -value tracking \ - -variable create_branch_revtype - eval tk_optionMenu $w.from.tracking_m \ - create_branch_trackinghead \ - $all_trackings - grid $w.from.tracking_r $w.from.tracking_m -sticky w - } - set all_tags [load_all_tags] - if {$all_tags ne {}} { - set create_branch_tag [lindex $all_tags 0] - radiobutton $w.from.tag_r \ - -text {Tag:} \ - -value tag \ - -variable create_branch_revtype - eval tk_optionMenu $w.from.tag_m create_branch_tag $all_tags - grid $w.from.tag_r $w.from.tag_m -sticky w - } - radiobutton $w.from.exp_r \ - -text {Revision Expression:} \ - -value expression \ - -variable create_branch_revtype - entry $w.from.exp_t \ - -borderwidth 1 \ - -relief sunken \ - -width 50 \ - -textvariable create_branch_revexp \ - -validate key \ - -validatecommand { - if {%d == 1 && [regexp {\s} %S]} {return 0} - if {%d == 1 && [string length %S] > 0} { - set create_branch_revtype expression - } - return 1 - } - grid $w.from.exp_r $w.from.exp_t -sticky we -padx {0 5} - grid columnconfigure $w.from 1 -weight 1 - pack $w.from -anchor nw -fill x -pady 5 -padx 5 - - labelframe $w.postActions -text {Post Creation Actions} - checkbutton $w.postActions.checkout \ - -text {Checkout after creation} \ - -variable create_branch_checkout - pack $w.postActions.checkout -anchor nw - pack $w.postActions -anchor nw -fill x -pady 5 -padx 5 - - set create_branch_checkout 1 - set create_branch_head $current_branch - set create_branch_revtype head - set create_branch_name $repo_config(gui.newbranchtemplate) - set create_branch_revexp {} - - bind $w " - grab $w - $w.desc.name_t icursor end - focus $w.desc.name_t - " - bind $w "destroy $w" - bind $w "do_create_branch_action $w;break" - wm title $w "[appname] ([reponame]): Create Branch" - tkwait window $w -} - proc do_delete_branch_action {w} { global all_heads global delete_branch_checktype delete_branch_head delete_branch_trackinghead diff --git a/lib/branch_create.tcl b/lib/branch_create.tcl new file mode 100644 index 0000000000..ef63f810f4 --- /dev/null +++ b/lib/branch_create.tcl @@ -0,0 +1,157 @@ +# git-gui branch create support +# Copyright (C) 2006, 2007 Shawn Pearce + +class branch_create { + +field w ; # widget path +field w_rev ; # mega-widget to pick the initial revision +field w_name ; # new branch name widget + +field name {}; # name of the branch the user has chosen +field opt_checkout 1; # automatically checkout the new branch? + +constructor dialog {} { + global repo_config + + make_toplevel top w + wm title $top "[appname] ([reponame]): Create Branch" + if {$top ne {.}} { + wm geometry $top "+[winfo rootx .]+[winfo rooty .]" + } + + label $w.header -text {Create New Branch} -font font_uibold + pack $w.header -side top -fill x + + frame $w.buttons + button $w.buttons.create -text Create \ + -default active \ + -command [cb _create] + pack $w.buttons.create -side right + button $w.buttons.cancel -text {Cancel} \ + -command [list destroy $w] + pack $w.buttons.cancel -side right -padx 5 + pack $w.buttons -side bottom -fill x -pady 10 -padx 10 + + labelframe $w.desc -text {Branch Description} + label $w.desc.name_r \ + -anchor w \ + -text {Name:} + set w_name $w.desc.name_t + entry $w_name \ + -borderwidth 1 \ + -relief sunken \ + -width 40 \ + -textvariable @name \ + -validate key \ + -validatecommand [cb _validate %d %S] + grid $w.desc.name_r $w_name -sticky we -padx {0 5} + + grid columnconfigure $w.desc 1 -weight 1 + pack $w.desc -anchor nw -fill x -pady 5 -padx 5 + + set w_rev [::choose_rev::new $w.rev {Starting Revision}] + pack $w.rev -anchor nw -fill x -pady 5 -padx 5 + + labelframe $w.postActions -text {Post Creation Actions} + checkbutton $w.postActions.checkout \ + -text {Checkout after creation} \ + -variable @opt_checkout + pack $w.postActions.checkout -anchor nw + pack $w.postActions -anchor nw -fill x -pady 5 -padx 5 + + set name $repo_config(gui.newbranchtemplate) + + bind $w " + grab $w + $w_name icursor end + focus $w_name + " + bind $w [list destroy $w] + bind $w [cb _create]\;break + tkwait window $w +} + +method _create {} { + global null_sha1 repo_config + global all_heads + + set newbranch $name + if {$newbranch eq {} + || $newbranch eq $repo_config(gui.newbranchtemplate)} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Please supply a branch name." + focus $w_name + return + } + if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Branch '$newbranch' already exists." + focus $w_name + return + } + if {[catch {git check-ref-format "heads/$newbranch"}]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "We do not like '$newbranch' as a branch name." + focus $w_name + return + } + + if {[catch {set cmt [$w_rev get_commit]}]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Invalid starting revision: [$w_rev get]" + return + } + if {[catch { + git update-ref \ + -m "branch: Created from [$w_rev get]" \ + "refs/heads/$newbranch" \ + $cmt \ + $null_sha1 + } err]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Failed to create '$newbranch'.\n\n$err" + return + } + + lappend all_heads $newbranch + set all_heads [lsort $all_heads] + populate_branch_menu + destroy $w + if {$opt_checkout} { + switch_branch $newbranch + } +} + +method _validate {d S} { + if {$d == 1} { + if {[regexp {[~^:?*\[\0- ]} $S]} { + return 0 + } + if {[string length $S] > 0} { + set name_type user + } + } + return 1 +} + +} diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl new file mode 100644 index 0000000000..04f77c0092 --- /dev/null +++ b/lib/choose_rev.tcl @@ -0,0 +1,127 @@ +# git-gui revision chooser +# Copyright (C) 2006, 2007 Shawn Pearce + +class choose_rev { + +field w ; # our megawidget path +field revtype {}; # type of revision chosen + +field c_head {}; # selected local branch head +field c_trck {}; # selected tracking branch +field c_tag {}; # selected tag +field c_expr {}; # current revision expression + +constructor new {path {title {}}} { + global all_heads current_branch + + set w $path + + if {$title ne {}} { + labelframe $w -text $title + } else { + frame $w + } + bind $w [cb _delete %W] + + if {$all_heads ne {}} { + set c_head $current_branch + radiobutton $w.head_r \ + -text {Local Branch:} \ + -value head \ + -variable @revtype + eval tk_optionMenu $w.head_m @c_head $all_heads + grid $w.head_r $w.head_m -sticky w + if {$revtype eq {}} { + set revtype head + } + trace add variable @c_head write [cb _select head] + } + + set all_trackings [all_tracking_branches] + if {$all_trackings ne {}} { + set c_trck [lindex $all_trackings 0] + radiobutton $w.trck_r \ + -text {Tracking Branch:} \ + -value trck \ + -variable @revtype + eval tk_optionMenu $w.trck_m @c_trck $all_trackings + grid $w.trck_r $w.trck_m -sticky w + if {$revtype eq {}} { + set revtype trck + } + trace add variable @c_trck write [cb _select trck] + } + + set all_tags [load_all_tags] + if {$all_tags ne {}} { + set c_tag [lindex $all_tags 0] + radiobutton $w.tag_r \ + -text {Tag:} \ + -value tag \ + -variable @revtype + eval tk_optionMenu $w.tag_m @c_tag $all_tags + grid $w.tag_r $w.tag_m -sticky w + if {$revtype eq {}} { + set revtype tag + } + trace add variable @c_tag write [cb _select tag] + } + + radiobutton $w.expr_r \ + -text {Revision Expression:} \ + -value expr \ + -variable @revtype + entry $w.expr_t \ + -borderwidth 1 \ + -relief sunken \ + -width 50 \ + -textvariable @c_expr \ + -validate key \ + -validatecommand [cb _validate %d %S] + grid $w.expr_r $w.expr_t -sticky we -padx {0 5} + if {$revtype eq {}} { + set revtype expr + } + + grid columnconfigure $w 1 -weight 1 + return $this +} + +method get {} { + switch -- $revtype { + head { return $c_head } + trck { return $c_trck } + tag { return $c_tag } + expr { return $c_expr } + default { error "unknown type of revision" } + } +} + +method get_commit {} { + set rev [get $this] + return [git rev-parse --verify "${rev}^0"] +} + +method _validate {d S} { + if {$d == 1} { + if {[regexp {\s} $S]} { + return 0 + } + if {[string length $S] > 0} { + set revtype expr + } + } + return 1 +} + +method _select {value args} { + set revtype $value +} + +method _delete {current} { + if {$current eq $w} { + delete_this + } +} + +} From 3206c63d0a365b11a430225a31f6a673f7645c25 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 3 Jul 2007 23:33:59 -0400 Subject: [PATCH 108/213] git-gui: Refactor the delete branch dialog to use class system A simple refactoring of the delete branch dialog to allow use of the class construct to better organize the code and to reuse the revision selection code of our new choose_rev mega-widget. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 2 +- lib/branch.tcl | 164 ------------------------------------------ lib/branch_delete.tcl | 163 +++++++++++++++++++++++++++++++++++++++++ lib/choose_rev.tcl | 21 ++++++ 4 files changed, 185 insertions(+), 165 deletions(-) create mode 100644 lib/branch_delete.tcl diff --git a/git-gui.sh b/git-gui.sh index e07f4babd0..63b2045d96 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1507,7 +1507,7 @@ if {[is_enabled branch]} { [.mbar.branch index last] -state] .mbar.branch add command -label {Delete...} \ - -command do_delete_branch + -command branch_delete::dialog lappend disable_on_lock [list .mbar.branch entryconf \ [.mbar.branch index last] -state] diff --git a/lib/branch.tcl b/lib/branch.tcl index e7559f9789..e56f674c6d 100644 --- a/lib/branch.tcl +++ b/lib/branch.tcl @@ -66,170 +66,6 @@ proc radio_selector {varname value args} { set var $value } -proc do_delete_branch_action {w} { - global all_heads - global delete_branch_checktype delete_branch_head delete_branch_trackinghead - - set check_rev {} - switch -- $delete_branch_checktype { - head {set check_rev $delete_branch_head} - tracking {set check_rev $delete_branch_trackinghead} - always {set check_rev {:none}} - } - if {$check_rev eq {:none}} { - set check_cmt {} - } elseif {[catch {set check_cmt [git rev-parse --verify "${check_rev}^0"]}]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Invalid check revision: $check_rev" - return - } - - set to_delete [list] - set not_merged [list] - foreach i [$w.list.l curselection] { - set b [$w.list.l get $i] - if {[catch {set o [git rev-parse --verify $b]}]} continue - if {$check_cmt ne {}} { - if {$b eq $check_rev} continue - if {[catch {set m [git merge-base $o $check_cmt]}]} continue - if {$o ne $m} { - lappend not_merged $b - continue - } - } - lappend to_delete [list $b $o] - } - if {$not_merged ne {}} { - set msg "The following branches are not completely merged into $check_rev: - - - [join $not_merged "\n - "]" - tk_messageBox \ - -icon info \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message $msg - } - if {$to_delete eq {}} return - if {$delete_branch_checktype eq {always}} { - set msg {Recovering deleted branches is difficult. - -Delete the selected branches?} - if {[tk_messageBox \ - -icon warning \ - -type yesno \ - -title [wm title $w] \ - -parent $w \ - -message $msg] ne yes} { - return - } - } - - set failed {} - foreach i $to_delete { - set b [lindex $i 0] - set o [lindex $i 1] - if {[catch {git update-ref -d "refs/heads/$b" $o} err]} { - append failed " - $b: $err\n" - } else { - set x [lsearch -sorted -exact $all_heads $b] - if {$x >= 0} { - set all_heads [lreplace $all_heads $x $x] - } - } - } - - if {$failed ne {}} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Failed to delete branches:\n$failed" - } - - set all_heads [lsort $all_heads] - populate_branch_menu - destroy $w -} - -proc do_delete_branch {} { - global all_heads tracking_branches current_branch - global delete_branch_checktype delete_branch_head delete_branch_trackinghead - - set w .branch_editor - toplevel $w - wm geometry $w "+[winfo rootx .]+[winfo rooty .]" - - label $w.header -text {Delete Local Branch} \ - -font font_uibold - pack $w.header -side top -fill x - - frame $w.buttons - button $w.buttons.create -text Delete \ - -command [list do_delete_branch_action $w] - pack $w.buttons.create -side right - button $w.buttons.cancel -text {Cancel} \ - -command [list destroy $w] - pack $w.buttons.cancel -side right -padx 5 - pack $w.buttons -side bottom -fill x -pady 10 -padx 10 - - labelframe $w.list -text {Local Branches} - listbox $w.list.l \ - -height 10 \ - -width 70 \ - -selectmode extended \ - -yscrollcommand [list $w.list.sby set] - foreach h $all_heads { - if {$h ne $current_branch} { - $w.list.l insert end $h - } - } - scrollbar $w.list.sby -command [list $w.list.l yview] - pack $w.list.sby -side right -fill y - pack $w.list.l -side left -fill both -expand 1 - pack $w.list -fill both -expand 1 -pady 5 -padx 5 - - labelframe $w.validate -text {Delete Only If} - radiobutton $w.validate.head_r \ - -text {Merged Into Local Branch:} \ - -value head \ - -variable delete_branch_checktype - eval tk_optionMenu $w.validate.head_m delete_branch_head $all_heads - grid $w.validate.head_r $w.validate.head_m -sticky w - set all_trackings [all_tracking_branches] - if {$all_trackings ne {}} { - set delete_branch_trackinghead [lindex $all_trackings 0] - radiobutton $w.validate.tracking_r \ - -text {Merged Into Tracking Branch:} \ - -value tracking \ - -variable delete_branch_checktype - eval tk_optionMenu $w.validate.tracking_m \ - delete_branch_trackinghead \ - $all_trackings - grid $w.validate.tracking_r $w.validate.tracking_m -sticky w - } - radiobutton $w.validate.always_r \ - -text {Always (Do not perform merge checks)} \ - -value always \ - -variable delete_branch_checktype - grid $w.validate.always_r -columnspan 2 -sticky w - grid columnconfigure $w.validate 1 -weight 1 - pack $w.validate -anchor nw -fill x -pady 5 -padx 5 - - set delete_branch_head $current_branch - set delete_branch_checktype head - - bind $w "grab $w; focus $w" - bind $w "destroy $w" - wm title $w "[appname] ([reponame]): Delete Branch" - tkwait window $w -} - proc switch_branch {new_branch} { global HEAD commit_type current_branch repo_config diff --git a/lib/branch_delete.tcl b/lib/branch_delete.tcl new file mode 100644 index 0000000000..16ca6938be --- /dev/null +++ b/lib/branch_delete.tcl @@ -0,0 +1,163 @@ +# git-gui branch delete support +# Copyright (C) 2007 Shawn Pearce + +class branch_delete { + +field w ; # widget path +field w_heads ; # listbox of local head names +field w_check ; # revision picker for merge test +field w_delete ; # delete button + +constructor dialog {} { + global all_heads current_branch + + make_toplevel top w + wm title $top "[appname] ([reponame]): Delete Branch" + if {$top ne {.}} { + wm geometry $top "+[winfo rootx .]+[winfo rooty .]" + } + + label $w.header -text {Delete Local Branch} -font font_uibold + pack $w.header -side top -fill x + + frame $w.buttons + set w_delete $w.buttons.delete + button $w_delete \ + -text Delete \ + -default active \ + -state disabled \ + -command [cb _delete] + pack $w_delete -side right + button $w.buttons.cancel \ + -text {Cancel} \ + -command [list destroy $w] + pack $w.buttons.cancel -side right -padx 5 + pack $w.buttons -side bottom -fill x -pady 10 -padx 10 + + labelframe $w.list -text {Local Branches} + set w_heads $w.list.l + listbox $w_heads \ + -height 10 \ + -width 70 \ + -selectmode extended \ + -yscrollcommand [list $w.list.sby set] + scrollbar $w.list.sby -command [list $w.list.l yview] + pack $w.list.sby -side right -fill y + pack $w.list.l -side left -fill both -expand 1 + pack $w.list -fill both -expand 1 -pady 5 -padx 5 + + set w_check [choose_rev::new \ + $w.check \ + {Delete Only If Merged Into} \ + ] + $w_check none {Always (Do not perform merge test.)} + pack $w.check -anchor nw -fill x -pady 5 -padx 5 + + foreach h $all_heads { + if {$h ne $current_branch} { + $w_heads insert end $h + } + } + + bind $w_heads <> [cb _select] + bind $w " + grab $w + focus $w + " + bind $w [list destroy $w] + bind $w [cb _delete]\;break + tkwait window $w +} + +method _select {} { + if {[$w_heads curselection] eq {}} { + $w_delete configure -state disabled + } else { + $w_delete configure -state normal + } +} + +method _delete {} { + global all_heads + + if {[catch {set check_cmt [$w_check get_commit]} err]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Invalid revision: [$w_check get]" + return + } + + set to_delete [list] + set not_merged [list] + foreach i [$w_heads curselection] { + set b [$w_heads get $i] + if {[catch { + set o [git rev-parse --verify "refs/heads/$b"] + }]} continue + if {$check_cmt ne {}} { + if {[catch {set m [git merge-base $o $check_cmt]}]} continue + if {$o ne $m} { + lappend not_merged $b + continue + } + } + lappend to_delete [list $b $o] + } + if {$not_merged ne {}} { + set msg "The following branches are not completely merged into [$w_check get]: + + - [join $not_merged "\n - "]" + tk_messageBox \ + -icon info \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message $msg + } + if {$to_delete eq {}} return + if {$check_cmt eq {}} { + set msg {Recovering deleted branches is difficult. + +Delete the selected branches?} + if {[tk_messageBox \ + -icon warning \ + -type yesno \ + -title [wm title $w] \ + -parent $w \ + -message $msg] ne yes} { + return + } + } + + set failed {} + foreach i $to_delete { + set b [lindex $i 0] + set o [lindex $i 1] + if {[catch {git update-ref -d "refs/heads/$b" $o} err]} { + append failed " - $b: $err\n" + } else { + set x [lsearch -sorted -exact $all_heads $b] + if {$x >= 0} { + set all_heads [lreplace $all_heads $x $x] + } + } + } + + if {$failed ne {}} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Failed to delete branches:\n$failed" + } + + set all_heads [lsort $all_heads] + populate_branch_menu + destroy $w +} + +} diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index 04f77c0092..01e8efe991 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -87,17 +87,38 @@ constructor new {path {title {}}} { return $this } +method none {text} { + if {[winfo exists $w.none_r]} { + $w.none_r configure -text $text + return + } + + radiobutton $w.none_r \ + -anchor w \ + -text $text \ + -value none \ + -variable @revtype + grid $w.none_r -sticky we -padx {0 5} -columnspan 2 + if {$revtype eq {}} { + set revtype none + } +} + method get {} { switch -- $revtype { head { return $c_head } trck { return $c_trck } tag { return $c_tag } expr { return $c_expr } + none { return {} } default { error "unknown type of revision" } } } method get_commit {} { + if {$revtype eq {none}} { + return {} + } set rev [get $this] return [git rev-parse --verify "${rev}^0"] } From 6f2a3fc812623bc82fb4997adb5a9a547b5dae1a Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 4 Jul 2007 00:15:41 -0400 Subject: [PATCH 109/213] git-gui: Optimize for newstyle refs/remotes layout Most people using Git 1.5.x and later are using the newer style of remotes layout where all of their tracking branches are in refs/remotes and refs/heads contains only the user's own local branches. In such a situation we can avoid calling is_tracking_branch for each head we are considering because we know that all of the heads must be local branches if no fetch option or Pull: line maps a branch into that namespace. If however any remote maps a remote branch into a local tracking branch that resides in refs/heads we do exactly what we did before, which requires scanning through all fetch lines in case any patterns are matched. I also switched some regexp/regsub calls to string match as this can be a faster operation for prefix matching. Signed-off-by: Shawn O. Pearce --- lib/branch.tcl | 11 +++++++---- lib/remote.tcl | 50 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/lib/branch.tcl b/lib/branch.tcl index e56f674c6d..de638d02e8 100644 --- a/lib/branch.tcl +++ b/lib/branch.tcl @@ -3,13 +3,16 @@ proc load_all_heads {} { global all_heads + global some_heads_tracking + set rh refs/heads + set rh_len [expr {[string length $rh] + 1}] set all_heads [list] - set fd [open "| git for-each-ref --format=%(refname) refs/heads" r] + set fd [open "| git for-each-ref --format=%(refname) $rh" r] while {[gets $fd line] > 0} { - if {[is_tracking_branch $line]} continue - if {![regsub ^refs/heads/ $line {} name]} continue - lappend all_heads $name + if {!$some_heads_tracking || ![is_tracking_branch $line]} { + lappend all_heads [string range $line $rh_len end] + } } close $fd diff --git a/lib/remote.tcl b/lib/remote.tcl index b54824ab72..55a6dc3301 100644 --- a/lib/remote.tcl +++ b/lib/remote.tcl @@ -1,14 +1,13 @@ # git-gui remote management # Copyright (C) 2006, 2007 Shawn Pearce +set some_heads_tracking 0; # assume not + proc is_tracking_branch {name} { global tracking_branches - - if {![catch {set info $tracking_branches($name)}]} { - return 1 - } - foreach t [array names tracking_branches] { - if {[string match {*/\*} $t] && [string match $t $name]} { + foreach spec $tracking_branches { + set t [lindex $spec 0] + if {$t eq $name || [string match $t $name]} { return 1 } } @@ -20,9 +19,10 @@ proc all_tracking_branches {} { set all_trackings {} set cmd {} - foreach name [array names tracking_branches] { - if {[regsub {/\*$} $name {} name]} { - lappend cmd $name + foreach spec $tracking_branches { + set name [lindex $spec 0] + if {[string range $name end-1 end] eq {/*}} { + lappend cmd [string range $name 0 end-2] } else { regsub ^refs/(heads|remotes)/ $name {} name lappend all_trackings $name @@ -43,11 +43,14 @@ proc all_tracking_branches {} { proc load_all_remotes {} { global repo_config - global all_remotes tracking_branches + global all_remotes tracking_branches some_heads_tracking + set some_heads_tracking 0 set all_remotes [list] - array unset tracking_branches + set trck [list] + set rh_str refs/heads/ + set rh_len [string length $rh_str] set rm_dir [gitdir remotes] if {[file isdirectory $rm_dir]} { set all_remotes [glob \ @@ -62,10 +65,16 @@ proc load_all_remotes {} { while {[gets $fd line] >= 0} { if {![regexp {^Pull:[ ]*([^:]+):(.+)$} \ $line line src dst]} continue - if {![regexp ^refs/ $dst]} { - set dst "refs/heads/$dst" + if {![string equal -length 5 refs/ $src]} { + set src $rh_str$src } - set tracking_branches($dst) [list $name $src] + if {![string equal -length 5 refs/ $dst]} { + set dst $rh_str$dst + } + if {[string equal -length $rh_len $rh_str $dst]} { + set some_heads_tracking 1 + } + lappend trck [list $dst $name $src] } close $fd } @@ -81,13 +90,20 @@ proc load_all_remotes {} { } foreach line $fl { if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue - if {![regexp ^refs/ $dst]} { - set dst "refs/heads/$dst" + if {![string equal -length 5 refs/ $src]} { + set src $rh_str$src } - set tracking_branches($dst) [list $name $src] + if {![string equal -length 5 refs/ $dst]} { + set dst $rh_str$dst + } + if {[string equal -length $rh_len $rh_str $dst]} { + set some_heads_tracking 1 + } + lappend trck [list $dst $name $src] } } + set tracking_branches [lsort -index 0 -unique $trck] set all_remotes [lsort -unique $all_remotes] } From 79a060e477a743ad49508aec9a491fe1aa7d7c3b Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 4 Jul 2007 01:10:41 -0400 Subject: [PATCH 110/213] git-gui: Maintain remote and source ref for tracking branches In the next change I want to let the user create their local branch name to match the remote branch name, so that the existing push dialog can push the branch back up to the remote repository without needing to do any sort of remapping. To do that we need to know exactly what branch name the remote system is using. So all_tracking_branches returns a list of specifications, where each specification is itself a list of: - local ref name (destination we fetch into) - remote name (repository we fetch from) - remote ref name (source ref we fetch from) Signed-off-by: Shawn O. Pearce --- lib/choose_rev.tcl | 35 +++++++++++++++++++++++++++++------ lib/remote.tcl | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index 01e8efe991..b3b615ee42 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -11,6 +11,8 @@ field c_trck {}; # selected tracking branch field c_tag {}; # selected tag field c_expr {}; # current revision expression +field trck_spec ; # array of specifications + constructor new {path {title {}}} { global all_heads current_branch @@ -37,19 +39,30 @@ constructor new {path {title {}}} { trace add variable @c_head write [cb _select head] } - set all_trackings [all_tracking_branches] - if {$all_trackings ne {}} { - set c_trck [lindex $all_trackings 0] + set trck_list [all_tracking_branches] + if {$trck_list ne {}} { + set nam [list] + foreach spec $trck_list { + set txt [lindex $spec 0] + regsub ^refs/(heads/|remotes/)? $txt {} txt + set trck_spec($txt) $spec + lappend nam $txt + } + set nam [lsort -unique $nam] + radiobutton $w.trck_r \ -text {Tracking Branch:} \ -value trck \ -variable @revtype - eval tk_optionMenu $w.trck_m @c_trck $all_trackings + eval tk_optionMenu $w.trck_m @c_trck $nam grid $w.trck_r $w.trck_m -sticky w + + set c_trck [lindex $nam 0] if {$revtype eq {}} { set revtype trck } trace add variable @c_trck write [cb _select trck] + unset nam spec txt } set all_tags [load_all_tags] @@ -115,12 +128,22 @@ method get {} { } } +method get_expr {} { + switch -- $revtype { + head { return refs/heads/$c_head } + trck { return [lindex $trck_spec($c_trck) 0] } + tag { return refs/tags/$c_tag } + expr { return $c_expr } + none { return {} } + default { error "unknown type of revision" } + } +} + method get_commit {} { if {$revtype eq {none}} { return {} } - set rev [get $this] - return [git rev-parse --verify "${rev}^0"] + return [git rev-parse --verify "[get_expr $this]^0"] } method _validate {d S} { diff --git a/lib/remote.tcl b/lib/remote.tcl index 55a6dc3301..fabec05fff 100644 --- a/lib/remote.tcl +++ b/lib/remote.tcl @@ -17,28 +17,41 @@ proc is_tracking_branch {name} { proc all_tracking_branches {} { global tracking_branches - set all_trackings {} - set cmd {} + set all [list] + set pat [list] + set cmd [list] + foreach spec $tracking_branches { - set name [lindex $spec 0] - if {[string range $name end-1 end] eq {/*}} { - lappend cmd [string range $name 0 end-2] + set dst [lindex $spec 0] + if {[string range $dst end-1 end] eq {/*}} { + lappend pat $spec + lappend cmd [string range $dst 0 end-2] } else { - regsub ^refs/(heads|remotes)/ $name {} name - lappend all_trackings $name + lappend all $spec } } - if {$cmd ne {}} { + if {$pat ne {}} { set fd [open "| git for-each-ref --format=%(refname) $cmd" r] - while {[gets $fd name] > 0} { - regsub ^refs/(heads|remotes)/ $name {} name - lappend all_trackings $name + while {[gets $fd n] > 0} { + foreach spec $pat { + set dst [string range [lindex $spec 0] 0 end-2] + set len [string length $dst] + if {[string equal -length $len $dst $n]} { + set src [string range [lindex $spec 2] 0 end-2] + set spec [list \ + $n \ + [lindex $spec 1] \ + $src[string range $n $len end] \ + ] + lappend all $spec + } + } } close $fd } - return [lsort -unique $all_trackings] + return [lsort -index 0 -unique $all] } proc load_all_remotes {} { @@ -65,6 +78,9 @@ proc load_all_remotes {} { while {[gets $fd line] >= 0} { if {![regexp {^Pull:[ ]*([^:]+):(.+)$} \ $line line src dst]} continue + if {[string index $src 0] eq {+}} { + set src [string range $src 1 end] + } if {![string equal -length 5 refs/ $src]} { set src $rh_str$src } @@ -90,6 +106,9 @@ proc load_all_remotes {} { } foreach line $fl { if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue + if {[string index $src 0] eq {+}} { + set src [string range $src 1 end] + } if {![string equal -length 5 refs/ $src]} { set src $rh_str$src } From dd87efc8cc71ceb6aa9a27e900976c317c927846 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 4 Jul 2007 02:19:53 -0400 Subject: [PATCH 111/213] git-gui: Allow users to match remote branch names locally Some workflows have users create a local branch that matches a remote branch they have fetched from another repository. If the user wants to push their changes back to that remote repository then they probably want to use the same branch name locally so that git-gui's push dialog can setup the push refspec automatically. To prevent typos with the local branch name we now offer an option to use the remote tracking branch name as the new local branch name. Signed-off-by: Shawn O. Pearce --- lib/branch_create.tcl | 45 +++++++++++++++++++++++++++++++++++++++---- lib/choose_rev.tcl | 8 ++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/branch_create.tcl b/lib/branch_create.tcl index ef63f810f4..7f82424eda 100644 --- a/lib/branch_create.tcl +++ b/lib/branch_create.tcl @@ -8,6 +8,8 @@ field w_rev ; # mega-widget to pick the initial revision field w_name ; # new branch name widget field name {}; # name of the branch the user has chosen +field name_type user; # type of branch name to use + field opt_checkout 1; # automatically checkout the new branch? constructor dialog {} { @@ -32,10 +34,12 @@ constructor dialog {} { pack $w.buttons.cancel -side right -padx 5 pack $w.buttons -side bottom -fill x -pady 10 -padx 10 - labelframe $w.desc -text {Branch Description} - label $w.desc.name_r \ + labelframe $w.desc -text {Branch Name} + radiobutton $w.desc.name_r \ -anchor w \ - -text {Name:} + -text {Name:} \ + -value user \ + -variable @name_type set w_name $w.desc.name_t entry $w_name \ -borderwidth 1 \ @@ -46,6 +50,13 @@ constructor dialog {} { -validatecommand [cb _validate %d %S] grid $w.desc.name_r $w_name -sticky we -padx {0 5} + radiobutton $w.desc.match_r \ + -anchor w \ + -text {Match Tracking Branch Name} \ + -value match \ + -variable @name_type + grid $w.desc.match_r -sticky we -padx {0 5} -columnspan 2 + grid columnconfigure $w.desc 1 -weight 1 pack $w.desc -anchor nw -fill x -pady 5 -padx 5 @@ -75,7 +86,33 @@ method _create {} { global null_sha1 repo_config global all_heads - set newbranch $name + switch -- $name_type { + user { + set newbranch $name + } + match { + set spec [$w_rev get_tracking_branch] + if {$spec eq {}} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Please select a tracking branch." + return + } + if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Tracking branch [$w get] is not a branch in the remote repository." + return + } + } + } + if {$newbranch eq {} || $newbranch eq $repo_config(gui.newbranchtemplate)} { tk_messageBox \ diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index b3b615ee42..8b92412943 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -128,6 +128,14 @@ method get {} { } } +method get_tracking_branch {} { + if {$revtype eq {trck}} { + return $trck_spec($c_trck) + } else { + return {} + } +} + method get_expr {} { switch -- $revtype { head { return refs/heads/$c_head } From 774173aa5f24023a82ce79f2a71fe3f664b747ad Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 4 Jul 2007 04:21:57 -0400 Subject: [PATCH 112/213] git-gui: Fast-forward existing branch in branch create dialog If the user elects to create a local branch that has the same name as an existing branch and we can fast-forward the local branch to the selected revision we might as well do the fast-forward for the user, rather than making them first switch to the branch then merge the selected revision into it. After all, its really just a fast forward. No history is lost. The resulting branch checkout may also be faster if the branch we are switching from is closer to the new revision. Likewise we also now allow the user to reset the local branch if it already exists but would not fast-forward. However before we do the actual reset we tell the user what commits they are going to lose by showing the oneline subject and abbreviated sha1, and we also let them inspect the range of commits in gitk. Signed-off-by: Shawn O. Pearce --- lib/branch_create.tcl | 262 +++++++++++++++++++++++++++++++++++------- 1 file changed, 219 insertions(+), 43 deletions(-) diff --git a/lib/branch_create.tcl b/lib/branch_create.tcl index 7f82424eda..0272d6f024 100644 --- a/lib/branch_create.tcl +++ b/lib/branch_create.tcl @@ -10,7 +10,9 @@ field w_name ; # new branch name widget field name {}; # name of the branch the user has chosen field name_type user; # type of branch name to use +field opt_merge ff; # type of merge to apply to existing branch field opt_checkout 1; # automatically checkout the new branch? +field reset_ok 0; # did the user agree to reset? constructor dialog {} { global repo_config @@ -63,12 +65,33 @@ constructor dialog {} { set w_rev [::choose_rev::new $w.rev {Starting Revision}] pack $w.rev -anchor nw -fill x -pady 5 -padx 5 - labelframe $w.postActions -text {Post Creation Actions} - checkbutton $w.postActions.checkout \ - -text {Checkout after creation} \ + labelframe $w.options -text {Options} + + frame $w.options.merge + label $w.options.merge.l -text {Update Existing Branch:} + pack $w.options.merge.l -side left + radiobutton $w.options.merge.no \ + -text No \ + -value no \ + -variable @opt_merge + pack $w.options.merge.no -side left + radiobutton $w.options.merge.ff \ + -text {Fast Forward Only} \ + -value ff \ + -variable @opt_merge + pack $w.options.merge.ff -side left + radiobutton $w.options.merge.reset \ + -text {Reset} \ + -value reset \ + -variable @opt_merge + pack $w.options.merge.reset -side left + pack $w.options.merge -anchor nw + + checkbutton $w.options.checkout \ + -text {Checkout After Creation} \ -variable @opt_checkout - pack $w.postActions.checkout -anchor nw - pack $w.postActions -anchor nw -fill x -pady 5 -padx 5 + pack $w.options.checkout -anchor nw + pack $w.options -anchor nw -fill x -pady 5 -padx 5 set name $repo_config(gui.newbranchtemplate) @@ -84,7 +107,7 @@ constructor dialog {} { method _create {} { global null_sha1 repo_config - global all_heads + global all_heads current_branch switch -- $name_type { user { @@ -124,7 +147,46 @@ method _create {} { focus $w_name return } - if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} { + + if {$newbranch eq $current_branch} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "'$newbranch' already exists and is the current branch." + focus $w_name + return + } + + if {[catch {git check-ref-format "heads/$newbranch"}]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "'$newbranch' is not an acceptable branch name." + focus $w_name + return + } + + if {[catch {set new [$w_rev get_commit]}]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Invalid revision: [$w_rev get]" + return + } + + set ref refs/heads/$newbranch + if {[catch {set cur [git rev-parse --verify "$ref^0"]}]} { + # Assume it does not exist, and that is what the error was. + # + set reflog_msg "branch: Created from [$w_rev get]" + set cur $null_sha1 + } elseif {$opt_merge eq {no}} { tk_messageBox \ -icon error \ -type ok \ @@ -133,52 +195,166 @@ method _create {} { -message "Branch '$newbranch' already exists." focus $w_name return - } - if {[catch {git check-ref-format "heads/$newbranch"}]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "We do not like '$newbranch' as a branch name." - focus $w_name - return + } else { + set mrb {} + catch {set mrb [git merge-base $new $cur]} + switch -- $opt_merge { + ff { + if {$mrb eq $new} { + # The current branch is actually newer. + # + set new $cur + } elseif {$mrb eq $cur} { + # The current branch is older. + # + set reflog_msg "merge [$w_rev get]: Fast-forward" + } else { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Branch '$newbranch' already exists.\n\nIt cannot fast-forward to [$w_rev get].\nA merge is required." + focus $w_name + return + } + } + reset { + if {$mrb eq $cur} { + # The current branch is older. + # + set reflog_msg "merge [$w_rev get]: Fast-forward" + } else { + # The current branch will lose things. + # + if {[_confirm_reset $this $newbranch $cur $new]} { + set reflog_msg "reset [$w_rev get]" + } else { + return + } + } + } + default { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Branch '$newbranch' already exists." + focus $w_name + return + } + } } - if {[catch {set cmt [$w_rev get_commit]}]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Invalid starting revision: [$w_rev get]" - return - } - if {[catch { - git update-ref \ - -m "branch: Created from [$w_rev get]" \ - "refs/heads/$newbranch" \ - $cmt \ - $null_sha1 - } err]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Failed to create '$newbranch'.\n\n$err" - return + if {$new ne $cur} { + if {[catch { + git update-ref -m $reflog_msg $ref $new $cur + } err]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Failed to create '$newbranch'.\n\n$err" + return + } + } + + if {$cur eq $null_sha1} { + lappend all_heads $newbranch + set all_heads [lsort -uniq $all_heads] + populate_branch_menu } - lappend all_heads $newbranch - set all_heads [lsort $all_heads] - populate_branch_menu destroy $w if {$opt_checkout} { switch_branch $newbranch } } +method _confirm_reset {newbranch cur new} { + set reset_ok 0 + set gitk [list do_gitk [list $cur ^$new]] + + set c $w.confirm_reset + toplevel $c + wm title $c "Confirm Branch Reset" + wm geometry $c "+[winfo rootx $w]+[winfo rooty $w]" + + pack [label $c.msg1 \ + -anchor w \ + -justify left \ + -text "Resetting '$newbranch' to [$w_rev get] will lose the following commits:" \ + ] -anchor w + + set list $c.list.l + frame $c.list + text $list \ + -font font_diff \ + -width 80 \ + -height 10 \ + -wrap none \ + -xscrollcommand [list $c.list.sbx set] \ + -yscrollcommand [list $c.list.sby set] + scrollbar $c.list.sbx -orient h -command [list $list xview] + scrollbar $c.list.sby -orient v -command [list $list yview] + pack $c.list.sbx -fill x -side bottom + pack $c.list.sby -fill y -side right + pack $list -fill both -expand 1 + pack $c.list -fill both -expand 1 -padx 5 -pady 5 + + pack [label $c.msg2 \ + -anchor w \ + -justify left \ + -text "Recovering lost commits may not be easy." \ + ] + pack [label $c.msg3 \ + -anchor w \ + -justify left \ + -text "Reset '$newbranch'?" \ + ] + + frame $c.buttons + button $c.buttons.visualize \ + -text Visualize \ + -command $gitk + pack $c.buttons.visualize -side left + button $c.buttons.reset \ + -text Reset \ + -command " + set @reset_ok 1 + destroy $c + " + pack $c.buttons.reset -side right + button $c.buttons.cancel \ + -default active \ + -text Cancel \ + -command [list destroy $c] + pack $c.buttons.cancel -side right -padx 5 + pack $c.buttons -side bottom -fill x -pady 10 -padx 10 + + set fd [open "| git rev-list --pretty=oneline $cur ^$new" r] + while {[gets $fd line] > 0} { + set abbr [string range $line 0 7] + set subj [string range $line 41 end] + $list insert end "$abbr $subj\n" + } + close $fd + $list configure -state disabled + + bind $c $gitk + + bind $c " + grab $c + focus $c.buttons.cancel + " + bind $c [list destroy $c] + bind $c [list destroy $c] + tkwait window $c + return $reset_ok +} + method _validate {d S} { if {$d == 1} { if {[regexp {[~^:?*\[\0- ]} $S]} { From 7618e6b1c1676dfdc2cc4c8af9e259c3e885825f Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 4 Jul 2007 16:38:13 -0400 Subject: [PATCH 113/213] git-gui: Enhance choose_rev to handle hundreds of branches One of my production repositories has hundreds of remote tracking branches. Trying to navigate these through a popup menu is just not possible. The list is far larger than the screen and it does not scroll fast enough to efficiently select a branch name when trying to create a branch or delete a branch. This is major rewrite of the revision chooser mega-widget. We now use a single listbox for all three major types of named refs (heads, tracking branches, tags) and a radio button group to pick which of those namespaces should be shown in the listbox. A filter field is shown to the right allowing the end-user to key in a glob specification to filter the list they are viewing. The filter is always taken as substring, so we assume * both starts and ends the pattern the user wanted but otherwise treat it as a glob pattern. This new picker works out really nicely. What used to take me at least a minute to find and select a branch now takes mere seconds. Signed-off-by: Shawn O. Pearce --- lib/branch_create.tcl | 10 +- lib/branch_delete.tcl | 9 +- lib/choose_rev.tcl | 346 ++++++++++++++++++++++++++++++------------ 3 files changed, 250 insertions(+), 115 deletions(-) diff --git a/lib/branch_create.tcl b/lib/branch_create.tcl index 0272d6f024..375f575eaf 100644 --- a/lib/branch_create.tcl +++ b/lib/branch_create.tcl @@ -63,7 +63,7 @@ constructor dialog {} { pack $w.desc -anchor nw -fill x -pady 5 -padx 5 set w_rev [::choose_rev::new $w.rev {Starting Revision}] - pack $w.rev -anchor nw -fill x -pady 5 -padx 5 + pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5 labelframe $w.options -text {Options} @@ -170,13 +170,7 @@ method _create {} { return } - if {[catch {set new [$w_rev get_commit]}]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Invalid revision: [$w_rev get]" + if {[catch {set new [$w_rev commit_or_die]}]} { return } diff --git a/lib/branch_delete.tcl b/lib/branch_delete.tcl index 16ca6938be..138e84192c 100644 --- a/lib/branch_delete.tcl +++ b/lib/branch_delete.tcl @@ -40,6 +40,7 @@ constructor dialog {} { -height 10 \ -width 70 \ -selectmode extended \ + -exportselection false \ -yscrollcommand [list $w.list.sby set] scrollbar $w.list.sby -command [list $w.list.l yview] pack $w.list.sby -side right -fill y @@ -80,13 +81,7 @@ method _select {} { method _delete {} { global all_heads - if {[catch {set check_cmt [$w_check get_commit]} err]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Invalid revision: [$w_check get]" + if {[catch {set check_cmt [$w_check commit_or_die]}]} { return } diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index 8b92412943..f19da0f633 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -3,15 +3,19 @@ class choose_rev { +image create photo ::choose_rev::img_find -data {R0lGODlhEAAQAIYAAPwCBCQmJDw+PBQSFAQCBMza3NTm5MTW1HyChOT29Ozq7MTq7Kze5Kzm7Oz6/NTy9Iza5GzGzKzS1Nzy9Nz29Kzq9HTGzHTK1Lza3AwKDLzu9JTi7HTW5GTCzITO1Mzq7Hza5FTK1ESyvHzKzKzW3DQyNDyqtDw6PIzW5HzGzAT+/Dw+RKyurNTOzMTGxMS+tJSGdATCxHRydLSqpLymnLSijBweHERCRNze3Pz69PTy9Oze1OTSxOTGrMSqlLy+vPTu5OzSvMymjNTGvNS+tMy2pMyunMSefAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe4gACCAAECA4OIiAIEBQYHBAKJgwIICQoLDA0IkZIECQ4PCxARCwSSAxITFA8VEBYXGBmJAQYLGhUbHB0eH7KIGRIMEBAgISIjJKaIJQQLFxERIialkieUGigpKRoIBCqJKyyLBwvJAioEyoICLS4v6QQwMQQyLuqLli8zNDU2BCf1lN3AkUPHDh49fAQAAEnGD1MCCALZEaSHkIUMBQS8wWMIkSJGhBzBmFEGgRsBUqpMiSgdAD+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7} + field w ; # our megawidget path -field revtype {}; # type of revision chosen +field w_list ; # list of currently filtered specs +field w_filter ; # filter entry for $w_list -field c_head {}; # selected local branch head -field c_trck {}; # selected tracking branch -field c_tag {}; # selected tag field c_expr {}; # current revision expression - -field trck_spec ; # array of specifications +field filter ; # current filter string +field revtype head; # type of revision chosen +field cur_specs [list]; # list of specs for $revtype +field spec_head ; # list of all head specs +field spec_trck ; # list of all tracking branch specs +field spec_tag ; # list of all tag specs constructor new {path {title {}}} { global all_heads current_branch @@ -25,61 +29,6 @@ constructor new {path {title {}}} { } bind $w [cb _delete %W] - if {$all_heads ne {}} { - set c_head $current_branch - radiobutton $w.head_r \ - -text {Local Branch:} \ - -value head \ - -variable @revtype - eval tk_optionMenu $w.head_m @c_head $all_heads - grid $w.head_r $w.head_m -sticky w - if {$revtype eq {}} { - set revtype head - } - trace add variable @c_head write [cb _select head] - } - - set trck_list [all_tracking_branches] - if {$trck_list ne {}} { - set nam [list] - foreach spec $trck_list { - set txt [lindex $spec 0] - regsub ^refs/(heads/|remotes/)? $txt {} txt - set trck_spec($txt) $spec - lappend nam $txt - } - set nam [lsort -unique $nam] - - radiobutton $w.trck_r \ - -text {Tracking Branch:} \ - -value trck \ - -variable @revtype - eval tk_optionMenu $w.trck_m @c_trck $nam - grid $w.trck_r $w.trck_m -sticky w - - set c_trck [lindex $nam 0] - if {$revtype eq {}} { - set revtype trck - } - trace add variable @c_trck write [cb _select trck] - unset nam spec txt - } - - set all_tags [load_all_tags] - if {$all_tags ne {}} { - set c_tag [lindex $all_tags 0] - radiobutton $w.tag_r \ - -text {Tag:} \ - -value tag \ - -variable @revtype - eval tk_optionMenu $w.tag_m @c_tag $all_tags - grid $w.tag_r $w.tag_m -sticky w - if {$revtype eq {}} { - set revtype tag - } - trace add variable @c_tag write [cb _select tag] - } - radiobutton $w.expr_r \ -text {Revision Expression:} \ -value expr \ @@ -92,66 +41,186 @@ constructor new {path {title {}}} { -validate key \ -validatecommand [cb _validate %d %S] grid $w.expr_r $w.expr_t -sticky we -padx {0 5} - if {$revtype eq {}} { - set revtype expr - } + + frame $w.types + radiobutton $w.types.head_r \ + -text {Local Branch} \ + -value head \ + -variable @revtype + pack $w.types.head_r -side left + radiobutton $w.types.trck_r \ + -text {Tracking Branch} \ + -value trck \ + -variable @revtype + pack $w.types.trck_r -side left + radiobutton $w.types.tag_r \ + -text {Tag} \ + -value tag \ + -variable @revtype + pack $w.types.tag_r -side left + set w_filter $w.types.filter + entry $w_filter \ + -borderwidth 1 \ + -relief sunken \ + -width 12 \ + -textvariable @filter \ + -validate key \ + -validatecommand [cb _filter %P] + pack $w_filter -side right + pack [label $w.types.filter_icon \ + -image ::choose_rev::img_find \ + ] -side right + grid $w.types -sticky we -padx {0 5} -columnspan 2 + + frame $w.list + set w_list $w.list.l + listbox $w_list \ + -font font_diff \ + -width 50 \ + -height 5 \ + -selectmode browse \ + -exportselection false \ + -xscrollcommand [cb _sb_set $w.list.sbx h] \ + -yscrollcommand [cb _sb_set $w.list.sby v] + pack $w_list -fill both -expand 1 + grid $w.list -sticky nswe -padx {20 5} -columnspan 2 grid columnconfigure $w 1 -weight 1 + grid rowconfigure $w 2 -weight 1 + + trace add variable @revtype write [cb _select] + bind $w_filter [list focus $w_list]\;break + bind $w_filter [list focus $w_list] + + set spec_head [list] + foreach name $all_heads { + lappend spec_head [list $name refs/heads/$name] + } + + set spec_trck [list] + foreach spec [all_tracking_branches] { + set name [lindex $spec 0] + regsub ^refs/(heads|remotes)/ $name {} name + lappend spec_trck [concat $name $spec] + } + + set spec_tag [list] + foreach name [load_all_tags] { + lappend spec_tag [list $name refs/tags/$name] + } + + if {[llength $spec_head] > 0} { set revtype head + } elseif {[llength $spec_trck] > 0} { set revtype trck + } elseif {[llength $spec_tag ] > 0} { set revtype tag + } else { set revtype expr + } + + if {$revtype eq {head} && $current_branch ne {}} { + set i 0 + foreach spec $spec_head { + if {[lindex $spec 0] eq $current_branch} { + $w_list selection set $i + break + } + incr i + } + } + return $this } method none {text} { - if {[winfo exists $w.none_r]} { - $w.none_r configure -text $text - return - } - - radiobutton $w.none_r \ - -anchor w \ - -text $text \ - -value none \ - -variable @revtype - grid $w.none_r -sticky we -padx {0 5} -columnspan 2 - if {$revtype eq {}} { - set revtype none + if {![winfo exists $w.none_r]} { + radiobutton $w.none_r \ + -anchor w \ + -value none \ + -variable @revtype + grid $w.none_r -sticky we -padx {0 5} -columnspan 2 } + $w.none_r configure -text $text } method get {} { switch -- $revtype { - head { return $c_head } - trck { return $c_trck } - tag { return $c_tag } - expr { return $c_expr } - none { return {} } + head - + trck - + tag { + set i [$w_list curselection] + if {$i ne {}} { + return [lindex $cur_specs $i 0] + } else { + return {} + } + } + + expr { return $c_expr } + none { return {} } default { error "unknown type of revision" } } } method get_tracking_branch {} { - if {$revtype eq {trck}} { - return $trck_spec($c_trck) - } else { + set i [$w_list curselection] + if {$i eq {} || $revtype ne {trck}} { return {} } -} - -method get_expr {} { - switch -- $revtype { - head { return refs/heads/$c_head } - trck { return [lindex $trck_spec($c_trck) 0] } - tag { return refs/tags/$c_tag } - expr { return $c_expr } - none { return {} } - default { error "unknown type of revision" } - } + return [lrange [lindex $cur_specs $i] 1 end] } method get_commit {} { - if {$revtype eq {none}} { + set e [_expr $this] + if {$e eq {}} { return {} } - return [git rev-parse --verify "[get_expr $this]^0"] + return [git rev-parse --verify "$e^0"] +} + +method commit_or_die {} { + if {[catch {set new [get_commit $this]} err]} { + + # Cleanup the not-so-friendly error from rev-parse. + # + regsub {^fatal:\s*} $err {} err + if {$err eq {Needed a single revision}} { + set err {} + } + + set top [winfo toplevel $w] + set msg "Invalid revision: [get $this]\n\n$err" + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $top] \ + -parent $top \ + -message $msg + error $msg + } + return $new +} + +method _expr {} { + switch -- $revtype { + head - + trck - + tag { + set i [$w_list curselection] + if {$i ne {}} { + return [lindex $cur_specs $i 1] + } else { + error "No revision selected." + } + } + + expr { + if {$c_expr ne {}} { + return $c_expr + } else { + error "Revision expression is empty." + } + } + none { return {} } + default { error "unknown type of revision" } + } } method _validate {d S} { @@ -166,8 +235,55 @@ method _validate {d S} { return 1 } -method _select {value args} { - set revtype $value +method _filter {P} { + if {[regexp {\s} $P]} { + return 0 + } + _rebuild $this $P + return 1 +} + +method _select {args} { + _rebuild $this $filter + if {[$w_filter cget -state] eq {normal}} { + focus $w_filter + } +} + +method _rebuild {pat} { + set ste normal + switch -- $revtype { + head { set new $spec_head } + trck { set new $spec_trck } + tag { set new $spec_tag } + expr - + none { + set new [list] + set ste disabled + } + } + + if {[$w_list cget -state] eq {disabled}} { + $w_list configure -state normal + } + $w_list delete 0 end + + if {$pat ne {}} { + set pat *${pat}* + } + set cur_specs [list] + foreach spec $new { + set txt [lindex $spec 0] + if {$pat eq {} || [string match $pat $txt]} { + lappend cur_specs $spec + $w_list insert end $txt + } + } + + if {[$w_filter cget -state] ne $ste} { + $w_list configure -state $ste + $w_filter configure -state $ste + } } method _delete {current} { @@ -176,4 +292,34 @@ method _delete {current} { } } +method _sb_set {sb orient first last} { + set old_focus [focus -lastfor $w] + + if {$first == 0 && $last == 1} { + if {[winfo exists $sb]} { + destroy $sb + if {$old_focus ne {}} { + update + focus $old_focus + } + } + return + } + + if {![winfo exists $sb]} { + if {$orient eq {h}} { + scrollbar $sb -orient h -command [list $w_list xview] + pack $sb -fill x -side bottom -before $w_list + } else { + scrollbar $sb -orient v -command [list $w_list yview] + pack $sb -fill y -side right -before $w_list + } + if {$old_focus ne {}} { + update + focus $old_focus + } + } + $sb set $first $last +} + } From 560eddc00c02e82077998200e8d8a45c31af924c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 5 Jul 2007 00:07:11 -0400 Subject: [PATCH 114/213] git-gui: Sort tags descending by tagger date When trying to create a branch from a tag most people are looking for a recent tag, not one that is ancient history. Rather than sorting tags by their string we now sort them by taggerdate, as this places the recent tags at the top of the list and the very old ones at the end. Tag date works nicely as an approximation of the actual history order of commits. Signed-off-by: Shawn O. Pearce --- lib/branch.tcl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/branch.tcl b/lib/branch.tcl index de638d02e8..a6e6921174 100644 --- a/lib/branch.tcl +++ b/lib/branch.tcl @@ -21,14 +21,13 @@ proc load_all_heads {} { proc load_all_tags {} { set all_tags [list] - set fd [open "| git for-each-ref --format=%(refname) refs/tags" r] + set fd [open "| git for-each-ref --sort=-taggerdate --format=%(refname) refs/tags" r] while {[gets $fd line] > 0} { if {![regsub ^refs/tags/ $line {} name]} continue lappend all_tags $name } close $fd - - return [lsort $all_tags] + return $all_tags } proc populate_branch_menu {} { From 7cf044266779d69d3a16322b4d505bc87267a005 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 5 Jul 2007 01:07:06 -0400 Subject: [PATCH 115/213] git-gui: Option to default new branches to match tracking branches In some workflows users will want to almost always just create a new local branch that matches a remote branch. In this type of workflow it is handy to have the new branch dialog default to "Match Tracking Branch" and "Starting Revision"-Tracking Branch", with the focus in the branch filter field. This can save users working on this type of workflow at least two mouse clicks every time they create a new local branch or switch to one with a fast-forward. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 1 + lib/branch_create.tcl | 27 +++++++++++++++++++++------ lib/choose_rev.tcl | 4 ++++ lib/option.tcl | 1 + 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 63b2045d96..99df2d9480 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1339,6 +1339,7 @@ set default_config(merge.verbosity) 2 set default_config(user.name) {} set default_config(user.email) {} +set default_config(gui.matchtrackingbranch) false set default_config(gui.pruneduringfetch) false set default_config(gui.trustmtime) false set default_config(gui.diffcontext) 5 diff --git a/lib/branch_create.tcl b/lib/branch_create.tcl index 375f575eaf..df3f435e11 100644 --- a/lib/branch_create.tcl +++ b/lib/branch_create.tcl @@ -93,13 +93,14 @@ constructor dialog {} { pack $w.options.checkout -anchor nw pack $w.options -anchor nw -fill x -pady 5 -padx 5 - set name $repo_config(gui.newbranchtemplate) + trace add variable @name_type write [cb _select] - bind $w " - grab $w - $w_name icursor end - focus $w_name - " + set name $repo_config(gui.newbranchtemplate) + if {[is_config_true gui.matchtrackingbranch]} { + set name_type match + } + + bind $w [cb _visible] bind $w [list destroy $w] bind $w [cb _create]\;break tkwait window $w @@ -361,4 +362,18 @@ method _validate {d S} { return 1 } +method _select {args} { + if {$name_type eq {match}} { + $w_rev pick_tracking_branch + } +} + +method _visible {} { + grab $w + if {$name_type eq {user}} { + $w_name icursor end + focus $w_name + } +} + } diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index f19da0f633..e6af073595 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -159,6 +159,10 @@ method get {} { } } +method pick_tracking_branch {} { + set revtype trck +} + method get_tracking_branch {} { set i [$w_list curselection] if {$i eq {} || $revtype ne {trck}} { diff --git a/lib/option.tcl b/lib/option.tcl index ae19a8f9cf..743304269b 100644 --- a/lib/option.tcl +++ b/lib/option.tcl @@ -191,6 +191,7 @@ proc do_options {} { {b gui.trustmtime {Trust File Modification Timestamps}} {b gui.pruneduringfetch {Prune Tracking Branches During Fetch}} + {b gui.matchtrackingbranch {Match Tracking Branches}} {i-0..99 gui.diffcontext {Number of Diff Context Lines}} {t gui.newbranchtemplate {New Branch Name Template}} } { From ba1964be26b8b9e3441591257a2c87f5811d6b50 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 5 Jul 2007 02:23:53 -0400 Subject: [PATCH 116/213] git-gui: Automatically refresh tracking branches when needed If the user is creating a new local branch and has selected to use a tracking branch as the starting revision they probably want to make sure they are using the absolute latest version available of that branch. We now offer a checkbox "Fetch Tracking Branch" (on by default) that instructs git-gui to run git-fetch on just that one branch before resolving the branch name into a commit SHA-1 and making (or updating) the local branch. Signed-off-by: Shawn O. Pearce --- lib/branch_create.tcl | 58 ++++++++++++++++++++++++++++++++++++++++--- lib/console.tcl | 44 ++++++++++++++++++++++++-------- 2 files changed, 88 insertions(+), 14 deletions(-) diff --git a/lib/branch_create.tcl b/lib/branch_create.tcl index df3f435e11..f708957b22 100644 --- a/lib/branch_create.tcl +++ b/lib/branch_create.tcl @@ -12,6 +12,7 @@ field name_type user; # type of branch name to use field opt_merge ff; # type of merge to apply to existing branch field opt_checkout 1; # automatically checkout the new branch? +field opt_fetch 1; # refetch tracking branch if used? field reset_ok 0; # did the user agree to reset? constructor dialog {} { @@ -87,6 +88,11 @@ constructor dialog {} { pack $w.options.merge.reset -side left pack $w.options.merge -anchor nw + checkbutton $w.options.fetch \ + -text {Fetch Tracking Branch} \ + -variable @opt_fetch + pack $w.options.fetch -anchor nw + checkbutton $w.options.checkout \ -text {Checkout After Creation} \ -variable @opt_checkout @@ -107,15 +113,15 @@ constructor dialog {} { } method _create {} { - global null_sha1 repo_config - global all_heads current_branch + global repo_config current_branch + global M1B + set spec [$w_rev get_tracking_branch] switch -- $name_type { user { set newbranch $name } match { - set spec [$w_rev get_tracking_branch] if {$spec eq {}} { tk_messageBox \ -icon error \ @@ -171,6 +177,52 @@ method _create {} { return } + if {$spec ne {} && $opt_fetch} { + set l_trck [lindex $spec 0] + set remote [lindex $spec 1] + set r_head [lindex $spec 2] + regsub ^refs/heads/ $r_head {} r_head + + set c $w.fetch_trck + toplevel $c + wm title $c "Refreshing Tracking Branch" + wm geometry $c "+[winfo rootx $w]+[winfo rooty $w]" + + set e [::console::embed \ + $c.console \ + "Fetching $r_head from $remote"] + pack $c.console -fill both -expand 1 + $e exec \ + [list git fetch $remote +$r_head:$l_trck] \ + [cb _finish_fetch $newbranch $c $e] + + bind $c [list grab $c] + bind $c <$M1B-Key-w> break + bind $c <$M1B-Key-W> break + wm protocol $c WM_DELETE_WINDOW [cb _noop] + } else { + _finish_create $this $newbranch + } +} + +method _noop {} {} + +method _finish_fetch {newbranch c e ok} { + wm protocol $c WM_DELETE_WINDOW {} + + if {$ok} { + destroy $c + _finish_create $this $newbranch + } else { + $e done $ok + button $c.close -text Close -command [list destroy $c] + pack $c.close -side bottom -anchor e -padx 10 -pady 10 + } +} + +method _finish_create {newbranch} { + global null_sha1 all_heads + if {[catch {set new [$w_rev commit_or_die]}]} { return } diff --git a/lib/console.tcl b/lib/console.tcl index ce25d92cac..297e8defa4 100644 --- a/lib/console.tcl +++ b/lib/console.tcl @@ -7,6 +7,7 @@ field t_short field t_long field w field console_cr +field is_toplevel 1; # are we our own window? constructor new {short_title long_title} { set t_short $short_title @@ -15,10 +16,25 @@ constructor new {short_title long_title} { return $this } +constructor embed {path title} { + set t_short {} + set t_long $title + set w $path + set is_toplevel 0 + _init $this + return $this +} + method _init {} { global M1B - make_toplevel top w -autodelete 0 - wm title $top "[appname] ([reponame]): $t_short" + + if {$is_toplevel} { + make_toplevel top w -autodelete 0 + wm title $top "[appname] ([reponame]): $t_short" + } else { + frame $w + } + set console_cr 1.0 frame $w.m @@ -57,15 +73,17 @@ method _init {} { $w.m.t tag remove sel 0.0 end " - button $w.ok -text {Close} \ - -state disabled \ - -command "destroy $w" - pack $w.ok -side bottom -anchor e -pady 10 -padx 10 + if {$is_toplevel} { + button $w.ok -text {Close} \ + -state disabled \ + -command [list destroy $w] + pack $w.ok -side bottom -anchor e -pady 10 -padx 10 + bind $w [list focus $w] + } bind_button3 $w.m.t "tk_popup $w.ctxm %X %Y" bind $w.m.t <$M1B-Key-a> "$w.m.t tag add sel 0.0 end;break" bind $w.m.t <$M1B-Key-A> "$w.m.t tag add sel 0.0 end;break" - bind $w "focus $w" } method exec {cmd {after {}}} { @@ -159,16 +177,20 @@ method done {ok} { if {$ok} { if {[winfo exists $w.m.s]} { $w.m.s conf -background green -text {Success} - $w.ok conf -state normal - focus $w.ok + if {$is_toplevel} { + $w.ok conf -state normal + focus $w.ok + } } } else { if {![winfo exists $w.m.s]} { _init $this } $w.m.s conf -background red -text {Error: Command Failed} - $w.ok conf -state normal - focus $w.ok + if {$is_toplevel} { + $w.ok conf -state normal + focus $w.ok + } } delete_this } From 311e02a4a5c7b82c996214f06d58e2b51b3ecc22 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 5 Jul 2007 19:19:37 -0400 Subject: [PATCH 117/213] git-gui: Better handling of detached HEAD If the current branch is not a symbolic-ref that points to a name in the refs/heads/ namespace we now just assume that the head is a detached head. In this case we return the special branch name of HEAD rather than empty string, as HEAD is a valid revision specification and the empty string is not. I have also slightly improved the current-branch function by using string functions to parse the symbolic-ref data. This should be slightly faster than using a regsub. I think the code is clearer too. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 99df2d9480..516bd972ec 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -285,14 +285,24 @@ proc git {args} { } proc current-branch {} { - set ref {} set fd [open [gitdir HEAD] r] - if {[gets $fd ref] <16 - || ![regsub {^ref: refs/heads/} $ref {} ref]} { + if {[gets $fd ref] < 1} { set ref {} } close $fd - return $ref + + set pfx {ref: refs/heads/} + set len [string length $pfx] + if {[string equal -length $len $pfx $ref]} { + # We're on a branch. It might not exist. But + # HEAD looks good enough to be a branch. + # + return [string range $ref $len end] + } else { + # Assume this is a detached head. + # + return HEAD + } } auto_load tk_optionMenu From 699d5601f59938d62ec2506f319c25a656a403da Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 5 Jul 2007 23:16:13 -0400 Subject: [PATCH 118/213] git-gui: Refactor our ui_status_value update technique I'm really starting to dislike global variables. The ui_status_value global varible is just one of those that seems to appear in a lot of code and in many cases we didn't even declare it "global" within the proc that updates it so we haven't always been getting all of the updates we expected to see. This change introduces two new global procs: ui_status $msg; # Sets the status bar to show $msg. ui_ready; # Changes the status bar to show "Ready." The second (special) form is used because we often update the area with this message once we are done processing a block of work and want the user to know we have completed it. I'm not fixing the cases that appear in lib/branch.tcl right now as I'm actually in the middle of a huge refactoring of that code to support making a detached HEAD checkout. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 36 +++++++++++++++++++++--------------- lib/commit.tcl | 33 +++++++++++++++------------------ lib/diff.tcl | 18 +++++++++--------- lib/index.tcl | 30 +++++++++++++++--------------- lib/merge.tcl | 14 +++++++------- 5 files changed, 67 insertions(+), 64 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 516bd972ec..88ef64337a 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -527,7 +527,7 @@ proc PARENT {} { proc rescan {after {honor_trustmtime 1}} { global HEAD PARENT MERGE_HEAD commit_type - global ui_index ui_workdir ui_status_value ui_comm + global ui_index ui_workdir ui_comm global rescan_active file_states global repo_config @@ -566,7 +566,7 @@ proc rescan {after {honor_trustmtime 1}} { rescan_stage2 {} $after } else { set rescan_active 1 - set ui_status_value {Refreshing file status...} + ui_status {Refreshing file status...} set cmd [list git update-index] lappend cmd -q lappend cmd --unmerged @@ -580,7 +580,6 @@ proc rescan {after {honor_trustmtime 1}} { } proc rescan_stage2 {fd after} { - global ui_status_value global rescan_active buf_rdi buf_rdf buf_rlo if {$fd ne {}} { @@ -601,7 +600,7 @@ proc rescan_stage2 {fd after} { set buf_rlo {} set rescan_active 3 - set ui_status_value {Scanning for modified files ...} + ui_status {Scanning for modified files ...} set fd_di [open "| git diff-index --cached -z [PARENT]" r] set fd_df [open "| git diff-files -z" r] set fd_lo [open $ls_others r] @@ -761,6 +760,16 @@ proc mapdesc {state path} { return $r } +proc ui_status {msg} { + set ::ui_status_value $msg +} + +proc ui_ready {{test {}}} { + if {$test eq {} || $::ui_status_value eq $test} { + ui_status Ready. + } +} + proc escape_path {path} { regsub -all {\\} $path "\\\\" path regsub -all "\n" $path "\\n" path @@ -1112,7 +1121,7 @@ proc incr_font_size {font {amt 1}} { set starting_gitk_msg {Starting gitk... please wait...} proc do_gitk {revs} { - global env ui_status_value starting_gitk_msg + global env starting_gitk_msg # -- Always start gitk through whatever we were loaded with. This # lets us bypass using shell process on Windows systems. @@ -1129,11 +1138,9 @@ proc do_gitk {revs} { error_popup "Unable to start gitk:\n\n$exe does not exist" } else { eval exec $cmd & - set ui_status_value $starting_gitk_msg + ui_status $starting_gitk_msg after 10000 { - if {$ui_status_value eq $starting_gitk_msg} { - set ui_status_value {Ready.} - } + ui_ready $starting_gitk_msg } } } @@ -1182,7 +1189,7 @@ proc do_quit {} { } proc do_rescan {} { - rescan {set ui_status_value {Ready.}} + rescan ui_ready } proc do_commit {} { @@ -1217,12 +1224,12 @@ proc toggle_or_diff {w x y} { update_indexinfo \ "Unstaging [short_path $path] from commit" \ [list $path] \ - [concat $after {set ui_status_value {Ready.}}] + [concat $after [list ui_ready]] } elseif {$w eq $ui_workdir} { update_index \ "Adding [short_path $path]" \ [list $path] \ - [concat $after {set ui_status_value {Ready.}}] + [concat $after [list ui_ready]] } } else { show_diff $path $w $lno @@ -1640,20 +1647,19 @@ if {[is_MacOSX]} { # if {[is_Cygwin] && [file exists /usr/local/miga/lib/gui-miga]} { proc do_miga {} { - global ui_status_value if {![lock_index update]} return set cmd [list sh --login -c "/usr/local/miga/lib/gui-miga \"[pwd]\""] set miga_fd [open "|$cmd" r] fconfigure $miga_fd -blocking 0 fileevent $miga_fd readable [list miga_done $miga_fd] - set ui_status_value {Running miga...} + ui_status {Running miga...} } proc miga_done {fd} { read $fd 512 if {[eof $fd]} { close $fd unlock_index - rescan [list set ui_status_value {Ready.}] + rescan ui_ready } } .mbar add cascade -label Tools -menu .mbar.tools diff --git a/lib/commit.tcl b/lib/commit.tcl index 0de2a28fa5..c5f608beb0 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -58,7 +58,7 @@ You are currently in the middle of a merge that has not been fully completed. Y $ui_comm insert end $msg $ui_comm edit reset $ui_comm edit modified false - rescan {set ui_status_value {Ready.}} + rescan ui_ready } set GIT_COMMITTER_IDENT {} @@ -108,12 +108,12 @@ proc create_new_commit {} { $ui_comm delete 0.0 end $ui_comm edit reset $ui_comm edit modified false - rescan {set ui_status_value {Ready.}} + rescan ui_ready } proc commit_tree {} { global HEAD commit_type file_states ui_comm repo_config - global ui_status_value pch_error + global pch_error if {[committer_ident] eq {}} return if {![lock_index update]} return @@ -132,7 +132,7 @@ Another Git program has modified this repository since the last scan. A rescan The rescan will be automatically started now. } unlock_index - rescan {set ui_status_value {Ready.}} + rescan ui_ready return } @@ -206,7 +206,7 @@ A good commit message has the following format: return } - set ui_status_value {Calling pre-commit hook...} + ui_status {Calling pre-commit hook...} set pch_error {} set fd_ph [open "| $pchook" r] fconfigure $fd_ph -blocking 0 -translation binary @@ -215,13 +215,13 @@ A good commit message has the following format: } proc commit_prehook_wait {fd_ph curHEAD msg} { - global pch_error ui_status_value + global pch_error append pch_error [read $fd_ph] fconfigure $fd_ph -blocking 1 if {[eof $fd_ph]} { if {[catch {close $fd_ph}]} { - set ui_status_value {Commit declined by pre-commit hook.} + ui_status {Commit declined by pre-commit hook.} hook_failed_popup pre-commit $pch_error unlock_index } else { @@ -234,9 +234,7 @@ proc commit_prehook_wait {fd_ph curHEAD msg} { } proc commit_writetree {curHEAD msg} { - global ui_status_value - - set ui_status_value {Committing changes...} + ui_status {Committing changes...} set fd_wt [open "| git write-tree" r] fileevent $fd_wt readable \ [list commit_committree $fd_wt $curHEAD $msg] @@ -244,15 +242,15 @@ proc commit_writetree {curHEAD msg} { proc commit_committree {fd_wt curHEAD msg} { global HEAD PARENT MERGE_HEAD commit_type - global all_heads current_branch - global ui_status_value ui_comm selected_commit_type + global current_branch + global ui_comm selected_commit_type global file_states selected_paths rescan_active global repo_config gets $fd_wt tree_id if {$tree_id eq {} || [catch {close $fd_wt} err]} { error_popup "write-tree failed:\n\n$err" - set ui_status_value {Commit failed.} + ui_status {Commit failed.} unlock_index return } @@ -269,7 +267,7 @@ No files were modified by this commit and it was not a merge commit. A rescan will be automatically started now. } unlock_index - rescan {set ui_status_value {No changes to commit.}} + rescan {ui_status {No changes to commit.}} return } } @@ -294,7 +292,7 @@ A rescan will be automatically started now. lappend cmd <$msg_p if {[catch {set cmt_id [eval git $cmd]} err]} { error_popup "commit-tree failed:\n\n$err" - set ui_status_value {Commit failed.} + ui_status {Commit failed.} unlock_index return } @@ -316,7 +314,7 @@ A rescan will be automatically started now. git update-ref -m $reflogm HEAD $cmt_id $curHEAD } err]} { error_popup "update-ref failed:\n\n$err" - set ui_status_value {Commit failed.} + ui_status {Commit failed.} unlock_index return } @@ -410,6 +408,5 @@ A rescan will be automatically started now. display_all_files unlock_index reshow_diff - set ui_status_value \ - "Created commit [string range $cmt_id 0 7]: $subject" + ui_status "Created commit [string range $cmt_id 0 7]: $subject" } diff --git a/lib/diff.tcl b/lib/diff.tcl index 29436b50cb..05bf75179b 100644 --- a/lib/diff.tcl +++ b/lib/diff.tcl @@ -17,7 +17,7 @@ proc clear_diff {} { } proc reshow_diff {} { - global ui_status_value file_states file_lists + global file_states file_lists global current_diff_path current_diff_side set p $current_diff_path @@ -49,13 +49,13 @@ A rescan will be automatically started to find other files which may have the sa clear_diff display_file $path __ - rescan {set ui_status_value {Ready.}} 0 + rescan ui_ready 0 } proc show_diff {path w {lno {}}} { global file_states file_lists global is_3way_diff diff_active repo_config - global ui_diff ui_status_value ui_index ui_workdir + global ui_diff ui_index ui_workdir global current_diff_path current_diff_side current_diff_header if {$diff_active || ![lock_index read]} return @@ -78,7 +78,7 @@ proc show_diff {path w {lno {}}} { set current_diff_path $path set current_diff_side $w set current_diff_header {} - set ui_status_value "Loading diff of [escape_path $path]..." + ui_status "Loading diff of [escape_path $path]..." # - Git won't give us the diff, there's nothing to compare to! # @@ -92,7 +92,7 @@ proc show_diff {path w {lno {}}} { } err ]} { set diff_active 0 unlock_index - set ui_status_value "Unable to display [escape_path $path]" + ui_status "Unable to display [escape_path $path]" error_popup "Error loading file:\n\n$err" return } @@ -127,7 +127,7 @@ proc show_diff {path w {lno {}}} { $ui_diff conf -state disabled set diff_active 0 unlock_index - set ui_status_value {Ready.} + ui_ready return } @@ -157,7 +157,7 @@ proc show_diff {path w {lno {}}} { if {[catch {set fd [open $cmd r]} err]} { set diff_active 0 unlock_index - set ui_status_value "Unable to display [escape_path $path]" + ui_status "Unable to display [escape_path $path]" error_popup "Error loading diff:\n\n$err" return } @@ -170,7 +170,7 @@ proc show_diff {path w {lno {}}} { } proc read_diff {fd} { - global ui_diff ui_status_value diff_active + global ui_diff diff_active global is_3way_diff current_diff_header $ui_diff conf -state normal @@ -256,7 +256,7 @@ proc read_diff {fd} { close $fd set diff_active 0 unlock_index - set ui_status_value {Ready.} + ui_ready if {[$ui_diff index end] eq {2.0}} { handle_empty_diff diff --git a/lib/index.tcl b/lib/index.tcl index 42742850ee..7c175a96a6 100644 --- a/lib/index.tcl +++ b/lib/index.tcl @@ -2,7 +2,7 @@ # Copyright (C) 2006, 2007 Shawn Pearce proc update_indexinfo {msg pathList after} { - global update_index_cp ui_status_value + global update_index_cp if {![lock_index update]} return @@ -12,7 +12,7 @@ proc update_indexinfo {msg pathList after} { set batch [expr {int($totalCnt * .01) + 1}] if {$batch > 25} {set batch 25} - set ui_status_value [format \ + ui_status [format \ "$msg... %i/%i files (%.2f%%)" \ $update_index_cp \ $totalCnt \ @@ -36,7 +36,7 @@ proc update_indexinfo {msg pathList after} { } proc write_update_indexinfo {fd pathList totalCnt batch msg after} { - global update_index_cp ui_status_value + global update_index_cp global file_states current_diff_path if {$update_index_cp >= $totalCnt} { @@ -67,7 +67,7 @@ proc write_update_indexinfo {fd pathList totalCnt batch msg after} { display_file $path $new } - set ui_status_value [format \ + ui_status [format \ "$msg... %i/%i files (%.2f%%)" \ $update_index_cp \ $totalCnt \ @@ -75,7 +75,7 @@ proc write_update_indexinfo {fd pathList totalCnt batch msg after} { } proc update_index {msg pathList after} { - global update_index_cp ui_status_value + global update_index_cp if {![lock_index update]} return @@ -85,7 +85,7 @@ proc update_index {msg pathList after} { set batch [expr {int($totalCnt * .01) + 1}] if {$batch > 25} {set batch 25} - set ui_status_value [format \ + ui_status [format \ "$msg... %i/%i files (%.2f%%)" \ $update_index_cp \ $totalCnt \ @@ -109,7 +109,7 @@ proc update_index {msg pathList after} { } proc write_update_index {fd pathList totalCnt batch msg after} { - global update_index_cp ui_status_value + global update_index_cp global file_states current_diff_path if {$update_index_cp >= $totalCnt} { @@ -144,7 +144,7 @@ proc write_update_index {fd pathList totalCnt batch msg after} { display_file $path $new } - set ui_status_value [format \ + ui_status [format \ "$msg... %i/%i files (%.2f%%)" \ $update_index_cp \ $totalCnt \ @@ -152,7 +152,7 @@ proc write_update_index {fd pathList totalCnt batch msg after} { } proc checkout_index {msg pathList after} { - global update_index_cp ui_status_value + global update_index_cp if {![lock_index update]} return @@ -162,7 +162,7 @@ proc checkout_index {msg pathList after} { set batch [expr {int($totalCnt * .01) + 1}] if {$batch > 25} {set batch 25} - set ui_status_value [format \ + ui_status [format \ "$msg... %i/%i files (%.2f%%)" \ $update_index_cp \ $totalCnt \ @@ -192,7 +192,7 @@ proc checkout_index {msg pathList after} { } proc write_checkout_index {fd pathList totalCnt batch msg after} { - global update_index_cp ui_status_value + global update_index_cp global file_states current_diff_path if {$update_index_cp >= $totalCnt} { @@ -217,7 +217,7 @@ proc write_checkout_index {fd pathList totalCnt batch msg after} { } } - set ui_status_value [format \ + ui_status [format \ "$msg... %i/%i files (%.2f%%)" \ $update_index_cp \ $totalCnt \ @@ -249,7 +249,7 @@ proc unstage_helper {txt paths} { update_indexinfo \ $txt \ $pathList \ - [concat $after {set ui_status_value {Ready.}}] + [concat $after [list ui_ready]] } } @@ -293,7 +293,7 @@ proc add_helper {txt paths} { update_index \ $txt \ $pathList \ - [concat $after {set ui_status_value {Ready to commit.}}] + [concat $after {ui_status {Ready to commit.}}] } } @@ -370,7 +370,7 @@ Any unadded changes will be permanently lost by the revert." \ checkout_index \ $txt \ $pathList \ - [concat $after {set ui_status_value {Ready.}}] + [concat $after [list ui_ready]] } else { unlock_index } diff --git a/lib/merge.tcl b/lib/merge.tcl index 889182f545..f0a02ea228 100644 --- a/lib/merge.tcl +++ b/lib/merge.tcl @@ -28,7 +28,7 @@ Another Git program has modified this repository since the last scan. A rescan The rescan will be automatically started now. } unlock_index - rescan {set ui_status_value {Ready.}} + rescan ui_ready return 0 } @@ -79,7 +79,7 @@ proc _visualize {w list} { } proc _start {w list} { - global HEAD ui_status_value current_branch + global HEAD current_branch set cmd [list git merge] set names [_refs $w $list] @@ -121,7 +121,7 @@ Please select fewer branches. To merge more than 15 branches, merge the branche } set msg "Merging $current_branch, [join $names {, }]" - set ui_status_value "$msg..." + ui_status "$msg..." set cons [console::new "Merge" $msg] console::exec $cons $cmd \ [namespace code [list _finish $revcnt $cons]] @@ -150,14 +150,14 @@ You can attempt this merge again by merging only one branch at a time." $w fconfigure $fd -blocking 0 -translation binary fileevent $fd readable \ [namespace code [list _reset_wait $fd]] - set ui_status_value {Aborting... please wait...} + ui_status {Aborting... please wait...} return } set msg {Merge failed. Conflict resolution is required.} } unlock_index - rescan [list set ui_status_value $msg] + rescan [list ui_status $msg] } proc dialog {} { @@ -285,7 +285,7 @@ Continue with aborting the current $op?"] eq {yes}} { set fd [open "| git read-tree --reset -u HEAD" r] fconfigure $fd -blocking 0 -translation binary fileevent $fd readable [namespace code [list _reset_wait $fd]] - set ui_status_value {Aborting... please wait...} + ui_status {Aborting... please wait...} } else { unlock_index } @@ -308,7 +308,7 @@ proc _reset_wait {fd} { catch {file delete [gitdir MERGE_MSG]} catch {file delete [gitdir GITGUI_MSG]} - rescan {set ui_status_value {Abort completed. Ready.}} + rescan {ui_status {Abort completed. Ready.}} } } From b24f56d60491416a1c5a8fc71863bbaa0f390f23 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 8 Jul 2007 01:28:18 -0700 Subject: [PATCH 119/213] git-stash: try reusing cached stat info as much as possible Earlier when we read a tree into a temporary index, we read it from scratch. Start from the current index and use read-tree -m to preserve cached stat information as much as possible, in order to speed up "git add -u". This makes "git stash" usable in a source tree of nontrivial size. Signed-off-by: Junio C Hamano --- git-stash.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/git-stash.sh b/git-stash.sh index eac5551380..de13dd1812 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -58,11 +58,11 @@ save_stash () { # state of the working tree w_tree=$( ( + rm -f "$TMP-index" && + cp -p ${GIT_INDEX_FILE-"$GIT_DIR/index"} "$TMP-index" && GIT_INDEX_FILE="$TMP-index" && export GIT_INDEX_FILE && - - rm -f "$TMP-index" && - git read-tree $i_tree && + git read-tree -m $i_tree && git add -u && git write-tree && rm -f "$TMP-index" From 4017761fd89060f2b57d7799f6bbda8b3568d3d4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 8 Jul 2007 13:41:21 +0100 Subject: [PATCH 120/213] branch.autosetupmerge: allow boolean values, or "all" Junio noticed that switching on autosetupmerge unilaterally started cluttering the config for local branches. That is not the original intention of branch.autosetupmerge, which was meant purely for convenience when branching off of remote branches, but that semantics got lost somewhere. If you still want that "new" behavior, you can switch branch.autosetupmerge to the value "all". Otherwise, it is interpreted as a boolean, which triggers setting up defaults _only_ when branching off of a remote branch, i.e. the originally intended behavior. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/config.txt | 5 ++++- Documentation/git-checkout.txt | 5 +++-- builtin-branch.c | 18 ++++++++++++------ t/t3200-branch.sh | 9 +++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 4b67f0adf7..aeece848a5 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -309,7 +309,10 @@ branch.autosetupmerge:: so that gitlink:git-pull[1] will appropriately merge from that remote branch. Note that even if this option is not set, this behavior can be chosen per-branch using the `--track` - and `--no-track` options. This option defaults to false. + and `--no-track` options. This option can have values + 'false' (never touch the configuration), 'all' (do this + for all branches), or 'true' (do this only when + branching from a remote tracking branch), and defaults to 'true'. branch..remote:: When in branch , it tells `git fetch` which remote to fetch. diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 818b720b91..82929523c7 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -52,8 +52,9 @@ OPTIONS set up configuration so that git-pull will automatically retrieve data from the remote branch. Set the branch.autosetupmerge configuration variable to true if you - want git-checkout and git-branch to always behave as if - '--track' were given. + want git-checkout and git-branch to behave as if + '--track' were given when you branch from a remote + tracking branch. --no-track:: When -b is given and a branch is created off a remote branch, diff --git a/builtin-branch.c b/builtin-branch.c index 84a8ad7b73..423c30194c 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -22,7 +22,7 @@ static const char builtin_branch_usage[] = static const char *head; static unsigned char head_sha1[20]; -static int branch_track_remotes = 1; +static int branch_track = 1; /* 0 = none, 1 = remotes, 2 = all */ static int branch_use_color; static char branch_colors[][COLOR_MAXLEN] = { @@ -66,8 +66,12 @@ static int git_branch_config(const char *var, const char *value) color_parse(value, var, branch_colors[slot]); return 0; } - if (!strcmp(var, "branch.autosetupmerge")) - branch_track_remotes = git_config_bool(var, value); + if (!strcmp(var, "branch.autosetupmerge")) { + if (!strcmp(value, "all")) + branch_track = 2; + else + branch_track = git_config_bool(var, value); + } return git_default_config(var, value); } @@ -504,7 +508,9 @@ static void create_branch(const char *name, const char *start_name, /* When branching off a remote branch, set up so that git-pull automatically merges from there. So far, this is only done for remotes registered via .git/config. */ - if (real_ref && track) + if (real_ref && (track == 2 || + (track == 1 && + !prefixcmp(real_ref, "refs/remotes/")))) set_branch_defaults(name, real_ref); if (write_ref_sha1(lock, sha1, msg) < 0) @@ -564,7 +570,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) int i; git_config(git_branch_config); - track = branch_track_remotes; + track = branch_track; for (i = 1; i < argc; i++) { const char *arg = argv[i]; @@ -576,7 +582,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) break; } if (!strcmp(arg, "--track")) { - track = 1; + track = 2; continue; } if (!strcmp(arg, "--no-track")) { diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index c6f472ac04..a19e961cb3 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -148,6 +148,15 @@ test_expect_success 'test tracking setup via config' \ test $(git config branch.my3.remote) = local && test $(git config branch.my3.merge) = refs/heads/master' +test_expect_success 'autosetupmerge = all' ' + git config branch.autosetupmerge true && + git branch all1 master && + test -z "$(git config branch.all1.merge)" && + git config branch.autosetupmerge all && + git branch all2 master && + test $(git config branch.all2.merge) = refs/heads/master +' + test_expect_success 'test overriding tracking setup via --no-track' \ 'git config branch.autosetupmerge true && git config remote.local.url . && From a7342913e21a96597f38ce0b48e3093c9739df1f Mon Sep 17 00:00:00 2001 From: Gerrit Pape Date: Fri, 6 Jul 2007 14:42:27 +0000 Subject: [PATCH 121/213] git-commit: don't add multiple Signed-off-by: from the same identity If requested to signoff a commit, don't add another Signed-off-by: line to the commit message if the exact same line is already there. This was noticed and requested by Josh Triplett through http://bugs.debian.org/430851 Signed-off-by: Gerrit Pape Signed-off-by: Junio C Hamano --- git-commit.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/git-commit.sh b/git-commit.sh index 9106a743cc..f3cd8ee978 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -458,16 +458,18 @@ fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG case "$signoff" in t) - need_blank_before_signoff= + sign=$(git-var GIT_COMMITTER_IDENT | sed -e ' + s/>.*/>/ + s/^/Signed-off-by: / + ') + blank_before_signoff= tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG | - grep 'Signed-off-by:' >/dev/null || need_blank_before_signoff=yes - { - test -z "$need_blank_before_signoff" || echo - git-var GIT_COMMITTER_IDENT | sed -e ' - s/>.*/>/ - s/^/Signed-off-by: / - ' - } >>"$GIT_DIR"/COMMIT_EDITMSG + grep 'Signed-off-by:' >/dev/null || blank_before_signoff=' +' + tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG | + grep "$sign"$ >/dev/null || + printf '%s%s\n' "$blank_before_signoff" "$sign" \ + >>"$GIT_DIR"/COMMIT_EDITMSG ;; esac From 561b0fbb4a2d336faeb929380bddd6ec420d7b11 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 8 Jul 2007 14:42:05 -0700 Subject: [PATCH 122/213] Fix merge-one-file for our-side-added/our-side-removed cases When commit ed93b449 changed the script so that it does not touch untracked working tree file, we forgot that we still needed to resolve the index entry (otherwise they are left unmerged). Signed-off-by: Junio C Hamano --- git-merge-one-file.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh index ebbb575965..1e7727d276 100755 --- a/git-merge-one-file.sh +++ b/git-merge-one-file.sh @@ -27,8 +27,9 @@ case "${1:-.}${2:-.}${3:-.}" in # read-tree checked that index matches HEAD already, # so we know we do not have this path tracked. # there may be an unrelated working tree file here, - # which we should just leave unmolested. - exit 0 + # which we should just leave unmolested. Make sure + # we do not have it in the index, though. + exec git update-index --remove -- "$4" fi if test -f "$4"; then rm -f -- "$4" && @@ -42,7 +43,8 @@ case "${1:-.}${2:-.}${3:-.}" in # ".$2.") # the other side did not add and we added so there is nothing - # to be done. + # to be done, except making the path merged. + exec git update-index --add --cacheinfo "$6" "$2" "$4" ;; "..$3") echo "Adding $4" @@ -50,7 +52,7 @@ case "${1:-.}${2:-.}${3:-.}" in echo "ERROR: untracked $4 is overwritten by the merge." exit 1 } - git update-index --add --cacheinfo "$6$7" "$2$3" "$4" && + git update-index --add --cacheinfo "$7" "$3" "$4" && exec git checkout-index -u -f -- "$4" ;; From 797e99a27848a0f6da1f3c85cb3714652fde23ba Mon Sep 17 00:00:00 2001 From: Carlos Rica Date: Sun, 8 Jul 2007 21:36:34 +0200 Subject: [PATCH 123/213] t7004: Skip tests for signed tags in an old version of gpg. As said here: http://www.gnupg.org/documentation/faqs.html#q6.19 the gpg version 1.0.6 didn't parse trust packets correctly, so for that version, creation of signed tags using the generated key fails. Signed-off-by: Carlos Rica Acked-by: Sven Verdoolaege Signed-off-by: Junio C Hamano --- t/t7004-tag.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index a845930404..b785080f9f 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -460,6 +460,17 @@ if [ $? -eq 127 ]; then exit fi +# As said here: http://www.gnupg.org/documentation/faqs.html#q6.19 +# the gpg version 1.0.6 didn't parse trust packets correctly, so for +# that version, creation of signed tags using the generated key fails. +case "$(gpg --version)" in +'gpg (GnuPG) 1.0.6'*) + echo "Skipping signed tag tests, because a bug in 1.0.6 version" + test_done + exit + ;; +esac + # key generation info: gpg --homedir t/t7004 --gen-key # Type DSA and Elgamal, size 2048 bits, no expiration date. # Name and email: C O Mitter From 18640d991bde7e081fb851cea5114c09472b188f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 8 Jul 2007 03:01:29 +0100 Subject: [PATCH 124/213] rebase -i: handle --continue more like non-interactive rebase Non-interactive rebase requires the working tree to be clean, but applies what is in the index without requiring the user to do it herself. Imitate that, but (since we are interactive, after all) fire up an editor with the commit message. It also fixes a subtle bug: a forgotten "continue" was removed, which led to an infinite loop when continuing without remaining patches. Both issues noticed by Frank Lichtenheld. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 26 +++++++++++++++++--------- t/t3404-rebase-interactive.sh | 16 +++++++++++++++- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 0c2a9697c4..705178f7e9 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -59,6 +59,10 @@ make_patch () { } die_with_patch () { + test -f "$DOTEST"/message || + git cat-file commit $sha1 | sed "1,/^$/d" > "$DOTEST"/message + test -f "$DOTEST"/author-script || + get_author_ident_from_commit $sha1 > "$DOTEST"/author-script make_patch "$1" die "$2" } @@ -140,10 +144,7 @@ pick_one_preserving_merges () { if ! git merge $STRATEGY -m "$msg" $new_parents then echo "$msg" > "$GIT_DIR"/MERGE_MSG - warn Error redoing merge $sha1 - warn - warn After fixup, please use - die "$author_script git commit" + die Error redoing merge $sha1 fi ;; *) @@ -154,11 +155,12 @@ pick_one_preserving_merges () { } do_next () { + test -f "$DOTEST"/message && rm "$DOTEST"/message + test -f "$DOTEST"/author-script && rm "$DOTEST"/author-script read command sha1 rest < "$TODO" case "$command" in \#|'') mark_action_done - continue ;; pick) comment_for_reflog pick @@ -201,6 +203,7 @@ do_next () { git cat-file commit $sha1 | sed -e '1,/^$/d' >> "$MSG" git reset --soft HEAD^ author_script=$(get_author_ident_from_commit $sha1) + echo "$author_script" > "$DOTEST"/author-script case $failed in f) # This is like --amend, but with a different message @@ -212,10 +215,6 @@ do_next () { cp "$MSG" "$GIT_DIR"/MERGE_MSG warn warn "Could not apply $sha1... $rest" - warn "After you fixed that, commit the result with" - warn - warn " $(echo $author_script | tr '\012' ' ') \\" - warn " git commit -F \"$GIT_DIR\"/MERGE_MSG -e" die_with_patch $sha1 "" esac ;; @@ -265,6 +264,15 @@ do test -d "$DOTEST" || die "No interactive rebase running" + # commit if necessary + git rev-parse --verify HEAD > /dev/null && + git update-index --refresh && + git diff-files --quiet && + ! git diff-index --cached --quiet HEAD && + . "$DOTEST"/author-script && + export GIT_AUTHOR_NAME GIT_AUTHOR_NAME GIT_AUTHOR_DATE && + git commit -F "$DOTEST"/message -e + require_clean_work_tree do_rest ;; diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 883cf29595..c25133699a 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -63,7 +63,10 @@ test_expect_success 'setup' ' cat > fake-editor.sh << EOF #!/bin/sh -test "\$1" = .git/COMMIT_EDITMSG && exit +test "\$1" = .git/COMMIT_EDITMSG && { + test -z "\$FAKE_COMMIT_MESSAGE" || echo "\$FAKE_COMMIT_MESSAGE" > "\$1" + exit +} test -z "\$FAKE_LINES" && exit grep -v "^#" < "\$1" > "\$1".tmp rm "\$1" @@ -181,6 +184,7 @@ test_expect_success 'preserve merges with -p' ' echo C > file1 && test_tick && git commit -m K file1 && + test_tick && git rebase -i -p --onto branch1 master && test $(git rev-parse HEAD^^2) = $(git rev-parse to-be-preserved) && test $(git rev-parse HEAD~3) = $(git rev-parse branch1) && @@ -188,4 +192,14 @@ test_expect_success 'preserve merges with -p' ' test $(git show HEAD~2:file1) = B ' +test_expect_success '--continue tries to commit' ' + test_tick && + ! git rebase -i --onto new-branch1 HEAD^ && + echo resolved > file1 && + git add file1 && + FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue && + test $(git rev-parse HEAD^) = $(git rev-parse new-branch1) && + git show HEAD | grep chouette +' + test_done From 3df0a859aa5cc68a2bd616cb686f01cf0e2468c1 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 8 Jul 2007 03:02:13 +0100 Subject: [PATCH 125/213] rebase -i: actually show the diffstat when being verbose The "while" loop in the function do_rest is not supposed to ever be exited. Instead, the function do_one checks if there is nothing left, and cleans up and exits if that is the case. So the diffstat code belongs there. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 705178f7e9..1a064af381 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -239,7 +239,10 @@ do_next () { fi && message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" && git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD && - git symbolic-ref HEAD $HEADNAME && + git symbolic-ref HEAD $HEADNAME && { + test ! -f "$DOTEST"/verbose || + git diff --stat $(cat "$DOTEST"/head)..HEAD + } && rm -rf "$DOTEST" && warn "Successfully rebased and updated $HEADNAME." @@ -251,9 +254,6 @@ do_rest () { do do_next done - test -f "$DOTEST"/verbose && - git diff --stat $(cat "$DOTEST"/head)..HEAD - exit } while case $# in 0) break ;; esac From 8e4a91bd780b89c7337f281a8601f2e0cae108fc Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 8 Jul 2007 03:02:47 +0100 Subject: [PATCH 126/213] rebase -i: remember the settings of -v, -s and -p when interrupted After interruption, be that an edit, or a conflicting commit, reset the variables VERBOSE, STRATEGY and PRESERVE_MERGES, so that the user does not have to respecify them with "rebase --continue". Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 4 ++++ t/t3404-rebase-interactive.sh | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 1a064af381..ac4d559f07 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -23,6 +23,9 @@ REWRITTEN="$DOTEST"/rewritten PRESERVE_MERGES= STRATEGY= VERBOSE= +test -d "$REWRITTEN" && PRESERVE_MERGES=t +test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)" +test -f "$DOTEST"/verbose && VERBOSE=t warn () { echo "$*" >&2 @@ -366,6 +369,7 @@ do echo $HEAD > "$DOTEST"/head echo $UPSTREAM > "$DOTEST"/upstream echo $ONTO > "$DOTEST"/onto + test -z "$STRATEGY" || echo "$STRATEGY" > "$DOTEST"/strategy test t = "$VERBOSE" && : > "$DOTEST"/verbose if [ t = "$PRESERVE_MERGES" ] then diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index c25133699a..43a6675caa 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -202,4 +202,14 @@ test_expect_success '--continue tries to commit' ' git show HEAD | grep chouette ' +test_expect_success 'verbose flag is heeded, even after --continue' ' + git reset --hard HEAD@{1} && + test_tick && + ! git rebase -v -i --onto new-branch1 HEAD^ && + echo resolved > file1 && + git add file1 && + git rebase --continue > output && + grep "^ file1 | 2 +-$" output +' + test_done From 82576ddb70d0a2ed88fa3fee2f4ad05ab5b77401 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 8 Jul 2007 21:32:22 +0100 Subject: [PATCH 127/213] rebase -i: put a nice warning into the todo list It seems that not everybody expects a difference between keeping a "pick" line, and deleting it. So be a bit more explicit about that, with all capitals to get the attention. Noticed by vmiklos on IRC. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index ac4d559f07..d9563ec46f 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -401,6 +401,9 @@ do # pick = use commit # edit = use commit, but stop for amending # squash = use commit, but meld into previous commit +# +# If you remove a line here THAT COMMIT WILL BE LOST. +# EOF git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \ --abbrev=7 --reverse $UPSTREAM..$HEAD | \ From ae7aa49914072b9007ba62245e68b8bbd24f964a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 8 Jul 2007 17:15:09 -0700 Subject: [PATCH 128/213] Document custom hunk header selection Since the external interface seems to have stabilized for this new feature, let's document it properly. Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/gitattributes.txt | 55 ++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index d3ac9c7181..810df07217 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -72,8 +72,8 @@ EFFECTS ------- Certain operations by git can be influenced by assigning -particular attributes to a path. Currently, three operations -are attributes-aware. +particular attributes to a path. Currently, the following +operations are attributes-aware. Checking-out and checking-in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -199,7 +199,9 @@ Generating diff text ~~~~~~~~~~~~~~~~~~~~ The attribute `diff` affects if `git diff` generates textual -patch for the path or just says `Binary files differ`. +patch for the path or just says `Binary files differ`. It also +can affect what line is shown on the hunk header `@@ -k,l +n,m @@` +line. Set:: @@ -224,7 +226,8 @@ String:: Diff is shown using the specified custom diff driver. The driver program is given its input using the same calling convention as used for GIT_EXTERNAL_DIFF - program. + program. This name is also used for custom hunk header + selection. Defining a custom diff driver @@ -249,6 +252,50 @@ parameters, just like `GIT_EXTERNAL_DIFF` program is called. See gitlink:git[7] for details. +Defining a custom hunk-header +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Each group of changes (called "hunk") in the textual diff output +is prefixed with a line of the form: + + @@ -k,l +n,m @@ TEXT + +The text is called 'hunk header', and by default a line that +begins with an alphabet, an underscore or a dollar sign is used, +which matches what GNU `diff -p` output uses. This default +selection however is not suited for some contents, and you can +use customized pattern to make a selection. + +First in .gitattributes, you would assign the `diff` attribute +for paths. + +------------------------ +*.tex diff=tex +------------------------ + +Then, you would define "diff.tex.funcname" configuration to +specify a regular expression that matches a line that you would +want to appear as the hunk header, like this: + +------------------------ +[diff "tex"] + funcname = "^\\(\\\\\\(sub\\)*section{.*\\)$" +------------------------ + +Note. A single level of backslashes are eaten by the +configuration file parser, so you would need to double the +backslashes; the pattern above picks a line that begins with a +backslash, and zero or more occurences of `sub` followed by +`section` followed by open brace, to the end of line. + +There are a few built-in patterns to make this easier, and `tex` +is one of them, so you do not have to write the above in your +configuration file (you still need to enable this with the +attribute mechanism, via `.gitattributes`). Another built-in +pattern is defined for `java` that defines a pattern suitable +for program text in Java language. + + Performing a three-way merge ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From d41b43eb4c73044d0fff2057211fc78e4e7b2094 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 18:40:56 -0400 Subject: [PATCH 129/213] git-gui: Refactor branch switch to support detached head This is a major rewrite of the way we perform switching between branches and the subsequent update of the working directory. Like core Git we now use a single code path to perform all changes: our new checkout_op class. We also use it for branch creation/update as it integrates the tracking branch fetch process along with a very basic merge (fast-forward and reset only currently). Because some users have literally hundreds of local branches we use the standard revision picker (with its branch filtering tool) to select the local branch, rather than keeping all of the local branches in the Branch menu. The branch menu listing out all of the available branches is simply not sane for those types of huge repositories. Users can now checkout a detached head by ticking off the option in the checkout dialog. This option is off by default for the obvious reason, but it can be easily enabled for any local branch by simply checking it. We also detach the head if any non local branch was selected, or if a revision expression was entered. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 32 ++- lib/branch.tcl | 169 +----------- lib/branch_checkout.tcl | 88 +++++++ lib/branch_create.tcl | 249 ++---------------- lib/branch_delete.tcl | 13 +- lib/branch_rename.tcl | 14 +- lib/checkout_op.tcl | 569 ++++++++++++++++++++++++++++++++++++++++ lib/choose_rev.tcl | 43 ++- lib/commit.tcl | 8 - lib/console.tcl | 8 + lib/transport.tcl | 4 +- 11 files changed, 747 insertions(+), 450 deletions(-) create mode 100644 lib/branch_checkout.tcl create mode 100644 lib/checkout_op.tcl diff --git a/git-gui.sh b/git-gui.sh index 88ef64337a..ac043677c8 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -284,7 +284,9 @@ proc git {args} { return [eval exec git $args] } -proc current-branch {} { +proc load_current_branch {} { + global current_branch is_detached + set fd [open [gitdir HEAD] r] if {[gets $fd ref] < 1} { set ref {} @@ -297,11 +299,13 @@ proc current-branch {} { # We're on a branch. It might not exist. But # HEAD looks good enough to be a branch. # - return [string range $ref $len end] + set current_branch [string range $ref $len end] + set is_detached 0 } else { # Assume this is a detached head. # - return HEAD + set current_branch HEAD + set is_detached 1 } } @@ -442,6 +446,7 @@ set MERGE_HEAD [list] set commit_type {} set empty_tree {} set current_branch {} +set is_detached 0 set current_diff_path {} set selected_commit_type new @@ -491,7 +496,7 @@ proc repository_state {ctvar hdvar mhvar} { set mh [list] - set current_branch [current-branch] + load_current_branch if {[catch {set hd [git rev-parse --verify HEAD]}]} { set hd {} set ct initial @@ -557,11 +562,6 @@ proc rescan {after {honor_trustmtime 1}} { $ui_comm edit modified false } - if {[is_enabled branch]} { - load_all_heads - populate_branch_menu - } - if {$honor_trustmtime && $repo_config(gui.trustmtime) eq {true}} { rescan_stage2 {} $after } else { @@ -1519,6 +1519,12 @@ if {[is_enabled branch]} { lappend disable_on_lock [list .mbar.branch entryconf \ [.mbar.branch index last] -state] + .mbar.branch add command -label {Checkout...} \ + -command branch_checkout::dialog \ + -accelerator $M1T-O + lappend disable_on_lock [list .mbar.branch entryconf \ + [.mbar.branch index last] -state] + .mbar.branch add command -label {Rename...} \ -command branch_rename::dialog lappend disable_on_lock [list .mbar.branch entryconf \ @@ -1739,7 +1745,7 @@ switch -- $subcommand { browser { set subcommand_args {rev?} switch [llength $argv] { - 0 { set current_branch [current-branch] } + 0 { load_current_branch } 1 { set current_branch [lindex $argv 0] } default usage } @@ -1773,7 +1779,7 @@ blame { unset is_path if {$head eq {}} { - set current_branch [current-branch] + load_current_branch } else { set current_branch $head } @@ -2240,6 +2246,8 @@ bind $ui_diff {focus %W} if {[is_enabled branch]} { bind . <$M1B-Key-n> branch_create::dialog bind . <$M1B-Key-N> branch_create::dialog + bind . <$M1B-Key-o> branch_checkout::dialog + bind . <$M1B-Key-O> branch_checkout::dialog } if {[is_enabled transport]} { bind . <$M1B-Key-p> do_push_anywhere @@ -2326,9 +2334,7 @@ user.email settings into your personal # if {[is_enabled transport]} { load_all_remotes - load_all_heads - populate_branch_menu populate_fetch_menu populate_push_menu } diff --git a/lib/branch.tcl b/lib/branch.tcl index a6e6921174..b948d926ae 100644 --- a/lib/branch.tcl +++ b/lib/branch.tcl @@ -2,7 +2,6 @@ # Copyright (C) 2006, 2007 Shawn Pearce proc load_all_heads {} { - global all_heads global some_heads_tracking set rh refs/heads @@ -16,7 +15,7 @@ proc load_all_heads {} { } close $fd - set all_heads [lsort $all_heads] + return [lsort $all_heads] } proc load_all_tags {} { @@ -30,173 +29,7 @@ proc load_all_tags {} { return $all_tags } -proc populate_branch_menu {} { - global all_heads disable_on_lock - - set m .mbar.branch - set last [$m index last] - for {set i 0} {$i <= $last} {incr i} { - if {[$m type $i] eq {separator}} { - $m delete $i last - set new_dol [list] - foreach a $disable_on_lock { - if {[lindex $a 0] ne $m || [lindex $a 2] < $i} { - lappend new_dol $a - } - } - set disable_on_lock $new_dol - break - } - } - - if {$all_heads ne {}} { - $m add separator - } - foreach b $all_heads { - $m add radiobutton \ - -label $b \ - -command [list switch_branch $b] \ - -variable current_branch \ - -value $b - lappend disable_on_lock \ - [list $m entryconf [$m index last] -state] - } -} - proc radio_selector {varname value args} { upvar #0 $varname var set var $value } - -proc switch_branch {new_branch} { - global HEAD commit_type current_branch repo_config - - if {![lock_index switch]} return - - # -- Our in memory state should match the repository. - # - repository_state curType curHEAD curMERGE_HEAD - if {[string match amend* $commit_type] - && $curType eq {normal} - && $curHEAD eq $HEAD} { - } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} { - info_popup {Last scanned state does not match repository state. - -Another Git program has modified this repository since the last scan. A rescan must be performed before the current branch can be changed. - -The rescan will be automatically started now. -} - unlock_index - rescan {set ui_status_value {Ready.}} - return - } - - # -- Don't do a pointless switch. - # - if {$current_branch eq $new_branch} { - unlock_index - return - } - - if {$repo_config(gui.trustmtime) eq {true}} { - switch_branch_stage2 {} $new_branch - } else { - set ui_status_value {Refreshing file status...} - set cmd [list git update-index] - lappend cmd -q - lappend cmd --unmerged - lappend cmd --ignore-missing - lappend cmd --refresh - set fd_rf [open "| $cmd" r] - fconfigure $fd_rf -blocking 0 -translation binary - fileevent $fd_rf readable \ - [list switch_branch_stage2 $fd_rf $new_branch] - } -} - -proc switch_branch_stage2 {fd_rf new_branch} { - global ui_status_value HEAD - - if {$fd_rf ne {}} { - read $fd_rf - if {![eof $fd_rf]} return - close $fd_rf - } - - set ui_status_value "Updating working directory to '$new_branch'..." - set cmd [list git read-tree] - lappend cmd -m - lappend cmd -u - lappend cmd --exclude-per-directory=.gitignore - lappend cmd $HEAD - lappend cmd $new_branch - set fd_rt [open "| $cmd" r] - fconfigure $fd_rt -blocking 0 -translation binary - fileevent $fd_rt readable \ - [list switch_branch_readtree_wait $fd_rt $new_branch] -} - -proc switch_branch_readtree_wait {fd_rt new_branch} { - global selected_commit_type commit_type HEAD MERGE_HEAD PARENT - global current_branch - global ui_comm ui_status_value - - # -- We never get interesting output on stdout; only stderr. - # - read $fd_rt - fconfigure $fd_rt -blocking 1 - if {![eof $fd_rt]} { - fconfigure $fd_rt -blocking 0 - return - } - - # -- The working directory wasn't in sync with the index and - # we'd have to overwrite something to make the switch. A - # merge is required. - # - if {[catch {close $fd_rt} err]} { - regsub {^fatal: } $err {} err - warn_popup "File level merge required. - -$err - -Staying on branch '$current_branch'." - set ui_status_value "Aborted checkout of '$new_branch' (file level merging is required)." - unlock_index - return - } - - # -- Update the symbolic ref. Core git doesn't even check for failure - # here, it Just Works(tm). If it doesn't we are in some really ugly - # state that is difficult to recover from within git-gui. - # - if {[catch {git symbolic-ref HEAD "refs/heads/$new_branch"} err]} { - error_popup "Failed to set current branch. - -This working directory is only partially switched. We successfully updated your files, but failed to update an internal Git file. - -This should not have occurred. [appname] will now close and give up. - -$err" - do_quit - return - } - - # -- Update our repository state. If we were previously in amend mode - # we need to toss the current buffer and do a full rescan to update - # our file lists. If we weren't in amend mode our file lists are - # accurate and we can avoid the rescan. - # - unlock_index - set selected_commit_type new - if {[string match amend* $commit_type]} { - $ui_comm delete 0.0 end - $ui_comm edit reset - $ui_comm edit modified false - rescan {set ui_status_value "Checked out branch '$current_branch'."} - } else { - repository_state commit_type HEAD MERGE_HEAD - set PARENT $HEAD - set ui_status_value "Checked out branch '$current_branch'." - } -} diff --git a/lib/branch_checkout.tcl b/lib/branch_checkout.tcl new file mode 100644 index 0000000000..62230efe43 --- /dev/null +++ b/lib/branch_checkout.tcl @@ -0,0 +1,88 @@ +# git-gui branch checkout support +# Copyright (C) 2007 Shawn Pearce + +class branch_checkout { + +field w ; # widget path +field w_rev ; # mega-widget to pick the initial revision + +field opt_fetch 1; # refetch tracking branch if used? +field opt_detach 0; # force a detached head case? + +constructor dialog {} { + make_toplevel top w + wm title $top "[appname] ([reponame]): Checkout Branch" + if {$top ne {.}} { + wm geometry $top "+[winfo rootx .]+[winfo rooty .]" + } + + label $w.header -text {Checkout Branch} -font font_uibold + pack $w.header -side top -fill x + + frame $w.buttons + button $w.buttons.create -text Checkout \ + -default active \ + -command [cb _checkout] + pack $w.buttons.create -side right + button $w.buttons.cancel -text {Cancel} \ + -command [list destroy $w] + pack $w.buttons.cancel -side right -padx 5 + pack $w.buttons -side bottom -fill x -pady 10 -padx 10 + + set w_rev [::choose_rev::new $w.rev {Revision}] + pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5 + + labelframe $w.options -text {Options} + + checkbutton $w.options.fetch \ + -text {Fetch Tracking Branch} \ + -variable @opt_fetch + pack $w.options.fetch -anchor nw + + checkbutton $w.options.detach \ + -text {Detach From Local Branch} \ + -variable @opt_detach + pack $w.options.detach -anchor nw + + pack $w.options -anchor nw -fill x -pady 5 -padx 5 + + bind $w [cb _visible] + bind $w [list destroy $w] + bind $w [cb _checkout]\;break + tkwait window $w +} + +method _checkout {} { + set spec [$w_rev get_tracking_branch] + if {$spec ne {} && $opt_fetch} { + set new {} + } elseif {[catch {set new [$w_rev commit_or_die]}]} { + return + } + + if {$opt_detach} { + set ref {} + } else { + set ref [$w_rev get_local_branch] + } + + set co [::checkout_op::new [$w_rev get] $new $ref] + $co parent $w + $co enable_checkout 1 + if {$spec ne {} && $opt_fetch} { + $co enable_fetch $spec + } + + if {[$co run]} { + destroy $w + } else { + $w_rev focus_filter + } +} + +method _visible {} { + grab $w + $w_rev focus_filter +} + +} diff --git a/lib/branch_create.tcl b/lib/branch_create.tcl index f708957b22..def615d19d 100644 --- a/lib/branch_create.tcl +++ b/lib/branch_create.tcl @@ -73,7 +73,7 @@ constructor dialog {} { pack $w.options.merge.l -side left radiobutton $w.options.merge.no \ -text No \ - -value no \ + -value none \ -variable @opt_merge pack $w.options.merge.no -side left radiobutton $w.options.merge.ff \ @@ -113,7 +113,7 @@ constructor dialog {} { } method _create {} { - global repo_config current_branch + global repo_config global M1B set spec [$w_rev get_tracking_branch] @@ -155,17 +155,6 @@ method _create {} { return } - if {$newbranch eq $current_branch} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "'$newbranch' already exists and is the current branch." - focus $w_name - return - } - if {[catch {git check-ref-format "heads/$newbranch"}]} { tk_messageBox \ -icon error \ @@ -178,228 +167,28 @@ method _create {} { } if {$spec ne {} && $opt_fetch} { - set l_trck [lindex $spec 0] - set remote [lindex $spec 1] - set r_head [lindex $spec 2] - regsub ^refs/heads/ $r_head {} r_head - - set c $w.fetch_trck - toplevel $c - wm title $c "Refreshing Tracking Branch" - wm geometry $c "+[winfo rootx $w]+[winfo rooty $w]" - - set e [::console::embed \ - $c.console \ - "Fetching $r_head from $remote"] - pack $c.console -fill both -expand 1 - $e exec \ - [list git fetch $remote +$r_head:$l_trck] \ - [cb _finish_fetch $newbranch $c $e] - - bind $c [list grab $c] - bind $c <$M1B-Key-w> break - bind $c <$M1B-Key-W> break - wm protocol $c WM_DELETE_WINDOW [cb _noop] - } else { - _finish_create $this $newbranch - } -} - -method _noop {} {} - -method _finish_fetch {newbranch c e ok} { - wm protocol $c WM_DELETE_WINDOW {} - - if {$ok} { - destroy $c - _finish_create $this $newbranch - } else { - $e done $ok - button $c.close -text Close -command [list destroy $c] - pack $c.close -side bottom -anchor e -padx 10 -pady 10 - } -} - -method _finish_create {newbranch} { - global null_sha1 all_heads - - if {[catch {set new [$w_rev commit_or_die]}]} { + set new {} + } elseif {[catch {set new [$w_rev commit_or_die]}]} { return } - set ref refs/heads/$newbranch - if {[catch {set cur [git rev-parse --verify "$ref^0"]}]} { - # Assume it does not exist, and that is what the error was. - # - set reflog_msg "branch: Created from [$w_rev get]" - set cur $null_sha1 - } elseif {$opt_merge eq {no}} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Branch '$newbranch' already exists." + set co [::checkout_op::new \ + [$w_rev get] \ + $new \ + refs/heads/$newbranch] + $co parent $w + $co enable_create 1 + $co enable_merge $opt_merge + $co enable_checkout $opt_checkout + if {$spec ne {} && $opt_fetch} { + $co enable_fetch $spec + } + + if {[$co run]} { + destroy $w + } else { focus $w_name - return - } else { - set mrb {} - catch {set mrb [git merge-base $new $cur]} - switch -- $opt_merge { - ff { - if {$mrb eq $new} { - # The current branch is actually newer. - # - set new $cur - } elseif {$mrb eq $cur} { - # The current branch is older. - # - set reflog_msg "merge [$w_rev get]: Fast-forward" - } else { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Branch '$newbranch' already exists.\n\nIt cannot fast-forward to [$w_rev get].\nA merge is required." - focus $w_name - return - } - } - reset { - if {$mrb eq $cur} { - # The current branch is older. - # - set reflog_msg "merge [$w_rev get]: Fast-forward" - } else { - # The current branch will lose things. - # - if {[_confirm_reset $this $newbranch $cur $new]} { - set reflog_msg "reset [$w_rev get]" - } else { - return - } - } - } - default { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Branch '$newbranch' already exists." - focus $w_name - return - } - } } - - if {$new ne $cur} { - if {[catch { - git update-ref -m $reflog_msg $ref $new $cur - } err]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Failed to create '$newbranch'.\n\n$err" - return - } - } - - if {$cur eq $null_sha1} { - lappend all_heads $newbranch - set all_heads [lsort -uniq $all_heads] - populate_branch_menu - } - - destroy $w - if {$opt_checkout} { - switch_branch $newbranch - } -} - -method _confirm_reset {newbranch cur new} { - set reset_ok 0 - set gitk [list do_gitk [list $cur ^$new]] - - set c $w.confirm_reset - toplevel $c - wm title $c "Confirm Branch Reset" - wm geometry $c "+[winfo rootx $w]+[winfo rooty $w]" - - pack [label $c.msg1 \ - -anchor w \ - -justify left \ - -text "Resetting '$newbranch' to [$w_rev get] will lose the following commits:" \ - ] -anchor w - - set list $c.list.l - frame $c.list - text $list \ - -font font_diff \ - -width 80 \ - -height 10 \ - -wrap none \ - -xscrollcommand [list $c.list.sbx set] \ - -yscrollcommand [list $c.list.sby set] - scrollbar $c.list.sbx -orient h -command [list $list xview] - scrollbar $c.list.sby -orient v -command [list $list yview] - pack $c.list.sbx -fill x -side bottom - pack $c.list.sby -fill y -side right - pack $list -fill both -expand 1 - pack $c.list -fill both -expand 1 -padx 5 -pady 5 - - pack [label $c.msg2 \ - -anchor w \ - -justify left \ - -text "Recovering lost commits may not be easy." \ - ] - pack [label $c.msg3 \ - -anchor w \ - -justify left \ - -text "Reset '$newbranch'?" \ - ] - - frame $c.buttons - button $c.buttons.visualize \ - -text Visualize \ - -command $gitk - pack $c.buttons.visualize -side left - button $c.buttons.reset \ - -text Reset \ - -command " - set @reset_ok 1 - destroy $c - " - pack $c.buttons.reset -side right - button $c.buttons.cancel \ - -default active \ - -text Cancel \ - -command [list destroy $c] - pack $c.buttons.cancel -side right -padx 5 - pack $c.buttons -side bottom -fill x -pady 10 -padx 10 - - set fd [open "| git rev-list --pretty=oneline $cur ^$new" r] - while {[gets $fd line] > 0} { - set abbr [string range $line 0 7] - set subj [string range $line 41 end] - $list insert end "$abbr $subj\n" - } - close $fd - $list configure -state disabled - - bind $c $gitk - - bind $c " - grab $c - focus $c.buttons.cancel - " - bind $c [list destroy $c] - bind $c [list destroy $c] - tkwait window $c - return $reset_ok } method _validate {d S} { diff --git a/lib/branch_delete.tcl b/lib/branch_delete.tcl index 138e84192c..c7573c6c72 100644 --- a/lib/branch_delete.tcl +++ b/lib/branch_delete.tcl @@ -9,7 +9,7 @@ field w_check ; # revision picker for merge test field w_delete ; # delete button constructor dialog {} { - global all_heads current_branch + global current_branch make_toplevel top w wm title $top "[appname] ([reponame]): Delete Branch" @@ -54,7 +54,7 @@ constructor dialog {} { $w_check none {Always (Do not perform merge test.)} pack $w.check -anchor nw -fill x -pady 5 -padx 5 - foreach h $all_heads { + foreach h [load_all_heads] { if {$h ne $current_branch} { $w_heads insert end $h } @@ -79,8 +79,6 @@ method _select {} { } method _delete {} { - global all_heads - if {[catch {set check_cmt [$w_check commit_or_die]}]} { return } @@ -133,11 +131,6 @@ Delete the selected branches?} set o [lindex $i 1] if {[catch {git update-ref -d "refs/heads/$b" $o} err]} { append failed " - $b: $err\n" - } else { - set x [lsearch -sorted -exact $all_heads $b] - if {$x >= 0} { - set all_heads [lreplace $all_heads $x $x] - } } } @@ -150,8 +143,6 @@ Delete the selected branches?} -message "Failed to delete branches:\n$failed" } - set all_heads [lsort $all_heads] - populate_branch_menu destroy $w } diff --git a/lib/branch_rename.tcl b/lib/branch_rename.tcl index 405101637f..1cadc31d20 100644 --- a/lib/branch_rename.tcl +++ b/lib/branch_rename.tcl @@ -8,7 +8,7 @@ field oldname field newname constructor dialog {} { - global all_heads current_branch + global current_branch make_toplevel top w wm title $top "[appname] ([reponame]): Rename Branch" @@ -34,7 +34,7 @@ constructor dialog {} { frame $w.rename label $w.rename.oldname_l -text {Branch:} - eval tk_optionMenu $w.rename.oldname_m @oldname $all_heads + eval tk_optionMenu $w.rename.oldname_m @oldname [load_all_heads] label $w.rename.newname_l -text {New Name:} entry $w.rename.newname_t \ @@ -64,7 +64,7 @@ constructor dialog {} { } method _rename {} { - global all_heads current_branch + global current_branch if {$oldname eq {}} { tk_messageBox \ @@ -118,14 +118,6 @@ method _rename {} { return } - set oldidx [lsearch -exact -sorted $all_heads $oldname] - if {$oldidx >= 0} { - set all_heads [lreplace $all_heads $oldidx $oldidx] - } - lappend all_heads $newname - set all_heads [lsort $all_heads] - populate_branch_menu - if {$current_branch eq $oldname} { set current_branch $newname } diff --git a/lib/checkout_op.tcl b/lib/checkout_op.tcl new file mode 100644 index 0000000000..844d8e551c --- /dev/null +++ b/lib/checkout_op.tcl @@ -0,0 +1,569 @@ +# git-gui commit checkout support +# Copyright (C) 2007 Shawn Pearce + +class checkout_op { + +field w {}; # our window (if we have one) +field w_cons {}; # embedded console window object + +field new_expr ; # expression the user saw/thinks this is +field new_hash ; # commit SHA-1 we are switching to +field new_ref ; # ref we are updating/creating + +field parent_w .; # window that started us +field merge_type none; # type of merge to apply to existing branch +field fetch_spec {}; # refetch tracking branch if used? +field checkout 1; # actually checkout the branch? +field create 0; # create the branch if it doesn't exist? + +field reset_ok 0; # did the user agree to reset? +field fetch_ok 0; # did the fetch succeed? + +field update_old {}; # was the update-ref call deferred? +field reflog_msg {}; # log message for the update-ref call + +constructor new {expr hash {ref {}}} { + set new_expr $expr + set new_hash $hash + set new_ref $ref + + return $this +} + +method parent {path} { + set parent_w [winfo toplevel $path] +} + +method enable_merge {type} { + set merge_type $type +} + +method enable_fetch {spec} { + set fetch_spec $spec +} + +method enable_checkout {co} { + set checkout $co +} + +method enable_create {co} { + set create $co +} + +method run {} { + if {$fetch_spec ne {}} { + global M1B + + # We were asked to refresh a single tracking branch + # before we get to work. We should do that before we + # consider any ref updating. + # + set fetch_ok 0 + set l_trck [lindex $fetch_spec 0] + set remote [lindex $fetch_spec 1] + set r_head [lindex $fetch_spec 2] + regsub ^refs/heads/ $r_head {} r_name + + _toplevel $this {Refreshing Tracking Branch} + set w_cons [::console::embed \ + $w.console \ + "Fetching $r_name from $remote"] + pack $w.console -fill both -expand 1 + $w_cons exec \ + [list git fetch $remote +$r_head:$l_trck] \ + [cb _finish_fetch] + + bind $w <$M1B-Key-w> break + bind $w <$M1B-Key-W> break + bind $w " + [list grab $w] + [list focus $w] + " + wm protocol $w WM_DELETE_WINDOW [cb _noop] + tkwait window $w + + if {!$fetch_ok} { + delete_this + return 0 + } + } + + if {$new_ref ne {}} { + # If we have a ref we need to update it before we can + # proceed with a checkout (if one was enabled). + # + if {![_update_ref $this]} { + delete_this + return 0 + } + } + + if {$checkout} { + _checkout $this + return 1 + } + + delete_this + return 1 +} + +method _noop {} {} + +method _finish_fetch {ok} { + if {$ok} { + set l_trck [lindex $fetch_spec 0] + if {[catch {set new_hash [git rev-parse --verify "$l_trck^0"]} err]} { + set ok 0 + $w_cons insert "fatal: Cannot resolve $l_trck" + $w_cons insert $err + } + } + + $w_cons done $ok + set w_cons {} + wm protocol $w WM_DELETE_WINDOW {} + + if {$ok} { + destroy $w + set w {} + } else { + button $w.close -text Close -command [list destroy $w] + pack $w.close -side bottom -anchor e -padx 10 -pady 10 + } + + set fetch_ok $ok +} + +method _update_ref {} { + global null_sha1 current_branch + + set ref $new_ref + set new $new_hash + + set is_current 0 + set rh refs/heads/ + set rn [string length $rh] + if {[string equal -length $rn $rh $ref]} { + set newbranch [string range $ref $rn end] + if {$current_branch eq $newbranch} { + set is_current 1 + } + } else { + set newbranch $ref + } + + if {[catch {set cur [git rev-parse --verify "$ref^0"]}]} { + # Assume it does not exist, and that is what the error was. + # + if {!$create} { + _error $this "Branch '$newbranch' does not exist." + return 0 + } + + set reflog_msg "branch: Created from $new_expr" + set cur $null_sha1 + } elseif {$create && $merge_type eq {none}} { + # We were told to create it, but not do a merge. + # Bad. Name shouldn't have existed. + # + _error $this "Branch '$newbranch' already exists." + return 0 + } elseif {!$create && $merge_type eq {none}} { + # We aren't creating, it exists and we don't merge. + # We are probably just a simple branch switch. + # Use whatever value we just read. + # + set new $cur + set new_hash $cur + } elseif {$new eq $cur} { + # No merge would be required, don't compute anything. + # + } else { + set mrb {} + catch {set mrb [git merge-base $new $cur]} + switch -- $merge_type { + ff { + if {$mrb eq $new} { + # The current branch is actually newer. + # + set new $cur + } elseif {$mrb eq $cur} { + # The current branch is older. + # + set reflog_msg "merge $new_expr: Fast-forward" + } else { + _error $this "Branch '$newbranch' already exists.\n\nIt cannot fast-forward to $new_expr.\nA merge is required." + return 0 + } + } + reset { + if {$mrb eq $cur} { + # The current branch is older. + # + set reflog_msg "merge $new_expr: Fast-forward" + } else { + # The current branch will lose things. + # + if {[_confirm_reset $this $cur]} { + set reflog_msg "reset $new_expr" + } else { + return 0 + } + } + } + default { + _error $this "Only 'ff' and 'reset' merge is currently supported." + return 0 + } + } + } + + if {$new ne $cur} { + if {$is_current} { + # No so fast. We should defer this in case + # we cannot update the working directory. + # + set update_old $cur + return 1 + } + + if {[catch { + git update-ref -m $reflog_msg $ref $new $cur + } err]} { + _error $this "Failed to update '$newbranch'.\n\n$err" + return 0 + } + } + + return 1 +} + +method _checkout {} { + if {[lock_index checkout_op]} { + after idle [cb _start_checkout] + } else { + _error $this "Index is already locked." + delete_this + } +} + +method _start_checkout {} { + global HEAD commit_type + + # -- Our in memory state should match the repository. + # + repository_state curType curHEAD curMERGE_HEAD + if {[string match amend* $commit_type] + && $curType eq {normal} + && $curHEAD eq $HEAD} { + } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} { + info_popup {Last scanned state does not match repository state. + +Another Git program has modified this repository since the last scan. A rescan must be performed before the current branch can be changed. + +The rescan will be automatically started now. +} + unlock_index + rescan ui_ready + delete_this + return + } + + if {[is_config_true gui.trustmtime]} { + _readtree $this + } else { + ui_status {Refreshing file status...} + set cmd [list git update-index] + lappend cmd -q + lappend cmd --unmerged + lappend cmd --ignore-missing + lappend cmd --refresh + set fd [open "| $cmd" r] + fconfigure $fd -blocking 0 -translation binary + fileevent $fd readable [cb _refresh_wait $fd] + } +} + +method _refresh_wait {fd} { + read $fd + if {[eof $fd]} { + close $fd + _readtree $this + } +} + +method _name {} { + if {$new_ref eq {}} { + return [string range $new_hash 0 7] + } + + set rh refs/heads/ + set rn [string length $rh] + if {[string equal -length $rn $rh $new_ref]} { + return [string range $new_ref $rn end] + } else { + return $new_ref + } +} + +method _readtree {} { + global HEAD + + ui_status "Updating working directory to '[_name $this]'..." + set cmd [list git read-tree] + lappend cmd -m + lappend cmd -u + lappend cmd --exclude-per-directory=.gitignore + lappend cmd $HEAD + lappend cmd $new_hash + set fd [open "| $cmd" r] + fconfigure $fd -blocking 0 -translation binary + fileevent $fd readable [cb _readtree_wait $fd] +} + +method _readtree_wait {fd} { + global selected_commit_type commit_type HEAD MERGE_HEAD PARENT + global current_branch is_detached + global ui_comm + + # -- We never get interesting output on stdout; only stderr. + # + read $fd + fconfigure $fd -blocking 1 + if {![eof $fd]} { + fconfigure $fd -blocking 0 + return + } + + set name [_name $this] + + # -- The working directory wasn't in sync with the index and + # we'd have to overwrite something to make the switch. A + # merge is required. + # + if {[catch {close $fd} err]} { + regsub {^fatal: } $err {} err + warn_popup "File level merge required. + +$err + +Staying on branch '$current_branch'." + ui_status "Aborted checkout of '$name' (file level merging is required)." + unlock_index + delete_this + return + } + + set log "checkout: moving" + if {!$is_detached} { + append log " from $current_branch" + } + + # -- Move/create HEAD as a symbolic ref. Core git does not + # even check for failure here, it Just Works(tm). If it + # doesn't we are in some really ugly state that is difficult + # to recover from within git-gui. + # + set rh refs/heads/ + set rn [string length $rh] + if {[string equal -length $rn $rh $new_ref]} { + set new_branch [string range $new_ref $rn end] + append log " to $new_branch" + + if {[catch { + git symbolic-ref -m $log HEAD $new_ref + } err]} { + _fatal $this $err + } + set current_branch $new_branch + set is_detached 0 + } else { + append log " to $new_expr" + + if {[catch { + _detach_HEAD $log $new_hash + } err]} { + _fatal $this $err + } + set current_branch HEAD + set is_detached 1 + } + + # -- We had to defer updating the branch itself until we + # knew the working directory would update. So now we + # need to finish that work. If it fails we're in big + # trouble. + # + if {$update_old ne {}} { + if {[catch { + git update-ref \ + -m $reflog_msg \ + $new_ref \ + $new_hash \ + $update_old + } err]} { + _fatal $this $err + } + } + + if {$is_detached} { + info_popup "You are no longer on a local branch. + +If you wanted to be on a branch, create one now starting from 'This Detached Checkout'." + } + + # -- Update our repository state. If we were previously in + # amend mode we need to toss the current buffer and do a + # full rescan to update our file lists. If we weren't in + # amend mode our file lists are accurate and we can avoid + # the rescan. + # + unlock_index + set selected_commit_type new + if {[string match amend* $commit_type]} { + $ui_comm delete 0.0 end + $ui_comm edit reset + $ui_comm edit modified false + rescan [list ui_status "Checked out '$name'."] + } else { + repository_state commit_type HEAD MERGE_HEAD + set PARENT $HEAD + ui_status "Checked out '$name'." + } + delete_this +} + +git-version proc _detach_HEAD {log new} { + >= 1.5.3 { + git update-ref --no-deref -m $log HEAD $new + } + default { + set p [gitdir HEAD] + file delete $p + set fd [open $p w] + fconfigure $fd -translation lf -encoding utf-8 + puts $fd $new + close $fd + } +} + +method _confirm_reset {cur} { + set reset_ok 0 + set name [_name $this] + set gitk [list do_gitk [list $cur ^$new_hash]] + + _toplevel $this {Confirm Branch Reset} + pack [label $w.msg1 \ + -anchor w \ + -justify left \ + -text "Resetting '$name' to $new_expr will lose the following commits:" \ + ] -anchor w + + set list $w.list.l + frame $w.list + text $list \ + -font font_diff \ + -width 80 \ + -height 10 \ + -wrap none \ + -xscrollcommand [list $w.list.sbx set] \ + -yscrollcommand [list $w.list.sby set] + scrollbar $w.list.sbx -orient h -command [list $list xview] + scrollbar $w.list.sby -orient v -command [list $list yview] + pack $w.list.sbx -fill x -side bottom + pack $w.list.sby -fill y -side right + pack $list -fill both -expand 1 + pack $w.list -fill both -expand 1 -padx 5 -pady 5 + + pack [label $w.msg2 \ + -anchor w \ + -justify left \ + -text {Recovering lost commits may not be easy.} \ + ] + pack [label $w.msg3 \ + -anchor w \ + -justify left \ + -text "Reset '$name'?" \ + ] + + frame $w.buttons + button $w.buttons.visualize \ + -text Visualize \ + -command $gitk + pack $w.buttons.visualize -side left + button $w.buttons.reset \ + -text Reset \ + -command " + set @reset_ok 1 + destroy $w + " + pack $w.buttons.reset -side right + button $w.buttons.cancel \ + -default active \ + -text Cancel \ + -command [list destroy $w] + pack $w.buttons.cancel -side right -padx 5 + pack $w.buttons -side bottom -fill x -pady 10 -padx 10 + + set fd [open "| git rev-list --pretty=oneline $cur ^$new_hash" r] + while {[gets $fd line] > 0} { + set abbr [string range $line 0 7] + set subj [string range $line 41 end] + $list insert end "$abbr $subj\n" + } + close $fd + $list configure -state disabled + + bind $w $gitk + bind $w " + grab $w + focus $w.buttons.cancel + " + bind $w [list destroy $w] + bind $w [list destroy $w] + tkwait window $w + return $reset_ok +} + +method _error {msg} { + if {[winfo ismapped $parent_w]} { + set p $parent_w + } else { + set p . + } + + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $p] \ + -parent $p \ + -message $msg +} + +method _toplevel {title} { + regsub -all {::} $this {__} w + set w .$w + + if {[winfo ismapped $parent_w]} { + set p $parent_w + } else { + set p . + } + + toplevel $w + wm title $w $title + wm geometry $w "+[winfo rootx $p]+[winfo rooty $p]" +} + +method _fatal {err} { + error_popup "Failed to set current branch. + +This working directory is only partially switched. We successfully updated your files, but failed to update an internal Git file. + +This should not have occurred. [appname] will now close and give up. + +$err" + exit 1 +} + +} diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index e6af073595..7f2b4e603d 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -18,7 +18,7 @@ field spec_trck ; # list of all tracking branch specs field spec_tag ; # list of all tag specs constructor new {path {title {}}} { - global all_heads current_branch + global current_branch is_detached set w $path @@ -29,6 +29,15 @@ constructor new {path {title {}}} { } bind $w [cb _delete %W] + if {$is_detached} { + radiobutton $w.detachedhead_r \ + -anchor w \ + -text {This Detached Checkout} \ + -value HEAD \ + -variable @revtype + grid $w.detachedhead_r -sticky we -padx {0 5} -columnspan 2 + } + radiobutton $w.expr_r \ -text {Revision Expression:} \ -value expr \ @@ -86,14 +95,18 @@ constructor new {path {title {}}} { grid $w.list -sticky nswe -padx {20 5} -columnspan 2 grid columnconfigure $w 1 -weight 1 - grid rowconfigure $w 2 -weight 1 + if {$is_detached} { + grid rowconfigure $w 3 -weight 1 + } else { + grid rowconfigure $w 2 -weight 1 + } trace add variable @revtype write [cb _select] bind $w_filter [list focus $w_list]\;break bind $w_filter [list focus $w_list] set spec_head [list] - foreach name $all_heads { + foreach name [load_all_heads] { lappend spec_head [list $name refs/heads/$name] } @@ -109,7 +122,8 @@ constructor new {path {title {}}} { lappend spec_tag [list $name refs/tags/$name] } - if {[llength $spec_head] > 0} { set revtype head + if {$is_detached} { set revtype HEAD + } elseif {[llength $spec_head] > 0} { set revtype head } elseif {[llength $spec_trck] > 0} { set revtype trck } elseif {[llength $spec_tag ] > 0} { set revtype tag } else { set revtype expr @@ -153,6 +167,7 @@ method get {} { } } + HEAD { return HEAD } expr { return $c_expr } none { return {} } default { error "unknown type of revision" } @@ -163,6 +178,20 @@ method pick_tracking_branch {} { set revtype trck } +method focus_filter {} { + if {[$w_filter cget -state] eq {normal}} { + focus $w_filter + } +} + +method get_local_branch {} { + if {$revtype eq {head}} { + return [_expr $this] + } else { + return {} + } +} + method get_tracking_branch {} { set i [$w_list curselection] if {$i eq {} || $revtype ne {trck}} { @@ -222,6 +251,7 @@ method _expr {} { error "Revision expression is empty." } } + HEAD { return HEAD } none { return {} } default { error "unknown type of revision" } } @@ -249,9 +279,7 @@ method _filter {P} { method _select {args} { _rebuild $this $filter - if {[$w_filter cget -state] eq {normal}} { - focus $w_filter - } + focus_filter $this } method _rebuild {pat} { @@ -261,6 +289,7 @@ method _rebuild {pat} { trck { set new $spec_trck } tag { set new $spec_tag } expr - + HEAD - none { set new [list] set ste disabled diff --git a/lib/commit.tcl b/lib/commit.tcl index c5f608beb0..d0e4996bae 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -359,14 +359,6 @@ A rescan will be automatically started now. if {[is_enabled singlecommit]} do_quit - # -- Make sure our current branch exists. - # - if {$commit_type eq {initial}} { - lappend all_heads $current_branch - set all_heads [lsort -unique $all_heads] - populate_branch_menu - } - # -- Update in memory status # set selected_commit_type new diff --git a/lib/console.tcl b/lib/console.tcl index 297e8defa4..27a880e408 100644 --- a/lib/console.tcl +++ b/lib/console.tcl @@ -173,6 +173,14 @@ method chain {cmdlist {ok 1}} { } } +method insert {txt} { + if {![winfo exists $w.m.t]} {_init $this} + $w.m.t conf -state normal + $w.m.t insert end "$txt\n" + set console_cr [$w.m.t index {end -1c}] + $w.m.t conf -state disabled +} + method done {ok} { if {$ok} { if {[winfo exists $w.m.s]} { diff --git a/lib/transport.tcl b/lib/transport.tcl index e8ebc6eda0..3a22bd40d4 100644 --- a/lib/transport.tcl +++ b/lib/transport.tcl @@ -74,7 +74,7 @@ trace add variable push_remote write \ [list radio_selector push_urltype remote] proc do_push_anywhere {} { - global all_heads all_remotes current_branch + global all_remotes current_branch global push_urltype push_remote push_url push_thin push_tags set w .push_setup @@ -101,7 +101,7 @@ proc do_push_anywhere {} { -width 70 \ -selectmode extended \ -yscrollcommand [list $w.source.sby set] - foreach h $all_heads { + foreach h [load_all_heads] { $w.source.l insert end $h if {$h eq $current_branch} { $w.source.l select set end From 02087abccea681bc0e1f6a9607e97df79ebbf2d9 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 21:19:59 -0400 Subject: [PATCH 130/213] git-gui: Unabbreviate commit SHA-1s prior to display If the end-user feeds us an abbreviated SHA-1 on the command line for `git gui browser` or `git gui blame` we now unabbreviate the value through `git rev-parse` so that the title section of the blame or browser window shows the user the complete SHA-1 as Git determined it to be. If the abbreviated value was ambiguous we now complain with the standard error message(s) as reported by git-rev-parse --verify, so that the user can understand what might be wrong and correct their command line. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/git-gui.sh b/git-gui.sh index ac043677c8..1844c9067c 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1746,7 +1746,18 @@ browser { set subcommand_args {rev?} switch [llength $argv] { 0 { load_current_branch } - 1 { set current_branch [lindex $argv 0] } + 1 { + set current_branch [lindex $argv 0] + if {[regexp {^[0-9a-f]{1,39}$} $current_branch]} { + if {[catch { + set current_branch \ + [git rev-parse --verify $current_branch] + } err]} { + puts stderr $err + exit 1 + } + } + } default usage } browser::new $current_branch @@ -1781,6 +1792,14 @@ blame { if {$head eq {}} { load_current_branch } else { + if {[regexp {^[0-9a-f]{1,39}$} $head]} { + if {[catch { + set head [git rev-parse --verify $head] + } err]} { + puts stderr $err + exit 1 + } + } set current_branch $head } From 84d3d7b84c600d90486205bf801580009dc523a8 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 21:29:54 -0400 Subject: [PATCH 131/213] git-gui: Default selection to first matching ref If we have specifications listed in our revision picker mega-widget then we should default the selection within that widget to the first ref available. This way the user does not need to use the spacebar to activate the selection of a ref within the box; instead they can navigate up/down with the arrow keys and be done with it. Signed-off-by: Shawn O. Pearce --- lib/choose_rev.tcl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index 7f2b4e603d..1aab56f5cc 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -133,6 +133,7 @@ constructor new {path {title {}}} { set i 0 foreach spec $spec_head { if {[lindex $spec 0] eq $current_branch} { + $w_list selection clear 0 end $w_list selection set $i break } @@ -312,6 +313,10 @@ method _rebuild {pat} { $w_list insert end $txt } } + if {$cur_specs ne {}} { + $w_list selection clear 0 end + $w_list selection set 0 + } if {[$w_filter cget -state] ne $ste} { $w_list configure -state $ste From 827c71199da9b762e0758fe96302d0c8b7a04bb9 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 21:34:28 -0400 Subject: [PATCH 132/213] git-gui: Allow double-click in checkout dialog to start checkout If the user double clicks a branch in the checkout dialog then they probably want to start the checkout process on that branch. I found myself doing this without realizing it, and of course it did nothing as there was no action bound to the listbox's Double-Button-1 event handler. Since I did it without thinking, others will probably also try, and expect the same behavior. Signed-off-by: Shawn O. Pearce --- lib/branch_checkout.tcl | 1 + lib/choose_rev.tcl | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib/branch_checkout.tcl b/lib/branch_checkout.tcl index 62230efe43..72c45b4554 100644 --- a/lib/branch_checkout.tcl +++ b/lib/branch_checkout.tcl @@ -30,6 +30,7 @@ constructor dialog {} { pack $w.buttons -side bottom -fill x -pady 10 -padx 10 set w_rev [::choose_rev::new $w.rev {Revision}] + $w_rev bind_listbox [cb _checkout] pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5 labelframe $w.options -text {Options} diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index 1aab56f5cc..afd81707ce 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -185,6 +185,10 @@ method focus_filter {} { } } +method bind_listbox {event script} { + bind $w_list $event $script +} + method get_local_branch {} { if {$revtype eq {head}} { return [_expr $this] From b29bd5ca3b0060513b7b96380fc43f7ab4f12156 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 22:01:47 -0400 Subject: [PATCH 133/213] git-gui: Extract blame viewer status bar into mega-widget Our blame viewer has had a very fancy progress bar at the bottom of the window that shows the current status of the blame engine, which includes the number of lines completed as both a text and a graphical meter. I want to reuse this meter system in other places, such as during a branch switch where read-tree -v can give us a progress meter for any long-running operation. This change extracts the code and refactors it as a widget that we can take advantage of in locations other than in the blame viewer. Signed-off-by: Shawn O. Pearce --- lib/blame.tcl | 52 +++++++------------------------ lib/status_bar.tcl | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 lib/status_bar.tcl diff --git a/lib/blame.tcl b/lib/blame.tcl index 76b5168fb3..13bfab3352 100644 --- a/lib/blame.tcl +++ b/lib/blame.tcl @@ -21,7 +21,7 @@ field w_amov ; # text column: annotations + move tracking field w_asim ; # text column: annotations (simple computation) field w_file ; # text column: actual file data field w_cviewer ; # pane showing commit message -field status ; # text variable bound to status bar +field status ; # status mega-widget instance field old_height ; # last known height of $w.file_pane # Tk UI colors @@ -242,14 +242,7 @@ constructor new {i_commit i_path} { pack $w.file_pane.cm.sbx -side bottom -fill x pack $w_cviewer -expand 1 -fill both - frame $w.status \ - -borderwidth 1 \ - -relief sunken - label $w.status.l \ - -textvariable @status \ - -anchor w \ - -justify left - pack $w.status.l -side left + set status [::status_bar::new $w.status] menu $w.ctxm -tearoff 0 $w.ctxm add command \ @@ -360,19 +353,6 @@ method _load {jump} { set total_lines 0 } - if {[winfo exists $w.status.c]} { - $w.status.c coords bar 0 0 0 20 - } else { - canvas $w.status.c \ - -width 100 \ - -height [expr {int([winfo reqheight $w.status.l] * 0.6)}] \ - -borderwidth 1 \ - -relief groove \ - -highlightt 0 - $w.status.c create rectangle 0 0 0 20 -tags bar -fill navy - pack $w.status.c -side right - } - if {$history eq {}} { $w_back conf -state disabled } else { @@ -386,7 +366,7 @@ method _load {jump} { set amov_data [list [list]] set asim_data [list [list]] - set status "Loading $commit:[escape_path $path]..." + $status show "Reading $commit:[escape_path $path]..." $w_path conf -text [escape_path $path] if {$commit eq {}} { set fd [open $path r] @@ -510,13 +490,16 @@ method _exec_blame {cur_w cur_d options cur_s} { lappend cmd -- $path set fd [open "| $cmd" r] fconfigure $fd -blocking 0 -translation lf -encoding binary - fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d $cur_s] + fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d] set current_fd $fd set blame_lines 0 - _status $this $cur_s + + $status start \ + "Loading$cur_s annotations..." \ + {lines annotated} } -method _read_blame {fd cur_w cur_d cur_s} { +method _read_blame {fd cur_w cur_d} { upvar #0 $cur_d line_data variable group_colors variable original_options @@ -697,26 +680,13 @@ method _read_blame {fd cur_w cur_d cur_s} { { original location} } else { set current_fd {} - set status {Annotation complete.} - destroy $w.status.c + $status stop {Annotation complete.} } } else { - _status $this $cur_s + $status update $blame_lines $total_lines } } ifdeleted { catch {close $fd} } -method _status {cur_s} { - set have $blame_lines - set total $total_lines - set pdone 0 - if {$total} {set pdone [expr {100 * $have / $total}]} - - set status [format \ - "Loading%s annotations... %i of %i lines annotated (%2i%%)" \ - $cur_s $have $total $pdone] - $w.status.c coords bar 0 0 $pdone 20 -} - method _click {cur_w pos} { set lno [lindex [split [$cur_w index $pos] .] 0] _showcommit $this $cur_w $lno diff --git a/lib/status_bar.tcl b/lib/status_bar.tcl new file mode 100644 index 0000000000..a6dea29006 --- /dev/null +++ b/lib/status_bar.tcl @@ -0,0 +1,76 @@ +# git-gui status bar mega-widget +# Copyright (C) 2007 Shawn Pearce + +class status_bar { + +field w ; # our own window path +field w_l ; # text widget we draw messages into +field w_c ; # canvas we draw a progress bar into +field status {}; # single line of text we show +field prefix {}; # text we format into status +field units {}; # unit of progress + +constructor new {path} { + set w $path + set w_l $w.l + set w_c $w.c + + frame $w \ + -borderwidth 1 \ + -relief sunken + label $w_l \ + -textvariable @status \ + -anchor w \ + -justify left + pack $w_l -side left + + bind $w [cb _delete %W] + return $this +} + +method start {msg uds} { + if {[winfo exists $w_c]} { + $w_c coords bar 0 0 0 20 + } else { + canvas $w_c \ + -width 100 \ + -height [expr {int([winfo reqheight $w_l] * 0.6)}] \ + -borderwidth 1 \ + -relief groove \ + -highlightt 0 + $w_c create rectangle 0 0 0 20 -tags bar -fill navy + pack $w_c -side right + } + + set status $msg + set prefix $msg + set units $uds +} + +method update {have total} { + set pdone 0 + if {$total > 0} { + set pdone [expr {100 * $have / $total}] + } + + set status [format "%s ... %i of %i %s (%2i%%)" \ + $prefix $have $total $units $pdone] + $w_c coords bar 0 0 $pdone 20 +} + +method stop {msg} { + destroy $w_c + set status $msg +} + +method show {msg} { + set status $msg +} + +method _delete {current} { + if {$current eq $w} { + delete_this + } +} + +} From 51530d1722b0a4cccc630043fc4b46d075bf8558 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 22:06:33 -0400 Subject: [PATCH 134/213] git-gui: Change the main window progress bar to use status_bar Now that we have a fancy status bar mega-widget we can reuse that within our main window. This opens the door for implementating future improvements like a progress bar. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 14 ++++---------- lib/status_bar.tcl | 6 ++++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 1844c9067c..b2c9a9c6a0 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -438,7 +438,6 @@ set _reponame [lindex [file split \ set current_diff_path {} set current_diff_side {} set diff_actions [list] -set ui_status_value {Initializing...} set HEAD {} set PARENT {} @@ -761,13 +760,11 @@ proc mapdesc {state path} { } proc ui_status {msg} { - set ::ui_status_value $msg + $::main_status show $msg } proc ui_ready {{test {}}} { - if {$test eq {} || $::ui_status_value eq $test} { - ui_status Ready. - } + $::main_status show {Ready.} $test } proc escape_path {path} { @@ -2207,12 +2204,9 @@ unset ui_diff_applyhunk # -- Status Bar # -label .status -textvariable ui_status_value \ - -anchor w \ - -justify left \ - -borderwidth 1 \ - -relief sunken +set main_status [::status_bar::new .status] pack .status -anchor w -side bottom -fill x +$main_status show {Initializing...} # -- Load geometry # diff --git a/lib/status_bar.tcl b/lib/status_bar.tcl index a6dea29006..0e2ac07a5e 100644 --- a/lib/status_bar.tcl +++ b/lib/status_bar.tcl @@ -63,8 +63,10 @@ method stop {msg} { set status $msg } -method show {msg} { - set status $msg +method show {msg {test {}}} { + if {$test eq {} || $status eq $test} { + set status $msg + } } method _delete {current} { From b79223064e163aa0ce7f5b63d12158e87f8729e4 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 8 Jul 2007 22:48:19 -0400 Subject: [PATCH 135/213] git-gui: Show a progress meter for checking out files Sometimes switching between branches can take more than a second or two, in which case `git checkout` would normally have shown a small progress meter to the user on the terminal to let them know that we are in fact working, and give them a reasonable idea of when we may finish. We now do obtain that progress meter from read-tree -v and include it in our main window's status bar. This allows users to see how many files we have checked out, how many remain, and what percentage of the operation is completed. It should help to keep users from getting bored during a large checkout operation. Signed-off-by: Shawn O. Pearce --- lib/checkout_op.tcl | 51 +++++++++++++++++++++++++++++++-------------- lib/status_bar.tcl | 22 +++++++++++++++++-- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/lib/checkout_op.tcl b/lib/checkout_op.tcl index 844d8e551c..5d02daac6f 100644 --- a/lib/checkout_op.tcl +++ b/lib/checkout_op.tcl @@ -19,6 +19,7 @@ field create 0; # create the branch if it doesn't exist? field reset_ok 0; # did the user agree to reset? field fetch_ok 0; # did the fetch succeed? +field readtree_d {}; # buffered output from read-tree field update_old {}; # was the update-ref call deferred? field reflog_msg {}; # log message for the update-ref call @@ -309,51 +310,69 @@ method _name {} { method _readtree {} { global HEAD - ui_status "Updating working directory to '[_name $this]'..." + set readtree_d {} + $::main_status start \ + "Updating working directory to '[_name $this]'..." \ + {files checked out} + set cmd [list git read-tree] lappend cmd -m lappend cmd -u + lappend cmd -v lappend cmd --exclude-per-directory=.gitignore lappend cmd $HEAD lappend cmd $new_hash - set fd [open "| $cmd" r] + + if {[catch { + set fd [open "| $cmd 2>@1" r] + } err]} { + # Older versions of Tcl 8.4 don't have this 2>@1 IO + # redirect operator. Fallback to |& cat for those. + # + set fd [open "| $cmd |& cat" r] + } + fconfigure $fd -blocking 0 -translation binary fileevent $fd readable [cb _readtree_wait $fd] } method _readtree_wait {fd} { - global selected_commit_type commit_type HEAD MERGE_HEAD PARENT - global current_branch is_detached - global ui_comm + global current_branch + + set buf [read $fd] + $::main_status update_meter $buf + append readtree_d $buf - # -- We never get interesting output on stdout; only stderr. - # - read $fd fconfigure $fd -blocking 1 if {![eof $fd]} { fconfigure $fd -blocking 0 return } - set name [_name $this] - - # -- The working directory wasn't in sync with the index and - # we'd have to overwrite something to make the switch. A - # merge is required. - # - if {[catch {close $fd} err]} { + if {[catch {close $fd}]} { + set err $readtree_d regsub {^fatal: } $err {} err + $::main_status stop "Aborted checkout of '[_name $this]' (file level merging is required)." warn_popup "File level merge required. $err Staying on branch '$current_branch'." - ui_status "Aborted checkout of '$name' (file level merging is required)." unlock_index delete_this return } + $::main_status stop + _after_readtree $this +} + +method _after_readtree {} { + global selected_commit_type commit_type HEAD MERGE_HEAD PARENT + global current_branch is_detached + global ui_comm + + set name [_name $this] set log "checkout: moving" if {!$is_detached} { append log " from $current_branch" diff --git a/lib/status_bar.tcl b/lib/status_bar.tcl index 0e2ac07a5e..72a8fe1fd3 100644 --- a/lib/status_bar.tcl +++ b/lib/status_bar.tcl @@ -9,6 +9,7 @@ field w_c ; # canvas we draw a progress bar into field status {}; # single line of text we show field prefix {}; # text we format into status field units {}; # unit of progress +field meter {}; # current core git progress meter (if active) constructor new {path} { set w $path @@ -45,6 +46,7 @@ method start {msg uds} { set status $msg set prefix $msg set units $uds + set meter {} } method update {have total} { @@ -58,9 +60,25 @@ method update {have total} { $w_c coords bar 0 0 $pdone 20 } -method stop {msg} { +method update_meter {buf} { + append meter $buf + set r [string last "\r" $meter] + if {$r == -1} { + return + } + + set prior [string range $meter 0 $r] + set meter [string range $meter [expr {$r + 1}] end] + if {[regexp "\\((\\d+)/(\\d+)\\)\\s+done\r\$" $prior _j a b]} { + update $this $a $b + } +} + +method stop {{msg {}}} { destroy $w_c - set status $msg + if {$msg ne {}} { + set status $msg + } } method show {msg {test {}}} { From 0b81261622afad691501ee51d7811048cf4a5fce Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 01:17:09 -0400 Subject: [PATCH 136/213] git-gui: Always use absolute path to all git executables Rather than making the C library search for git every time we want to execute it we now search for the main git wrapper at startup, do symlink resolution, and then always use the absolute path that we found to execute the binary later on. This should save us some cycles, especially on stat challenged systems like Cygwin/Win32. While I was working on this change I also converted all of our existing pipes ([open "| git ..."]) to use two new pipe wrapper functions. These functions take additional options like --nice and --stderr which instructs Tcl to take special action, like running the underlying git program through `nice` (if available) or redirect stderr to stdout for capture in Tcl. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 217 ++++++++++++++++++++++++++++++++--- lib/blame.tcl | 21 ++-- lib/branch.tcl | 7 +- lib/browser.tcl | 3 +- lib/checkout_op.tcl | 39 +++---- lib/commit.tcl | 4 +- lib/database.tcl | 2 +- lib/diff.tcl | 8 +- lib/index.tcl | 18 +-- lib/merge.tcl | 18 +-- lib/option.tcl | 1 + lib/remote.tcl | 2 +- lib/remote_branch_delete.tcl | 2 +- 13 files changed, 258 insertions(+), 84 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index b2c9a9c6a0..09f49ce020 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -117,6 +117,7 @@ set _gitdir {} set _gitexec {} set _reponame {} set _iscygwin {} +set _search_path {} proc appname {} { global _appname @@ -128,7 +129,7 @@ proc gitdir {args} { if {$args eq {}} { return $_gitdir } - return [eval [concat [list file join $_gitdir] $args]] + return [eval [list file join $_gitdir] $args] } proc gitexec {args} { @@ -137,11 +138,19 @@ proc gitexec {args} { if {[catch {set _gitexec [git --exec-path]} err]} { error "Git not installed?\n\n$err" } + if {[is_Cygwin]} { + set _gitexec [exec cygpath \ + --windows \ + --absolute \ + $_gitexec] + } else { + set _gitexec [file normalize $_gitexec] + } } if {$args eq {}} { return $_gitexec } - return [eval [concat [list file join $_gitexec] $args]] + return [eval [list file join $_gitexec] $args] } proc reponame {} { @@ -237,7 +246,7 @@ proc load_config {include_global} { array unset global_config if {$include_global} { catch { - set fd_rc [open "| git config --global --list" r] + set fd_rc [git_read config --global --list] while {[gets $fd_rc line] >= 0} { if {[regexp {^([^=]+)=(.*)$} $line line name value]} { if {[is_many_config $name]} { @@ -253,7 +262,7 @@ proc load_config {include_global} { array unset repo_config catch { - set fd_rc [open "| git config --list" r] + set fd_rc [git_read config --list] while {[gets $fd_rc line] >= 0} { if {[regexp {^([^=]+)=(.*)$} $line line name value]} { if {[is_many_config $name]} { @@ -280,8 +289,172 @@ proc load_config {include_global} { ## ## handy utils +proc _git_cmd {name} { + global _git_cmd_path + + if {[catch {set v $_git_cmd_path($name)}]} { + switch -- $name { + --version - + --exec-path { return [list $::_git $name] } + } + + set p [gitexec git-$name$::_search_exe] + if {[file exists $p]} { + set v [list $p] + } elseif {[is_Cygwin]} { + # On Cygwin git is a proper Cygwin program and knows + # how to properly restart the Cygwin environment and + # spawn its non-.exe support program. + # + set v [list $::_git $name] + } elseif {[is_Windows] + && $::_sh ne {} + && [file exists [gitexec git-$name]]} { + # Assume this is a UNIX shell script. We can + # probably execute it through a Bourne shell. + # + set v [list $::_sh [gitexec git-$name]] + } else { + error "No [gitexec git-$name]" + } + set _git_cmd_path($name) $v + } + return $v +} + +proc _which {what} { + global env _search_exe _search_path + + if {$_search_path eq {}} { + if {[is_Cygwin]} { + set _search_path [split [exec cygpath \ + --windows \ + --path \ + --absolute \ + $env(PATH)] {;}] + set _search_exe .exe + } elseif {[is_Windows]} { + set _search_path [split $env(PATH) {;}] + set _search_exe .exe + } else { + set _search_path [split $env(PATH) :] + set _search_exe {} + } + } + + foreach p $_search_path { + set p [file join $p $what$_search_exe] + if {[file exists $p]} { + return [file normalize $p] + } + } + return {} +} + proc git {args} { - return [eval exec git $args] + set opt [list exec] + + while {1} { + switch -- [lindex $args 0] { + --nice { + global _nice + if {$_nice ne {}} { + lappend opt $_nice + } + } + + default { + break + } + + } + + set args [lrange $args 1 end] + } + + set cmdp [_git_cmd [lindex $args 0]] + set args [lrange $args 1 end] + + return [eval $opt $cmdp $args] +} + +proc git_read {args} { + set opt [list |] + + while {1} { + switch -- [lindex $args 0] { + --nice { + global _nice + if {$_nice ne {}} { + lappend opt $_nice + } + } + + --stderr { + lappend args 2>@1 + } + + default { + break + } + + } + + set args [lrange $args 1 end] + } + + set cmdp [_git_cmd [lindex $args 0]] + set args [lrange $args 1 end] + + if {[catch { + set fd [open [concat $opt $cmdp $args] r] + } err]} { + if { [lindex $args end] eq {2>@1} + && $err eq {can not find channel named "1"} + } { + # Older versions of Tcl 8.4 don't have this 2>@1 IO + # redirect operator. Fallback to |& cat for those. + # The command was not actually started, so its safe + # to try to start it a second time. + # + set fd [open [concat \ + $opt \ + $cmdp \ + [lrange $args 0 end-1] \ + [list |& cat] \ + ] r] + } else { + error $err + } + } + return $fd +} + +proc git_write {args} { + set opt [list |] + + while {1} { + switch -- [lindex $args 0] { + --nice { + global _nice + if {$_nice ne {}} { + lappend opt $_nice + } + } + + default { + break + } + + } + + set args [lrange $args 1 end] + } + + set cmdp [_git_cmd [lindex $args 0]] + set args [lrange $args 1 end] + + return [open [concat $opt $cmdp $args] w] } proc load_current_branch {} { @@ -318,6 +491,19 @@ proc tk_optionMenu {w varName args} { return $m } +###################################################################### +## +## find git + +set _git [_which git] +if {$_git eq {}} { + catch {wm withdraw .} + error_popup "Cannot find git in PATH." + exit 1 +} +set _nice [_which nice] +set _sh [_which sh] + ###################################################################### ## ## version check @@ -566,12 +752,12 @@ proc rescan {after {honor_trustmtime 1}} { } else { set rescan_active 1 ui_status {Refreshing file status...} - set cmd [list git update-index] - lappend cmd -q - lappend cmd --unmerged - lappend cmd --ignore-missing - lappend cmd --refresh - set fd_rf [open "| $cmd" r] + set fd_rf [git_read update-index \ + -q \ + --unmerged \ + --ignore-missing \ + --refresh \ + ] fconfigure $fd_rf -blocking 0 -translation binary fileevent $fd_rf readable \ [list rescan_stage2 $fd_rf $after] @@ -587,8 +773,7 @@ proc rescan_stage2 {fd after} { close $fd } - set ls_others [list | git ls-files --others -z \ - --exclude-per-directory=.gitignore] + set ls_others [list --exclude-per-directory=.gitignore] set info_exclude [gitdir info exclude] if {[file readable $info_exclude]} { lappend ls_others "--exclude-from=$info_exclude" @@ -600,9 +785,9 @@ proc rescan_stage2 {fd after} { set rescan_active 3 ui_status {Scanning for modified files ...} - set fd_di [open "| git diff-index --cached -z [PARENT]" r] - set fd_df [open "| git diff-files -z" r] - set fd_lo [open $ls_others r] + set fd_di [git_read diff-index --cached -z [PARENT]] + set fd_df [git_read diff-files -z] + set fd_lo [eval git_read ls-files --others -z $ls_others] fconfigure $fd_di -blocking 0 -translation binary -encoding binary fconfigure $fd_df -blocking 0 -translation binary -encoding binary diff --git a/lib/blame.tcl b/lib/blame.tcl index 13bfab3352..4bdb9a27a3 100644 --- a/lib/blame.tcl +++ b/lib/blame.tcl @@ -371,8 +371,7 @@ method _load {jump} { if {$commit eq {}} { set fd [open $path r] } else { - set cmd [list git cat-file blob "$commit:$path"] - set fd [open "| $cmd" r] + set fd [git_read cat-file blob "$commit:$path"] } fconfigure $fd -blocking 0 -translation lf -encoding binary fileevent $fd readable [cb _read_file $fd $jump] @@ -475,20 +474,14 @@ method _read_file {fd jump} { } ifdeleted { catch {close $fd} } method _exec_blame {cur_w cur_d options cur_s} { - set cmd [list] - if {![is_Windows] || [is_Cygwin]} { - lappend cmd nice - } - lappend cmd git blame - set cmd [concat $cmd $options] - lappend cmd --incremental + lappend options --incremental if {$commit eq {}} { - lappend cmd --contents $path + lappend options --contents $path } else { - lappend cmd $commit + lappend options $commit } - lappend cmd -- $path - set fd [open "| $cmd" r] + lappend options -- $path + set fd [eval git_read --nice blame $options] fconfigure $fd -blocking 0 -translation lf -encoding binary fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d] set current_fd $fd @@ -767,7 +760,7 @@ method _showcommit {cur_w lno} { if {[catch {set msg $header($cmit,message)}]} { set msg {} catch { - set fd [open "| git cat-file commit $cmit" r] + set fd [git_read cat-file commit $cmit] fconfigure $fd -encoding binary -translation lf if {[catch {set enc $repo_config(i18n.commitencoding)}]} { set enc utf-8 diff --git a/lib/branch.tcl b/lib/branch.tcl index b948d926ae..777eeb79c1 100644 --- a/lib/branch.tcl +++ b/lib/branch.tcl @@ -7,7 +7,7 @@ proc load_all_heads {} { set rh refs/heads set rh_len [expr {[string length $rh] + 1}] set all_heads [list] - set fd [open "| git for-each-ref --format=%(refname) $rh" r] + set fd [git_read for-each-ref --format=%(refname) $rh] while {[gets $fd line] > 0} { if {!$some_heads_tracking || ![is_tracking_branch $line]} { lappend all_heads [string range $line $rh_len end] @@ -20,7 +20,10 @@ proc load_all_heads {} { proc load_all_tags {} { set all_tags [list] - set fd [open "| git for-each-ref --sort=-taggerdate --format=%(refname) refs/tags" r] + set fd [git_read for-each-ref \ + --sort=-taggerdate \ + --format=%(refname) \ + refs/tags] while {[gets $fd line] > 0} { if {![regsub ^refs/tags/ $line {} name]} continue lappend all_tags $name diff --git a/lib/browser.tcl b/lib/browser.tcl index 3d6341bcc5..4d33052ab5 100644 --- a/lib/browser.tcl +++ b/lib/browser.tcl @@ -178,8 +178,7 @@ method _ls {tree_id {name {}}} { lappend browser_stack [list $tree_id $name] $w conf -state disabled - set cmd [list git ls-tree -z $tree_id] - set fd [open "| $cmd" r] + set fd [git_read ls-tree -z $tree_id] fconfigure $fd -blocking 0 -translation binary -encoding binary fileevent $fd readable [cb _read $fd] } diff --git a/lib/checkout_op.tcl b/lib/checkout_op.tcl index 5d02daac6f..00a994be12 100644 --- a/lib/checkout_op.tcl +++ b/lib/checkout_op.tcl @@ -274,12 +274,12 @@ The rescan will be automatically started now. _readtree $this } else { ui_status {Refreshing file status...} - set cmd [list git update-index] - lappend cmd -q - lappend cmd --unmerged - lappend cmd --ignore-missing - lappend cmd --refresh - set fd [open "| $cmd" r] + set fd [git_read update-index \ + -q \ + --unmerged \ + --ignore-missing \ + --refresh \ + ] fconfigure $fd -blocking 0 -translation binary fileevent $fd readable [cb _refresh_wait $fd] } @@ -315,23 +315,14 @@ method _readtree {} { "Updating working directory to '[_name $this]'..." \ {files checked out} - set cmd [list git read-tree] - lappend cmd -m - lappend cmd -u - lappend cmd -v - lappend cmd --exclude-per-directory=.gitignore - lappend cmd $HEAD - lappend cmd $new_hash - - if {[catch { - set fd [open "| $cmd 2>@1" r] - } err]} { - # Older versions of Tcl 8.4 don't have this 2>@1 IO - # redirect operator. Fallback to |& cat for those. - # - set fd [open "| $cmd |& cat" r] - } - + set fd [git_read --stderr read-tree \ + -m \ + -u \ + -v \ + --exclude-per-directory=.gitignore \ + $HEAD \ + $new_hash \ + ] fconfigure $fd -blocking 0 -translation binary fileevent $fd readable [cb _readtree_wait $fd] } @@ -524,7 +515,7 @@ method _confirm_reset {cur} { pack $w.buttons.cancel -side right -padx 5 pack $w.buttons -side bottom -fill x -pady 10 -padx 10 - set fd [open "| git rev-list --pretty=oneline $cur ^$new_hash" r] + set fd [git_read rev-list --pretty=oneline $cur ^$new_hash] while {[gets $fd line] > 0} { set abbr [string range $line 0 7] set subj [string range $line 41 end] diff --git a/lib/commit.tcl b/lib/commit.tcl index d0e4996bae..dc7c88c601 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -25,7 +25,7 @@ You are currently in the middle of a merge that has not been fully completed. Y set msg {} set parents [list] if {[catch { - set fd [open "| git cat-file commit $curHEAD" r] + set fd [git_read cat-file commit $curHEAD] fconfigure $fd -encoding binary -translation lf if {[catch {set enc $repo_config(i18n.commitencoding)}]} { set enc utf-8 @@ -235,7 +235,7 @@ proc commit_prehook_wait {fd_ph curHEAD msg} { proc commit_writetree {curHEAD msg} { ui_status {Committing changes...} - set fd_wt [open "| git write-tree" r] + set fd_wt [git_read write-tree] fileevent $fd_wt readable \ [list commit_committree $fd_wt $curHEAD $msg] } diff --git a/lib/database.tcl b/lib/database.tcl index 43e4a289bb..87c815d7ac 100644 --- a/lib/database.tcl +++ b/lib/database.tcl @@ -2,7 +2,7 @@ # Copyright (C) 2006, 2007 Shawn Pearce proc do_stats {} { - set fd [open "| git count-objects -v" r] + set fd [git_read count-objects -v] while {[gets $fd line] > 0} { if {[regexp {^([^:]+): (\d+)$} $line _ name value]} { set stats($name) $value diff --git a/lib/diff.tcl b/lib/diff.tcl index 05bf75179b..9cb9d0604a 100644 --- a/lib/diff.tcl +++ b/lib/diff.tcl @@ -131,7 +131,7 @@ proc show_diff {path w {lno {}}} { return } - set cmd [list | git] + set cmd [list] if {$w eq $ui_index} { lappend cmd diff-index lappend cmd --cached @@ -154,7 +154,7 @@ proc show_diff {path w {lno {}}} { lappend cmd -- lappend cmd $path - if {[catch {set fd [open $cmd r]} err]} { + if {[catch {set fd [eval git_read --nice $cmd]} err]} { set diff_active 0 unlock_index ui_status "Unable to display [escape_path $path]" @@ -271,7 +271,7 @@ proc apply_hunk {x y} { if {$current_diff_path eq {} || $current_diff_header eq {}} return if {![lock_index apply_hunk]} return - set apply_cmd {git apply --cached --whitespace=nowarn} + set apply_cmd {apply --cached --whitespace=nowarn} set mi [lindex $file_states($current_diff_path) 0] if {$current_diff_side eq $ui_index} { set mode unstage @@ -301,7 +301,7 @@ proc apply_hunk {x y} { } if {[catch { - set p [open "| $apply_cmd" w] + set p [eval git_write $apply_cmd] fconfigure $p -translation binary -encoding binary puts -nonewline $p $current_diff_header puts -nonewline $p [$ui_diff get $s_lno $e_lno] diff --git a/lib/index.tcl b/lib/index.tcl index 7c175a96a6..3ea72e1ec9 100644 --- a/lib/index.tcl +++ b/lib/index.tcl @@ -17,7 +17,7 @@ proc update_indexinfo {msg pathList after} { $update_index_cp \ $totalCnt \ 0.0] - set fd [open "| git update-index -z --index-info" w] + set fd [git_write update-index -z --index-info] fconfigure $fd \ -blocking 0 \ -buffering full \ @@ -90,7 +90,7 @@ proc update_index {msg pathList after} { $update_index_cp \ $totalCnt \ 0.0] - set fd [open "| git update-index --add --remove -z --stdin" w] + set fd [git_write update-index --add --remove -z --stdin] fconfigure $fd \ -blocking 0 \ -buffering full \ @@ -167,13 +167,13 @@ proc checkout_index {msg pathList after} { $update_index_cp \ $totalCnt \ 0.0] - set cmd [list git checkout-index] - lappend cmd --index - lappend cmd --quiet - lappend cmd --force - lappend cmd -z - lappend cmd --stdin - set fd [open "| $cmd " w] + set fd [git_write checkout-index \ + --index \ + --quiet \ + --force \ + -z \ + --stdin \ + ] fconfigure $fd \ -blocking 0 \ -buffering full \ diff --git a/lib/merge.tcl b/lib/merge.tcl index f0a02ea228..288d7ac889 100644 --- a/lib/merge.tcl +++ b/lib/merge.tcl @@ -146,7 +146,7 @@ The working directory will now be reset. You can attempt this merge again by merging only one branch at a time." $w - set fd [open "| git read-tree --reset -u HEAD" r] + set fd [git_read read-tree --reset -u HEAD] fconfigure $fd -blocking 0 -translation binary fileevent $fd readable \ [namespace code [list _reset_wait $fd]] @@ -167,11 +167,13 @@ proc dialog {} { if {![_can_merge]} return set fmt {list %(objectname) %(*objectname) %(refname) %(subject)} - set cmd [list git for-each-ref --tcl --format=$fmt] - lappend cmd refs/heads - lappend cmd refs/remotes - lappend cmd refs/tags - set fr_fd [open "| $cmd" r] + set fr_fd [git_read for-each-ref \ + --tcl \ + --format=$fmt \ + refs/heads \ + refs/remotes \ + refs/tags \ + ] fconfigure $fr_fd -translation binary while {[gets $fr_fd line] > 0} { set line [eval $line] @@ -186,7 +188,7 @@ proc dialog {} { close $fr_fd set to_show {} - set fr_fd [open "| git rev-list --all --not HEAD"] + set fr_fd [git_read rev-list --all --not HEAD] while {[gets $fr_fd line] > 0} { if {[catch {set ref $sha1($line)}]} continue foreach n $ref { @@ -282,7 +284,7 @@ You must finish amending this commit. Aborting the current $op will cause *ALL* uncommitted changes to be lost. Continue with aborting the current $op?"] eq {yes}} { - set fd [open "| git read-tree --reset -u HEAD" r] + set fd [git_read read-tree --reset -u HEAD] fconfigure $fd -blocking 0 -translation binary fileevent $fd readable [namespace code [list _reset_wait $fd]] ui_status {Aborting... please wait...} diff --git a/lib/option.tcl b/lib/option.tcl index 743304269b..aa9f783afd 100644 --- a/lib/option.tcl +++ b/lib/option.tcl @@ -95,6 +95,7 @@ $copyright" \ } set d {} + append d "git wrapper: $::_git\n" append d "git exec dir: [gitexec]\n" append d "git-gui lib: $oguilib" diff --git a/lib/remote.tcl b/lib/remote.tcl index fabec05fff..e235ca8876 100644 --- a/lib/remote.tcl +++ b/lib/remote.tcl @@ -32,7 +32,7 @@ proc all_tracking_branches {} { } if {$pat ne {}} { - set fd [open "| git for-each-ref --format=%(refname) $cmd" r] + set fd [eval git_read for-each-ref --format=%(refname) $cmd] while {[gets $fd n] > 0} { foreach spec $pat { set dst [string range [lindex $spec 0] 0 end-2] diff --git a/lib/remote_branch_delete.tcl b/lib/remote_branch_delete.tcl index d7e2b8db45..c88a360db5 100644 --- a/lib/remote_branch_delete.tcl +++ b/lib/remote_branch_delete.tcl @@ -296,7 +296,7 @@ method _load {cache uri} { set full_list [list] set head_cache($cache) [list] set full_cache($cache) [list] - set active_ls [open "| [list git ls-remote $uri]" r] + set active_ls [git_read ls-remote $uri] fconfigure $active_ls \ -blocking 0 \ -translation lf \ From 02efd48f520d14012fc82c999172306a94862dee Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 02:10:39 -0400 Subject: [PATCH 137/213] git-gui: Correct gitk installation location The master Makefile in git.git installs gitk into bindir, not gitexecdir, which means gitk is located as a sibling of the git wrapper and not as though it were a git helper tool. We can also avoid some Tcl concat operations by letting eval do all of the heavy lifting; we have two proper Tcl lists ($cmd and $revs) that we are joining together and $revs is currently never an empty list. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 09f49ce020..53cf89876f 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1303,24 +1303,16 @@ proc incr_font_size {font {amt 1}} { set starting_gitk_msg {Starting gitk... please wait...} proc do_gitk {revs} { - global env starting_gitk_msg - # -- Always start gitk through whatever we were loaded with. This # lets us bypass using shell process on Windows systems. # - set cmd [list [info nameofexecutable]] - set exe [gitexec gitk] - lappend cmd $exe - if {$revs ne {}} { - append cmd { } - append cmd $revs - } - + set exe [file join [file dirname $::_git] gitk] + set cmd [list [info nameofexecutable] $exe] if {! [file exists $exe]} { error_popup "Unable to start gitk:\n\n$exe does not exist" } else { - eval exec $cmd & - ui_status $starting_gitk_msg + eval exec $cmd $revs & + ui_status $::starting_gitk_msg after 10000 { ui_ready $starting_gitk_msg } From c67298902ca36579b4cc43c1868cdb41279ef21b Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 02:13:00 -0400 Subject: [PATCH 138/213] git-gui: Assume unfound commands are known by git wrapper If we cannot locate a command in $gitexecdir on our own then it may just be because we are supposed to run it by `git $name` rather than by `git-$name`. Many commands are now builtins, more are likely to go in that direction, and we may see the hardlinks in $gitexecdir go away in future versions of git. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/git-gui.sh b/git-gui.sh index 53cf89876f..9b342f0846 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -315,7 +315,10 @@ proc _git_cmd {name} { # set v [list $::_sh [gitexec git-$name]] } else { - error "No [gitexec git-$name]" + # Assume it is builtin to git somehow and we + # aren't actually able to see a file for it. + # + set v [list $::_git $name] } set _git_cmd_path($name) $v } From 11d6596709e04b8d2b429f230b2ed570d013f812 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 8 Jul 2007 19:03:19 -0700 Subject: [PATCH 139/213] revision.c: remove duplicated parents after history simplification When we simplify history due to path limits, the parents list for a rewritten commit can end up having duplicates. Instead of filtering them out in the output codepath like earlier commit 88494423 did, remove them much earlier, when the parent information actually gets rewritten. Signed-off-by: Junio C Hamano --- revision.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/revision.c b/revision.c index 5184716bf0..33ee9ee3b2 100644 --- a/revision.c +++ b/revision.c @@ -1308,6 +1308,25 @@ static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp } } +static void remove_duplicate_parents(struct commit *commit) +{ + struct commit_list *p; + struct commit_list **pp = &commit->parents; + + /* Examine existing parents while marking ones we have seen... */ + for (p = commit->parents; p; p = p->next) { + struct commit *parent = p->item; + if (parent->object.flags & TMP_MARK) + continue; + parent->object.flags |= TMP_MARK; + *pp = p; + pp = &p->next; + } + /* ... and clear the temporary mark */ + for (p = commit->parents; p; p = p->next) + p->item->object.flags &= ~TMP_MARK; +} + static int rewrite_parents(struct rev_info *revs, struct commit *commit) { struct commit_list **pp = &commit->parents; @@ -1324,6 +1343,7 @@ static int rewrite_parents(struct rev_info *revs, struct commit *commit) } pp = &parent->next; } + remove_duplicate_parents(commit); return 0; } From 1ed84157a21a3e868228b15588e4aadfbe5a030b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 8 Jul 2007 19:05:31 -0700 Subject: [PATCH 140/213] Revert 88494423 (removal of duplicate parents in the output codepath) Now this is not needed, as we rewrite the parent list in the commit object itself. Signed-off-by: Junio C Hamano --- builtin-rev-list.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/builtin-rev-list.c b/builtin-rev-list.c index 86db8b03fe..8efd609b12 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -70,21 +70,9 @@ static void show_commit(struct commit *commit) if (revs.parents) { struct commit_list *parents = commit->parents; while (parents) { - struct object *o = &(parents->item->object); + printf(" %s", sha1_to_hex(parents->item->object.sha1)); parents = parents->next; - if (o->flags & TMP_MARK) - continue; - printf(" %s", sha1_to_hex(o->sha1)); - o->flags |= TMP_MARK; } - /* TMP_MARK is a general purpose flag that can - * be used locally, but the user should clean - * things up after it is done with them. - */ - for (parents = commit->parents; - parents; - parents = parents->next) - parents->item->object.flags &= ~TMP_MARK; } if (revs.commit_format == CMIT_FMT_ONELINE) putchar(' '); From 70a7595cc07f38d4a83dff1d4697eb49c2e65b2c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 02:30:24 -0400 Subject: [PATCH 141/213] git-gui: Treat `git version` as `git --version` We know that the version subcommand of git is special. It does not currently have an executable link installed into $gitexecdir and we therefore would never match it with one of our file exists tests. So we forward any invocations to it directly to the git wrapper, as it is a builtin within that executable. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/git-gui.sh b/git-gui.sh index 9b342f0846..a3ac5daf14 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -294,6 +294,7 @@ proc _git_cmd {name} { if {[catch {set v $_git_cmd_path($name)}]} { switch -- $name { + version - --version - --exec-path { return [list $::_git $name] } } From c136f2b8b9eaac7a702799de25648b74ef12618a Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 02:47:33 -0400 Subject: [PATCH 142/213] git-gui: Perform our own magic shbang detection on Windows If we cannot locate a .exe for a git tool that we want to run than it may just be a Bourne shell script as these are popular in Git. In such a case the first line of the file will say "#!/bin/sh" so a UNIX kernel knows what program to start to parse and run that. But Windows doesn't support shbang lines, and neither does the Tcl that comes with Cygwin. We can pass control off to the git wrapper as that is a real Cygwin program and can therefore start the Bourne shell script, but that is at least two fork+exec calls to get the program running. One to do the fork+exec of the git wrapper and another to start the Bourne shell script. If the program is run multiple times it is rather expensive as the magic shbang detection won't be cached across executions. On MinGW/MSYS we don't have the luxury of such magic detection. The MSYS team has taught some of this magic to the git wrapper, but again its slower than it needs to be as the git wrapper must still go and run the Bourne shell after it is called. We now attempt to guess the shbang line on Windows by reading the first line of the file and building our own command line path from it. Currently we support Bourne shell (sh), Perl and Python. That is the entire set of shbang lines that appear in git.git today. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index a3ac5daf14..7e6952c2bc 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -302,19 +302,31 @@ proc _git_cmd {name} { set p [gitexec git-$name$::_search_exe] if {[file exists $p]} { set v [list $p] - } elseif {[is_Cygwin]} { - # On Cygwin git is a proper Cygwin program and knows - # how to properly restart the Cygwin environment and - # spawn its non-.exe support program. + } elseif {[is_Windows] && [file exists [gitexec git-$name]]} { + # Try to determine what sort of magic will make + # git-$name go and do its thing, because native + # Tcl on Windows doesn't know it. # - set v [list $::_git $name] - } elseif {[is_Windows] - && $::_sh ne {} - && [file exists [gitexec git-$name]]} { - # Assume this is a UNIX shell script. We can - # probably execute it through a Bourne shell. - # - set v [list $::_sh [gitexec git-$name]] + set p [gitexec git-$name] + set f [open $p r] + set s [gets $f] + close $f + + switch -glob -- $s { + #!*sh { set i sh } + #!*perl { set i perl } + #!*python { set i python } + default { error "git-$name is not supported: $s" } + } + + upvar #0 _$i interp + if {![info exists interp]} { + set interp [_which $i] + } + if {$interp eq {}} { + error "git-$name requires $i (not in PATH)" + } + set v [list $interp $p] } else { # Assume it is builtin to git somehow and we # aren't actually able to see a file for it. @@ -506,7 +518,6 @@ if {$_git eq {}} { exit 1 } set _nice [_which nice] -set _sh [_which sh] ###################################################################### ## From 848d732c10616269886d0b9c82e434b65ffc33f0 Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Sun, 8 Jul 2007 23:45:21 -0500 Subject: [PATCH 143/213] pack-objects: Prefer shallower deltas if the size is equal Change "try_delta" so that if it finds a delta that has the same size but shallower depth than the existing delta, it will prefer the shallower one. This makes certain delta trees vastly less deep. Signed-off-by: Brian Downing Signed-off-by: Junio C Hamano --- builtin-pack-objects.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 3d396ca37a..54b9d268da 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1337,7 +1337,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, if (max_size == 0) return 0; if (trg_entry->delta && trg_entry->delta_size <= max_size) - max_size = trg_entry->delta_size-1; + max_size = trg_entry->delta_size; src_size = src_entry->size; sizediff = src_size < trg_size ? trg_size - src_size : 0; if (sizediff >= max_size) @@ -1371,6 +1371,12 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, return 0; if (trg_entry->delta_data) { + /* Prefer only shallower same-sized deltas. */ + if (delta_size == trg_entry->delta_size && + src_entry->depth + 1 >= trg_entry->depth) { + free(delta_buf); + return 0; + } delta_cache_size -= trg_entry->delta_size; free(trg_entry->delta_data); } From 74c4763c76a111809747652210962ad09896b74f Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 03:07:05 -0400 Subject: [PATCH 144/213] git-gui: Teach console widget to use git_read Now that we are pretty strict about setting up own absolute paths to any git helper (saving a marginal runtime cost to resolve the tool) we can do the same in our console widget by making sure all console execs go through git_read if they are a git subcommand, and if not make sure they at least try to use the Tcl 2>@1 IO redirection if possible, as it should be faster than |& cat. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 46 ++++++++++++++++++++++++---------------------- lib/console.tcl | 17 +++++------------ 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 7e6952c2bc..3efecdd962 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -394,6 +394,29 @@ proc git {args} { return [eval $opt $cmdp $args] } +proc _open_stdout_stderr {cmd} { + if {[catch { + set fd [open $cmd r] + } err]} { + if { [lindex $cmd end] eq {2>@1} + && $err eq {can not find channel named "1"} + } { + # Older versions of Tcl 8.4 don't have this 2>@1 IO + # redirect operator. Fallback to |& cat for those. + # The command was not actually started, so its safe + # to try to start it a second time. + # + set fd [open [concat \ + [lrange $cmd 0 end-1] \ + [list |& cat] \ + ] r] + } else { + error $err + } + } + return $fd +} + proc git_read {args} { set opt [list |] @@ -422,28 +445,7 @@ proc git_read {args} { set cmdp [_git_cmd [lindex $args 0]] set args [lrange $args 1 end] - if {[catch { - set fd [open [concat $opt $cmdp $args] r] - } err]} { - if { [lindex $args end] eq {2>@1} - && $err eq {can not find channel named "1"} - } { - # Older versions of Tcl 8.4 don't have this 2>@1 IO - # redirect operator. Fallback to |& cat for those. - # The command was not actually started, so its safe - # to try to start it a second time. - # - set fd [open [concat \ - $opt \ - $cmdp \ - [lrange $args 0 end-1] \ - [list |& cat] \ - ] r] - } else { - error $err - } - } - return $fd + return [_open_stdout_stderr [concat $opt $cmdp $args]] } proc git_write {args} { diff --git a/lib/console.tcl b/lib/console.tcl index 27a880e408..03d0354d5e 100644 --- a/lib/console.tcl +++ b/lib/console.tcl @@ -87,19 +87,12 @@ method _init {} { } method exec {cmd {after {}}} { - # -- Cygwin's Tcl tosses the enviroment when we exec our child. - # But most users need that so we have to relogin. :-( - # - if {[is_Cygwin]} { - set cmd [list sh --login -c "cd \"[pwd]\" && [join $cmd { }]"] + if {[lindex $cmd 0] eq {git}} { + set fd_f [eval git_read --stderr [lrange $cmd 1 end]] + } else { + lappend cmd 2>@1 + set fd_f [_open_stdout_stderr $cmd] } - - # -- Tcl won't let us redirect both stdout and stderr to - # the same pipe. So pass it through cat... - # - set cmd [concat | $cmd |& cat] - - set fd_f [open $cmd r] fconfigure $fd_f -blocking 0 -translation binary fileevent $fd_f readable [cb _read $fd_f $after] } From 7eafa2f1578e605e1e68d8ccba9d600cc6b89173 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 03:28:41 -0400 Subject: [PATCH 145/213] git-gui: Improve the Windows and Mac OS X shortcut creators We now embed any GIT_* and SSH_* environment variables as well as the path to the git wrapper executable into the Mac OS X .app file. This should allow us to restore the environment properly when we restart. We also try to use proper Bourne shell single quoting when we can, as this avoids any sort of problems that might occur due to a path containing shell metacharacters. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 5 +++++ lib/shortcut.tcl | 47 ++++++++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 3efecdd962..2077261e64 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -475,6 +475,11 @@ proc git_write {args} { return [open [concat $opt $cmdp $args] w] } +proc sq {value} { + regsub -all ' $value "'\\''" value + return "'$value'" +} + proc load_current_branch {} { global current_branch is_detached diff --git a/lib/shortcut.tcl b/lib/shortcut.tcl index a0a1b7dddd..64ced9d801 100644 --- a/lib/shortcut.tcl +++ b/lib/shortcut.tcl @@ -13,10 +13,11 @@ proc do_windows_shortcut {} { set fn ${fn}.bat } if {[catch { + set ge [file normalize [file dirname $::_git]] set fd [open $fn w] puts $fd "@ECHO Entering [reponame]" puts $fd "@ECHO Starting git-gui... please wait..." - puts $fd "@SET PATH=[file normalize [gitexec]];%PATH%" + puts $fd "@SET PATH=$ge;%PATH%" puts $fd "@SET GIT_DIR=[file normalize [gitdir]]" puts -nonewline $fd "@\"[info nameofexecutable]\"" puts $fd " \"[file normalize $argv0]\"" @@ -62,17 +63,11 @@ proc do_cygwin_shortcut {} { --unix \ --absolute \ [gitdir]] - set gw [exec cygpath \ - --windows \ - --absolute \ - [file dirname [gitdir]]] - regsub -all ' $me "'\\''" me - regsub -all ' $gd "'\\''" gd - puts $fd "@ECHO Entering $gw" + puts $fd "@ECHO Entering [reponame]" puts $fd "@ECHO Starting git-gui... please wait..." puts -nonewline $fd "@\"$sh\" --login -c \"" - puts -nonewline $fd "GIT_DIR='$gd'" - puts -nonewline $fd " '$me'" + puts -nonewline $fd "GIT_DIR=[sq [$gd]]" + puts -nonewline $fd " [sq $me]" puts $fd "&\"" close $fd } err]} { @@ -90,6 +85,9 @@ proc do_macosx_app {} { -initialdir [file join $env(HOME) Desktop] \ -initialfile "Git [reponame].app"] if {$fn != {}} { + if {[file extension $fn] ne {.app}} { + set fn ${fn}.app + } if {[catch { set Contents [file join $fn Contents] set MacOS [file join $Contents MacOS] @@ -123,20 +121,27 @@ proc do_macosx_app {} { close $fd set fd [open $exe w] - set gd [file normalize [gitdir]] - set ep [file normalize [gitexec]] - regsub -all ' $gd "'\\''" gd - regsub -all ' $ep "'\\''" ep puts $fd "#!/bin/sh" - foreach name [array names env] { - if {[string match GIT_* $name]} { - regsub -all ' $env($name) "'\\''" v - puts $fd "export $name='$v'" + foreach name [lsort [array names env]] { + set value $env($name) + switch -- $name { + GIT_DIR { set value [file normalize [gitdir]] } + } + + switch -glob -- $name { + SSH_* - + GIT_* { + puts $fd "if test \"z\$$name\" = z; then" + puts $fd " export $name=[sq $value]" + puts $fd "fi &&" + } } } - puts $fd "export PATH='$ep':\$PATH" - puts $fd "export GIT_DIR='$gd'" - puts $fd "exec [file normalize $argv0]" + puts $fd "export PATH=[sq [file dirname $::_git]]:\$PATH &&" + puts $fd "cd [sq [file normalize [pwd]]] &&" + puts $fd "exec \\" + puts $fd " [sq [info nameofexecutable]] \\" + puts $fd " [sq [file normalize $argv0]]" close $fd file attributes $exe -permissions u+x,g+x,o+x From 096e96b493bfc30687c87b303b93e75864942786 Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Thu, 5 Jul 2007 06:33:02 -0500 Subject: [PATCH 146/213] [PATCH] gitk: Fix for tree view ending in nested directories Unroll the prefix stack when assigning treeheights when leaving proc treeview. Previously, when the ls-tree output ended in multiple nested directories (for instance in a repository with a single file "foo/bar/baz"), $treeheight("foo/bar/") was assigned twice, and $treeheight("foo/") was never assigned. This led to an error when expanding the "foo" directory in the gitk treeview. Signed-off-by: Brian Downing Signed-off-by: Paul Mackerras --- gitk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gitk b/gitk index 45e16e4fd5..28a6bac3aa 100755 --- a/gitk +++ b/gitk @@ -1216,6 +1216,9 @@ proc treeview {w l openlevs} { set treeheight($prefix) $ht incr ht [lindex $htstack end] set htstack [lreplace $htstack end end] + set prefixend [lindex $prefendstack end] + set prefendstack [lreplace $prefendstack end end] + set prefix [string range $prefix 0 $prefixend] } $w conf -state disabled } From 8c93917d23ec7ef998154a6b2ac91ed1a1bf5e3a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 9 Jul 2007 22:29:24 +1000 Subject: [PATCH 147/213] gitk: Fix bug causing "can't read commitrow(0,n)" error In commit 66e46f37de3ed3211a8ae0e8fc09c063bc3a1e08 I changed gitk to store ids in rowrangelist and idrowranges rather than row numbers, but I missed two places in the layouttail procedure. This resulted in occasional errors such as the "can't read "commitrow(0,8572)": no such element in array" error reported by Mark Levedahl. This fixes it by using the id rather than the row number. Signed-off-by: Paul Mackerras --- gitk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitk b/gitk index 28a6bac3aa..ee818647c4 100755 --- a/gitk +++ b/gitk @@ -2885,7 +2885,7 @@ proc layouttail {} { set id [lindex $idlist $col] addextraid $id $row unset idinlist($id) - lappend idrowranges($id) $row + lappend idrowranges($id) $id lappend rowrangelist $idrowranges($id) unset idrowranges($id) incr row @@ -2901,7 +2901,7 @@ proc layouttail {} { lset rowidlist $row [list $id] lset rowoffsets $row 0 makeuparrow $id 0 $row 0 - lappend idrowranges($id) $row + lappend idrowranges($id) $id lappend rowrangelist $idrowranges($id) unset idrowranges($id) incr row From c961b228bcab390a1b42d517b6ed5a1edb55efed Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 9 Jul 2007 22:45:47 +1000 Subject: [PATCH 148/213] gitk: Use git log and add support for --left-right This is based on patches from Linus Torvalds and Junio Hamano, so the ideas here are theirs. This makes gitk use "git log -z --pretty=raw" instead of "git rev-list" to generate the list of commits, and also makes it grok the "<" and ">" markers that git log (and git rev-list) output with the --left-right flag to indicate which side of a symmetric diff a commit is reachable from. Left-side commits are drawn with a triangle pointing leftwards instead of a circle, and right-side commits are drawn with a triangle pointing rightwards. The commitlisted list is used to store the left/right information as well as the information about whether each commit is on the boundary. Signed-off-by: Paul Mackerras --- gitk | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/gitk b/gitk index ee818647c4..468cf32228 100755 --- a/gitk +++ b/gitk @@ -96,8 +96,8 @@ proc start_rev_list {view} { set order "--date-order" } if {[catch { - set fd [open [concat | git rev-list --header $order \ - --parents --boundary --default HEAD $args] r] + set fd [open [concat | git log -z --pretty=raw $order \ + --parents --boundary $args] r] } err]} { puts stderr "Error executing git rev-list: $err" exit 1 @@ -194,10 +194,14 @@ proc getcommitlines {fd view} { set j [string first "\n" $cmit] set ok 0 set listed 1 - if {$j >= 0} { - set ids [string range $cmit 0 [expr {$j - 1}]] - if {[string range $ids 0 0] == "-"} { - set listed 0 + if {$j >= 0 && [string match "commit *" $cmit]} { + set ids [string range $cmit 7 [expr {$j - 1}]] + if {[string match {[-<>]*} $ids]} { + switch -- [string index $ids 0] { + "-" {set listed 0} + "<" {set listed 2} + ">" {set listed 3} + } set ids [string range $ids 1 end] } set ok 1 @@ -213,7 +217,7 @@ proc getcommitlines {fd view} { if {[string length $shortcmit] > 80} { set shortcmit "[string range $shortcmit 0 80]..." } - error_popup "Can't parse git rev-list output: {$shortcmit}" + error_popup "Can't parse git log output: {$shortcmit}" exit 1 } set id [lindex $ids 0] @@ -3334,23 +3338,41 @@ proc drawlines {id} { } proc drawcmittext {id row col} { - global linespc canv canv2 canv3 canvy0 fgcolor + global linespc canv canv2 canv3 canvy0 fgcolor curview global commitlisted commitinfo rowidlist parentlist global rowtextx idpos idtags idheads idotherrefs global linehtag linentag linedtag markingmatches global mainfont canvxmax boldrows boldnamerows fgcolor nullid + # listed is 0 for boundary, 1 for normal, 2 for left, 3 for right + set listed [lindex $commitlisted $row] if {$id eq $nullid} { set ofill red } else { - set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}] + set ofill [expr {$listed != 0? "blue": "white"}] } set x [xc $row $col] set y [yc $row] set orad [expr {$linespc / 3}] - set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \ - [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \ - -fill $ofill -outline $fgcolor -width 1 -tags circle] + if {$listed <= 1} { + set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \ + [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \ + -fill $ofill -outline $fgcolor -width 1 -tags circle] + } elseif {$listed == 2} { + # triangle pointing left for left-side commits + set t [$canv create polygon \ + [expr {$x - $orad}] $y \ + [expr {$x + $orad - 1}] [expr {$y - $orad}] \ + [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \ + -fill $ofill -outline $fgcolor -width 1 -tags circle] + } else { + # triangle pointing right for right-side commits + set t [$canv create polygon \ + [expr {$x + $orad - 1}] $y \ + [expr {$x - $orad}] [expr {$y - $orad}] \ + [expr {$x - $orad}] [expr {$y + $orad - 1}] \ + -fill $ofill -outline $fgcolor -width 1 -tags circle] + } $canv raise $t $canv bind $t <1> {selcanvline {} %x %y} set rmx [llength [lindex $rowidlist $row]] From 5922446794ee1bfcd4bede739467211cd46aa005 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 11:01:02 -0400 Subject: [PATCH 149/213] git-gui: Paper bag fix for Cygwin shortcut creation We cannot execute the git directory, it is not a valid Tcl command name. Instead we just want to pass it as an argument to our sq proc. Signed-off-by: Shawn O. Pearce --- lib/shortcut.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shortcut.tcl b/lib/shortcut.tcl index 64ced9d801..7086162476 100644 --- a/lib/shortcut.tcl +++ b/lib/shortcut.tcl @@ -66,7 +66,7 @@ proc do_cygwin_shortcut {} { puts $fd "@ECHO Entering [reponame]" puts $fd "@ECHO Starting git-gui... please wait..." puts -nonewline $fd "@\"$sh\" --login -c \"" - puts -nonewline $fd "GIT_DIR=[sq [$gd]]" + puts -nonewline $fd "GIT_DIR=[sq $gd]" puts -nonewline $fd " [sq $me]" puts $fd "&\"" close $fd From 6a5955fac3bd5a1369e73512b9606769f0c95e7c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 11:09:27 -0400 Subject: [PATCH 150/213] git-gui: Use sh.exe in Cygwin shortcuts Because we are trying to execute /bin/sh we know it must be a real Windows executable and thus ends with the standard .exe suffix. Signed-off-by: Shawn O. Pearce --- lib/shortcut.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shortcut.tcl b/lib/shortcut.tcl index 7086162476..26adb99821 100644 --- a/lib/shortcut.tcl +++ b/lib/shortcut.tcl @@ -54,7 +54,7 @@ proc do_cygwin_shortcut {} { set sh [exec cygpath \ --windows \ --absolute \ - /bin/sh] + /bin/sh.exe] set me [exec cygpath \ --unix \ --absolute \ From 264f4a32fa898a47e37ccb6f2580746d6f36453f Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 11:10:26 -0400 Subject: [PATCH 151/213] git-gui: Include a space in Cygwin shortcut command lines Signed-off-by: Shawn O. Pearce --- lib/shortcut.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shortcut.tcl b/lib/shortcut.tcl index 26adb99821..c36be2f3cd 100644 --- a/lib/shortcut.tcl +++ b/lib/shortcut.tcl @@ -68,7 +68,7 @@ proc do_cygwin_shortcut {} { puts -nonewline $fd "@\"$sh\" --login -c \"" puts -nonewline $fd "GIT_DIR=[sq $gd]" puts -nonewline $fd " [sq $me]" - puts $fd "&\"" + puts $fd " &\"" close $fd } err]} { error_popup "Cannot write script:\n\n$err" From f39a946a1fb0fa4856cd0027b9da3603a1b06fdc Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 9 Jul 2007 22:58:23 -0400 Subject: [PATCH 152/213] Support wholesale directory renames in fast-import Some source material (e.g. Subversion dump files) perform directory renames without telling us exactly which files in that subdirectory were moved. This makes it hard for a frontend to convert such data formats to a fast-import stream, as all the frontend has on hand is "Rename a/ to b/" with no details about what files are in a/, unless the frontend also kept track of all files. The new 'R' subcommand within a commit allows the frontend to rename either a file or an entire subdirectory, without needing to know the object's SHA-1 or the specific files contained within it. The rename is performed as efficiently as possible internally, making it cheaper than a 'D'/'M' pair for a file rename. Signed-off-by: Shawn O. Pearce --- Documentation/git-fast-import.txt | 28 +++++++++- fast-import.c | 91 +++++++++++++++++++++++++------ t/t9300-fast-import.sh | 68 +++++++++++++++++++++++ 3 files changed, 168 insertions(+), 19 deletions(-) diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index c66af7c876..80a8ee0f1c 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -302,7 +302,7 @@ change to the project. data ('from' SP LF)? ('merge' SP LF)? - (filemodify | filedelete | filedeleteall)* + (filemodify | filedelete | filerename | filedeleteall)* LF .... @@ -325,11 +325,13 @@ commit message use a 0 length data. Commit messages are free-form and are not interpreted by Git. Currently they must be encoded in UTF-8, as fast-import does not permit other encodings to be specified. -Zero or more `filemodify`, `filedelete` and `filedeleteall` commands +Zero or more `filemodify`, `filedelete`, `filename` and +`filedeleteall` commands may be included to update the contents of the branch prior to creating the commit. These commands may be supplied in any order. However it is recommended that a `filedeleteall` command preceed -all `filemodify` commands in the same commit, as `filedeleteall` +all `filemodify` and `filerename` commands in the same commit, as +`filedeleteall` wipes the branch clean (see below). `author` @@ -495,6 +497,26 @@ here `` is the complete path of the file or subdirectory to be removed from the branch. See `filemodify` above for a detailed description of ``. +`filerename` +^^^^^^^^^^^^ +Renames an existing file or subdirectory to a different location +within the branch. The existing file or directory must exist. If +the destination exists it will be replaced by the source directory. + +.... + 'R' SP SP LF +.... + +here the first `` is the source location and the second +`` is the destination. See `filemodify` above for a detailed +description of what `` may look like. To use a source path +that contains SP the path must be quoted. + +A `filerename` command takes effect immediately. Once the source +location has been renamed to the destination any future commands +applied to the source location will create new files there and not +impact the destination of the rename. + `filedeleteall` ^^^^^^^^^^^^^^^ Included in a `commit` command to remove all files (and also all diff --git a/fast-import.c b/fast-import.c index f9bfcc72c8..a1cb13f09b 100644 --- a/fast-import.c +++ b/fast-import.c @@ -26,9 +26,10 @@ Format of STDIN stream: lf; commit_msg ::= data; - file_change ::= file_clr | file_del | file_obm | file_inm; + file_change ::= file_clr | file_del | file_rnm | file_obm | file_inm; file_clr ::= 'deleteall' lf; file_del ::= 'D' sp path_str lf; + file_rnm ::= 'R' sp path_str sp path_str lf; file_obm ::= 'M' sp mode sp (hexsha1 | idnum) sp path_str lf; file_inm ::= 'M' sp mode sp 'inline' sp path_str lf data; @@ -1154,7 +1155,8 @@ static int tree_content_set( struct tree_entry *root, const char *p, const unsigned char *sha1, - const uint16_t mode) + const uint16_t mode, + struct tree_content *subtree) { struct tree_content *t = root->tree; const char *slash1; @@ -1168,20 +1170,22 @@ static int tree_content_set( n = strlen(p); if (!n) die("Empty path component found in input"); + if (!slash1 && !S_ISDIR(mode) && subtree) + die("Non-directories cannot have subtrees"); for (i = 0; i < t->entry_count; i++) { e = t->entries[i]; if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) { if (!slash1) { - if (e->versions[1].mode == mode + if (!S_ISDIR(mode) + && e->versions[1].mode == mode && !hashcmp(e->versions[1].sha1, sha1)) return 0; e->versions[1].mode = mode; hashcpy(e->versions[1].sha1, sha1); - if (e->tree) { + if (e->tree) release_tree_content_recursive(e->tree); - e->tree = NULL; - } + e->tree = subtree; hashclr(root->versions[1].sha1); return 1; } @@ -1191,7 +1195,7 @@ static int tree_content_set( } if (!e->tree) load_tree(e); - if (tree_content_set(e, slash1 + 1, sha1, mode)) { + if (tree_content_set(e, slash1 + 1, sha1, mode, subtree)) { hashclr(root->versions[1].sha1); return 1; } @@ -1209,9 +1213,9 @@ static int tree_content_set( if (slash1) { e->tree = new_tree_content(8); e->versions[1].mode = S_IFDIR; - tree_content_set(e, slash1 + 1, sha1, mode); + tree_content_set(e, slash1 + 1, sha1, mode, subtree); } else { - e->tree = NULL; + e->tree = subtree; e->versions[1].mode = mode; hashcpy(e->versions[1].sha1, sha1); } @@ -1219,7 +1223,10 @@ static int tree_content_set( return 1; } -static int tree_content_remove(struct tree_entry *root, const char *p) +static int tree_content_remove( + struct tree_entry *root, + const char *p, + struct tree_entry *backup_leaf) { struct tree_content *t = root->tree; const char *slash1; @@ -1239,13 +1246,14 @@ static int tree_content_remove(struct tree_entry *root, const char *p) goto del_entry; if (!e->tree) load_tree(e); - if (tree_content_remove(e, slash1 + 1)) { + if (tree_content_remove(e, slash1 + 1, backup_leaf)) { for (n = 0; n < e->tree->entry_count; n++) { if (e->tree->entries[n]->versions[1].mode) { hashclr(root->versions[1].sha1); return 1; } } + backup_leaf = NULL; goto del_entry; } return 0; @@ -1254,10 +1262,11 @@ static int tree_content_remove(struct tree_entry *root, const char *p) return 0; del_entry: - if (e->tree) { + if (backup_leaf) + memcpy(backup_leaf, e, sizeof(*backup_leaf)); + else if (e->tree) release_tree_content_recursive(e->tree); - e->tree = NULL; - } + e->tree = NULL; e->versions[1].mode = 0; hashclr(e->versions[1].sha1); hashclr(root->versions[1].sha1); @@ -1629,7 +1638,7 @@ static void file_change_m(struct branch *b) typename(type), command_buf.buf); } - tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode); + tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode, NULL); free(p_uq); } @@ -1645,10 +1654,58 @@ static void file_change_d(struct branch *b) die("Garbage after path in: %s", command_buf.buf); p = p_uq; } - tree_content_remove(&b->branch_tree, p); + tree_content_remove(&b->branch_tree, p, NULL); free(p_uq); } +static void file_change_r(struct branch *b) +{ + const char *s, *d; + char *s_uq, *d_uq; + const char *endp; + struct tree_entry leaf; + + s = command_buf.buf + 2; + s_uq = unquote_c_style(s, &endp); + if (s_uq) { + if (*endp != ' ') + die("Missing space after source: %s", command_buf.buf); + } + else { + endp = strchr(s, ' '); + if (!endp) + die("Missing space after source: %s", command_buf.buf); + s_uq = xmalloc(endp - s + 1); + memcpy(s_uq, s, endp - s); + s_uq[endp - s] = 0; + } + s = s_uq; + + endp++; + if (!*endp) + die("Missing dest: %s", command_buf.buf); + + d = endp; + d_uq = unquote_c_style(d, &endp); + if (d_uq) { + if (*endp) + die("Garbage after dest in: %s", command_buf.buf); + d = d_uq; + } + + memset(&leaf, 0, sizeof(leaf)); + tree_content_remove(&b->branch_tree, s, &leaf); + if (!leaf.versions[1].mode) + die("Path %s not in branch", s); + tree_content_set(&b->branch_tree, d, + leaf.versions[1].sha1, + leaf.versions[1].mode, + leaf.tree); + + free(s_uq); + free(d_uq); +} + static void file_change_deleteall(struct branch *b) { release_tree_content_recursive(b->branch_tree.tree); @@ -1816,6 +1873,8 @@ static void cmd_new_commit(void) file_change_m(b); else if (!prefixcmp(command_buf.buf, "D ")) file_change_d(b); + else if (!prefixcmp(command_buf.buf, "R ")) + file_change_r(b); else if (!strcmp("deleteall", command_buf.buf)) file_change_deleteall(b); else diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 53774c8325..bf3720d762 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -580,4 +580,72 @@ test_expect_success \ git diff --raw L^ L >output && git diff expect output' +### +### series M +### + +test_tick +cat >input < $GIT_COMMITTER_DATE +data <expect <actual && + compare_diff_raw expect actual' + +cat >input < $GIT_COMMITTER_DATE +data <expect <actual && + compare_diff_raw expect actual' + +cat >input < $GIT_COMMITTER_DATE +data <expect <actual && + compare_diff_raw expect actual' + test_done From 52aaf649cb70134090c3e3a762bed730d5451c17 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 9 Jul 2007 14:47:24 +0100 Subject: [PATCH 153/213] rerere: record resolution even if file is not in merge base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two-file merges were rare enough that they were dropped outside of the radar. This fix is a trivial change to builtin-rerere.c::find_conflict(). It is still sane to insist that we do not do rerere for symlinks, and require to have stages #2 and #3, but we can drop the requirement to have stage #1. rerere does not use information from there anyway. This fix is from Junio, together with two tests to verify that it works as expected. Acked-by: Uwe Kleine-König Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-rerere.c | 17 +++++++---------- t/t4200-rerere.sh | 44 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/builtin-rerere.c b/builtin-rerere.c index c25b3d5586..6ffc43d864 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -168,19 +168,16 @@ static int find_conflict(struct path_list *conflict) int i; if (read_cache() < 0) return error("Could not read index"); - for (i = 0; i + 2 < active_nr; i++) { - struct cache_entry *e1 = active_cache[i]; - struct cache_entry *e2 = active_cache[i+1]; - struct cache_entry *e3 = active_cache[i+2]; - if (ce_stage(e1) == 1 && - ce_stage(e2) == 2 && + for (i = 0; i+1 < active_nr; i++) { + struct cache_entry *e2 = active_cache[i]; + struct cache_entry *e3 = active_cache[i+1]; + if (ce_stage(e2) == 2 && ce_stage(e3) == 3 && - ce_same_name(e1, e2) && ce_same_name(e1, e3) && - S_ISREG(ntohl(e1->ce_mode)) && + ce_same_name(e2, e3) && S_ISREG(ntohl(e2->ce_mode)) && S_ISREG(ntohl(e3->ce_mode))) { - path_list_insert((const char *)e1->name, conflict); - i += 2; + path_list_insert((const char *)e2->name, conflict); + i++; /* skip over both #2 and #3 */ } } return 0; diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 6f55ba03bd..cfcdb69dc8 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -116,11 +116,12 @@ test_expect_success 'commit succeeds' \ test_expect_success 'recorded postimage' "test -f $rr/postimage" -git checkout -b third master -git show second^:a1 | sed 's/To die: t/To die! T/' > a1 -git commit -q -a -m third - -test_expect_failure 'another conflicting merge' 'git pull . first' +test_expect_success 'another conflicting merge' ' + git checkout -b third master && + git show second^:a1 | sed "s/To die: t/To die! T/" > a1 && + git commit -q -a -m third && + ! git pull . first +' git show first:a1 | sed 's/To die: t/To die! T/' > expect test_expect_success 'rerere kicked in' "! grep ======= a1" @@ -164,4 +165,37 @@ test_expect_success 'garbage collection (part2)' 'git rerere gc' test_expect_success 'old records rest in peace' \ "test ! -f $rr/preimage && test ! -f $rr2/preimage" +test_expect_success 'file2 added differently in two branches' ' + git reset --hard && + git checkout -b fourth && + echo Hallo > file2 && + git add file2 && + git commit -m version1 && + git checkout third && + echo Bello > file2 && + git add file2 && + git commit -m version2 && + ! git merge fourth && + sha1=$(sed -e "s/ .*//" .git/rr-cache/MERGE_RR) && + rr=.git/rr-cache/$sha1 && + echo Cello > file2 && + git add file2 && + git commit -m resolution +' + +test_expect_success 'resolution was recorded properly' ' + git reset --hard HEAD~2 && + git checkout -b fifth && + echo Hallo > file3 && + git add file3 && + git commit -m version1 && + git checkout third && + echo Bello > file3 && + git add file3 && + git commit -m version2 && + ! git merge fifth && + git diff-files -q && + test Cello = "$(cat file3)" +' + test_done From 54dadbdb29668fbd51effefd0a0c65d915f5422b Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Mon, 9 Jul 2007 21:30:39 -0400 Subject: [PATCH 154/213] Makefile: rebuild git.o on version change, clean up git$X flags Commit 334d28ae factored out git.o as an intermediate stage between git.c and git$X. However: - It left some no-longer-relevant flags in the rule for git$X. - It failed to replace git$X with git.o in the list of files that record GIT_VERSION. This broke incorporation of a changed GIT_VERSION into git$X because, when GIT_VERSION changes, git.o isn't remade and git$X is relinked from the git.o that still contains the old GIT_VERSION. This patch removes the irrelevant flags and fixes incorporation of a changed GIT_VERSION into git$X. Signed-off-by: Matt McCutchen Signed-off-by: Junio C Hamano --- Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5b30e5c864..d7541b403b 100644 --- a/Makefile +++ b/Makefile @@ -753,8 +753,7 @@ git.o: git.c common-cmds.h GIT-CFLAGS $(ALL_CFLAGS) -c $(filter %.c,$^) git$X: git.o $(BUILTIN_OBJS) $(GITLIBS) - $(QUIET_LINK)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \ - $(ALL_CFLAGS) -o $@ $(filter %.c,$^) git.o \ + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \ $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) help.o: common-cmds.h @@ -857,7 +856,7 @@ configure: configure.ac rm -f $<+ # These can record GIT_VERSION -git$X git.spec \ +git.o git.spec \ $(patsubst %.sh,%,$(SCRIPT_SH)) \ $(patsubst %.perl,%,$(SCRIPT_PERL)) \ : GIT-VERSION-FILE From dfd255dd1a7c04ad24891db50e5d80d96f93fd4a Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Tue, 10 Jul 2007 00:47:23 -0400 Subject: [PATCH 155/213] Add allocation and freeing functions for struct refs Instead of open-coding allocation wherever it happens, have a function. Also, add a function to free a list of refs, which we currently never actually do. Signed-off-by: Daniel Barkalow Signed-off-by: Junio C Hamano --- connect.c | 2 +- remote.c | 25 ++++++++++++++++++++++--- remote.h | 7 +++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/connect.c b/connect.c index 65e79edc77..715cdc0223 100644 --- a/connect.c +++ b/connect.c @@ -72,7 +72,7 @@ struct ref **get_remote_heads(int in, struct ref **list, continue; if (nr_match && !path_match(name, nr_match, match)) continue; - ref = xcalloc(1, sizeof(*ref) + len - 40); + ref = alloc_ref(len - 40); hashcpy(ref->old_sha1, old_sha1); memcpy(ref->name, buffer + 41, len - 40); *list = ref; diff --git a/remote.c b/remote.c index cf98a44367..616f6f2165 100644 --- a/remote.c +++ b/remote.c @@ -320,6 +320,25 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec) return -1; } +struct ref *alloc_ref(unsigned namelen) +{ + struct ref *ret = xmalloc(sizeof(struct ref) + namelen); + memset(ret, 0, sizeof(struct ref) + namelen); + return ret; +} + +void free_refs(struct ref *ref) +{ + struct ref *next; + while (ref) { + next = ref->next; + if (ref->peer_ref) + free(ref->peer_ref); + free(ref); + ref = next; + } +} + static int count_refspec_match(const char *pattern, struct ref *refs, struct ref **matched_ref) @@ -391,7 +410,7 @@ static struct ref *try_explicit_object_name(const char *name) int len; if (!*name) { - ref = xcalloc(1, sizeof(*ref) + 20); + ref = alloc_ref(20); strcpy(ref->name, "(delete)"); hashclr(ref->new_sha1); return ref; @@ -399,7 +418,7 @@ static struct ref *try_explicit_object_name(const char *name) if (get_sha1(name, sha1)) return NULL; len = strlen(name) + 1; - ref = xcalloc(1, sizeof(*ref) + len); + ref = alloc_ref(len); memcpy(ref->name, name, len); hashcpy(ref->new_sha1, sha1); return ref; @@ -411,7 +430,7 @@ static struct ref *make_dst(const char *name, struct ref ***dst_tail) size_t len; len = strlen(name) + 1; - dst = xcalloc(1, sizeof(*dst) + len); + dst = alloc_ref(len); memcpy(dst->name, name, len); link_dst_tail(dst, dst_tail); return dst; diff --git a/remote.h b/remote.h index 01dbcef670..080b7dab99 100644 --- a/remote.h +++ b/remote.h @@ -30,6 +30,13 @@ struct refspec { char *dst; }; +struct ref *alloc_ref(unsigned namelen); + +/* + * Frees the entire list and peers of elements. + */ +void free_refs(struct ref *ref); + int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, int nr_refspec, char **refspec, int all); From 1d735267c9fb74892b0db41b567dc55dcc878006 Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Tue, 10 Jul 2007 00:47:26 -0400 Subject: [PATCH 156/213] Some cosmetic changes to remote library Functions for managing ref lists were named based on their use in match_refs (for push). For fetch, they will be used for other purposes, so rename them as a separate patch to make the future code readable. Signed-off-by: Daniel Barkalow Signed-off-by: Junio C Hamano --- remote.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/remote.c b/remote.c index 616f6f2165..09c427906d 100644 --- a/remote.c +++ b/remote.c @@ -396,11 +396,12 @@ static int count_refspec_match(const char *pattern, } } -static void link_dst_tail(struct ref *ref, struct ref ***tail) +static void tail_link_ref(struct ref *ref, struct ref ***tail) { **tail = ref; + while (ref->next) + ref = ref->next; *tail = &ref->next; - **tail = NULL; } static struct ref *try_explicit_object_name(const char *name) @@ -424,16 +425,16 @@ static struct ref *try_explicit_object_name(const char *name) return ref; } -static struct ref *make_dst(const char *name, struct ref ***dst_tail) +static struct ref *make_linked_ref(const char *name, struct ref ***tail) { - struct ref *dst; + struct ref *ret; size_t len; len = strlen(name) + 1; - dst = alloc_ref(len); - memcpy(dst->name, name, len); - link_dst_tail(dst, dst_tail); - return dst; + ret = alloc_ref(len); + memcpy(ret->name, name, len); + tail_link_ref(ret, tail); + return ret; } static int match_explicit(struct ref *src, struct ref *dst, @@ -481,7 +482,7 @@ static int match_explicit(struct ref *src, struct ref *dst, break; case 0: if (!memcmp(dst_value, "refs/", 5)) - matched_dst = make_dst(dst_value, dst_tail); + matched_dst = make_linked_ref(dst_value, dst_tail); else error("dst refspec %s does not match any " "existing ref on the remote and does " @@ -591,7 +592,7 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, goto free_name; if (!dst_peer) { /* Create a new one and link it */ - dst_peer = make_dst(dst_name, dst_tail); + dst_peer = make_linked_ref(dst_name, dst_tail); hashcpy(dst_peer->new_sha1, src->new_sha1); } dst_peer->peer_ref = src; From c7bd55028ff463fa0162bffb35ac519beb462ca5 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 10 Jul 2007 09:51:42 -0400 Subject: [PATCH 157/213] Correct trivial typo in fast-import documentation Rogan Dawes noticed I meant `filerename` here and not `filename`. Signed-off-by: Shawn O. Pearce --- Documentation/git-fast-import.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 80a8ee0f1c..bf1ba67ad0 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -325,7 +325,7 @@ commit message use a 0 length data. Commit messages are free-form and are not interpreted by Git. Currently they must be encoded in UTF-8, as fast-import does not permit other encodings to be specified. -Zero or more `filemodify`, `filedelete`, `filename` and +Zero or more `filemodify`, `filedelete`, `filerename` and `filedeleteall` commands may be included to update the contents of the branch prior to creating the commit. These commands may be supplied in any order. From 55feb1200f0e1a7f6cb8670de0dee97f09d8cb9f Mon Sep 17 00:00:00 2001 From: Michael Hendricks Date: Wed, 4 Jul 2007 18:36:48 -0600 Subject: [PATCH 158/213] gitweb: configurable width for the projects list Description column This allows gitweb users to set $projects_list_description_width in their gitweb.conf to determine how many characters of a project description are displayed before being truncated with an ellipsis. Signed-off-by: Michael Hendricks Acked-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index dc609f4f86..27580b5670 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -71,6 +71,9 @@ our $logo_label = "git homepage"; # source of projects list our $projects_list = "++GITWEB_LIST++"; +# the width (in characters) of the projects list "Description" column +our $projects_list_description_width = 25; + # default order of projects list # valid values are none, project, descr, owner, and age our $default_projects_order = "project"; @@ -3182,7 +3185,7 @@ sub git_project_list_body { if (!defined $pr->{'descr'}) { my $descr = git_get_project_description($pr->{'path'}) || ""; $pr->{'descr_long'} = to_utf8($descr); - $pr->{'descr'} = chop_str($descr, 25, 5); + $pr->{'descr'} = chop_str($descr, $projects_list_description_width, 5); } if (!defined $pr->{'owner'}) { $pr->{'owner'} = git_get_project_owner("$pr->{'path'}") || ""; From 835252272e0192bd26983e22428480c5c89775fb Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 11 Jul 2007 15:18:17 +0100 Subject: [PATCH 159/213] Fix core.sharedRepository = 2 For compatibility reasons, "git init --shared=all" does not write "all" into the config, but a number. In the shared setup, you really have to support even older clients on the _same_ repository. But git_config_perm() did not pick up on it. Also, "git update-server-info" failed to pick up on the shared permissions. This patch fixes both issues, and adds a test to prove it. Signed-off-by: Johannes Schindelin Tested-by: martin f krafft Signed-off-by: Junio C Hamano --- server-info.c | 2 ++ setup.c | 4 ++++ t/t1301-shared-repo.sh | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100755 t/t1301-shared-repo.sh diff --git a/server-info.c b/server-info.c index f9be5a7f60..0d1312ca56 100644 --- a/server-info.c +++ b/server-info.c @@ -38,6 +38,7 @@ static int update_info_refs(int force) return error("unable to update %s", path0); for_each_ref(add_info_ref, NULL); fclose(info_ref_fp); + adjust_shared_perm(path1); rename(path1, path0); free(path0); free(path1); @@ -227,6 +228,7 @@ static int update_info_packs(int force) return error("cannot open %s", name); write_pack_info_file(fp); fclose(fp); + adjust_shared_perm(name); rename(name, infofile); return 0; } diff --git a/setup.c b/setup.c index bb26f3af96..7b07144af7 100644 --- a/setup.c +++ b/setup.c @@ -364,6 +364,7 @@ const char *setup_git_directory_gently(int *nongit_ok) int git_config_perm(const char *var, const char *value) { if (value) { + int i; if (!strcmp(value, "umask")) return PERM_UMASK; if (!strcmp(value, "group")) @@ -372,6 +373,9 @@ int git_config_perm(const char *var, const char *value) !strcmp(value, "world") || !strcmp(value, "everybody")) return PERM_EVERYBODY; + i = atoi(value); + if (i > 1) + return i; } return git_config_bool(var, value); } diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh new file mode 100755 index 0000000000..bb5f30220a --- /dev/null +++ b/t/t1301-shared-repo.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes Schindelin +# + +test_description='Test shared repository initialization' + +. ./test-lib.sh + +test_expect_success 'shared=all' ' + mkdir sub && + cd sub && + git init --shared=all && + test 2 = $(git config core.sharedrepository) +' + +test_expect_success 'update-server-info honors core.sharedRepository' ' + : > a1 && + git add a1 && + test_tick && + git commit -m a1 && + umask 0277 && + git update-server-info && + test 444 = $(stat -c %a .git/info/refs) +' + +test_done From 36d56de649aacdbf555d2c9743c514cc52368f2c Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 10 Jul 2007 14:50:49 +0100 Subject: [PATCH 160/213] Fix --cherry-pick with given paths If you say --cherry-pick, you do not want to see patches which are in the upstream. If you specify paths with that, what you usually expect is that only those parts of the patches are looked at which actually touch the given paths. With this patch, that expectation is met. Noticed by Sam Vilain. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- revision.c | 9 ++++-- t/t6007-rev-list-cherry-pick-file.sh | 43 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100755 t/t6007-rev-list-cherry-pick-file.sh diff --git a/revision.c b/revision.c index 33ee9ee3b2..27cce090a1 100644 --- a/revision.c +++ b/revision.c @@ -437,7 +437,7 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str return 0; } -static void cherry_pick_list(struct commit_list *list) +static void cherry_pick_list(struct commit_list *list, struct rev_info *revs) { struct commit_list *p; int left_count = 0, right_count = 0; @@ -458,6 +458,11 @@ static void cherry_pick_list(struct commit_list *list) left_first = left_count < right_count; init_patch_ids(&ids); + if (revs->diffopt.nr_paths) { + ids.diffopts.nr_paths = revs->diffopt.nr_paths; + ids.diffopts.paths = revs->diffopt.paths; + ids.diffopts.pathlens = revs->diffopt.pathlens; + } /* Compute patch-ids for one side */ for (p = list; p; p = p->next) { @@ -546,7 +551,7 @@ static int limit_list(struct rev_info *revs) p = &commit_list_insert(commit, p)->next; } if (revs->cherry_pick) - cherry_pick_list(newlist); + cherry_pick_list(newlist, revs); revs->commits = newlist; return 0; diff --git a/t/t6007-rev-list-cherry-pick-file.sh b/t/t6007-rev-list-cherry-pick-file.sh new file mode 100755 index 0000000000..3faeae6c01 --- /dev/null +++ b/t/t6007-rev-list-cherry-pick-file.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +test_description='test git rev-list --cherry-pick -- file' + +. ./test-lib.sh + +# A---B +# \ +# \ +# C +# +# B changes a file foo.c, adding a line of text. C changes foo.c as +# well as bar.c, but the change in foo.c was identical to change B. + +test_expect_success setup ' + echo Hallo > foo && + git add foo && + test_tick && + git commit -m "A" && + git tag A && + git checkout -b branch && + echo Bello > foo && + echo Cello > bar && + git add foo bar && + test_tick && + git commit -m "C" && + git tag C && + git checkout master && + git checkout branch foo && + test_tick && + git commit -m "B" && + git tag B +' + +test_expect_success '--cherry-pick foo comes up empty' ' + test -z "$(git rev-list --left-right --cherry-pick B...C -- foo)" +' + +test_expect_success '--cherry-pick bar does not come up empty' ' + ! test -z "$(git rev-list --left-right --cherry-pick B...C -- bar)" +' + +test_done From defd53142e0c3326c3677cc3d623a6aeef899518 Mon Sep 17 00:00:00 2001 From: Carlos Rica Date: Tue, 10 Jul 2007 23:53:45 +0200 Subject: [PATCH 161/213] t0030: Remove repeated instructions and add missing && Moved some tests to another test_expect_success block. Many tests now reuse the same "expect" file. Also replacing many printf "" >expect with one >expect instruction. Added missing && which concatenated tests in some test_expect_success blocks. Signed-off-by: Carlos Rica Signed-off-by: Junio C Hamano --- t/t0030-stripspace.sh | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh index fdc9fdce6f..4a2980c833 100755 --- a/t/t0030-stripspace.sh +++ b/t/t0030-stripspace.sh @@ -85,39 +85,36 @@ test_expect_success \ ' test_expect_success \ - 'consecutive blank lines at the beginning should be removed' ' - printf "" > expect && + 'only consecutive blank lines should be completely removed' ' + > expect && + printf "\n" | git stripspace >actual && git diff expect actual && - printf "" > expect && printf "\n\n\n" | git stripspace >actual && git diff expect actual && - printf "" > expect && printf "$sss\n$sss\n$sss\n" | git stripspace >actual && git diff expect actual && - printf "" > expect && printf "$sss$sss\n$sss\n\n" | git stripspace >actual && git diff expect actual && - printf "" > expect && printf "\n$sss\n$sss$sss\n" | git stripspace >actual && git diff expect actual && - printf "" > expect && printf "$sss$sss$sss$sss\n\n\n" | git stripspace >actual && git diff expect actual && - printf "" > expect && printf "\n$sss$sss$sss$sss\n\n" | git stripspace >actual && git diff expect actual && - printf "" > expect && printf "\n\n$sss$sss$sss$sss\n" | git stripspace >actual && - git diff expect actual && + git diff expect actual +' +test_expect_success \ + 'consecutive blank lines at the beginning should be removed' ' printf "$ttt\n" > expect && printf "\n$ttt\n" | git stripspace >actual && git diff expect actual && @@ -139,26 +136,22 @@ test_expect_success \ git diff expect actual && printf "$ttt\n" > expect && + printf "$sss\n$sss\n$sss\n$ttt\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "\n$sss\n$sss$sss\n$ttt\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "$sss$sss\n$sss\n\n$ttt\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "$sss$sss$sss\n\n\n$ttt\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "\n$sss$sss$sss\n\n$ttt\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "\n\n$sss$sss$sss\n$ttt\n" | git stripspace >actual && git diff expect actual ' @@ -186,26 +179,22 @@ test_expect_success \ git diff expect actual && printf "$ttt\n" > expect && + printf "$ttt\n$sss\n$sss\n$sss\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "$ttt\n\n$sss\n$sss$sss\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "$ttt\n$sss$sss\n$sss\n\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "$ttt\n$sss$sss$sss\n\n\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "$ttt\n\n$sss$sss$sss\n\n" | git stripspace >actual && git diff expect actual && - printf "$ttt\n" > expect && printf "$ttt\n\n\n$sss$sss$sss\n" | git stripspace >actual && git diff expect actual ' @@ -224,7 +213,7 @@ test_expect_success \ 'text plus spaces without newline at end should end with newline' ' test `printf "$ttt$sss" | git stripspace | wc -l` -gt 0 && test `printf "$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 && - test `printf "$ttt$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 + test `printf "$ttt$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 && test `printf "$ttt$sss$sss" | git stripspace | wc -l` -gt 0 && test `printf "$ttt$ttt$sss$sss" | git stripspace | wc -l` -gt 0 && test `printf "$ttt$sss$sss$sss" | git stripspace | wc -l` -gt 0 @@ -340,13 +329,13 @@ test_expect_success \ printf "" >expect && printf "" | git stripspace >actual && - git diff expect actual + git diff expect actual && printf "$sss$sss" | git stripspace >actual && - git diff expect actual + git diff expect actual && printf "$sss$sss$sss" | git stripspace >actual && - git diff expect actual + git diff expect actual && printf "$sss$sss$sss$sss" | git stripspace >actual && git diff expect actual From b61a8a67478310eb3349d869119ce7a729090273 Mon Sep 17 00:00:00 2001 From: Carlos Rica Date: Tue, 10 Jul 2007 23:59:43 +0200 Subject: [PATCH 162/213] t0030: Add tests with consecutive text lines and others with spaces added. Previous tests only had paragraphs of one line. This commit adds some tests to check when many consecutive text lines are given. Also, it adds tests for checking that many lines between paragraphs are correctly reduced to one when there are tabs and spaces in those lines. Signed-off-by: Carlos Rica Signed-off-by: Junio C Hamano --- t/t0030-stripspace.sh | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh index 4a2980c833..b1c900379b 100755 --- a/t/t0030-stripspace.sh +++ b/t/t0030-stripspace.sh @@ -81,6 +81,30 @@ test_expect_success \ printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && printf "$ttt\n\n\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt\n\n$ttt$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt$ttt$ttt\n" | git stripspace >actual && git diff expect actual ' @@ -341,4 +365,31 @@ test_expect_success \ git diff expect actual ' +test_expect_success \ + 'consecutive text lines should be unchanged' ' + printf "$ttt$ttt\n$ttt\n" >expect && + printf "$ttt$ttt\n$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt\n$ttt$ttt\n$ttt\n" >expect && + printf "$ttt\n$ttt$ttt\n$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt\n$ttt\n$ttt\n$ttt$ttt\n" >expect && + printf "$ttt\n$ttt\n$ttt\n$ttt$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt\n$ttt\n\n$ttt$ttt\n$ttt\n" >expect && + printf "$ttt\n$ttt\n\n$ttt$ttt\n$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt$ttt\n\n$ttt\n$ttt$ttt\n" >expect && + printf "$ttt$ttt\n\n$ttt\n$ttt$ttt\n" | git stripspace >actual && + git diff expect actual && + + printf "$ttt\n$ttt$ttt\n\n$ttt\n" >expect && + printf "$ttt\n$ttt$ttt\n\n$ttt\n" | git stripspace >actual && + git diff expect actual +' + test_done From 5206d13091a38b2fef534c78e893814dbab0af26 Mon Sep 17 00:00:00 2001 From: Carlos Rica Date: Wed, 11 Jul 2007 01:11:53 +0200 Subject: [PATCH 163/213] t7004: Add tests for the git tag -n option. These tests check the syntax for the git tag -n option and its output when one, none or many lines of the message are requested. Also this commit adds a missing && in the test that checks the sorted output of git tag -l. Signed-off-by: Carlos Rica Signed-off-by: Junio C Hamano --- t/t7004-tag.sh | 202 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 1 deletion(-) diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index b785080f9f..17de2a90e6 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -164,7 +164,7 @@ test_expect_success 'listing all tags should print them ordered' ' git tag a1 && git tag v1.0 && git tag t210 && - git tag -l > actual + git tag -l > actual && git diff expect actual ' @@ -437,6 +437,106 @@ test_expect_success \ git diff expect actual ' +# listing messages for annotated non-signed tags: + +test_expect_success \ + 'listing the one-line message of a non-signed tag should succeed' ' + git-tag -m "A msg" tag-one-line && + + echo "tag-one-line" >expect && + git-tag -l | grep "^tag-one-line" >actual && + git diff expect actual && + git-tag -n 0 -l | grep "^tag-one-line" >actual && + git diff expect actual && + git-tag -n 0 -l tag-one-line >actual && + git diff expect actual && + + echo "tag-one-line A msg" >expect && + git-tag -n xxx -l | grep "^tag-one-line" >actual && + git diff expect actual && + git-tag -n "" -l | grep "^tag-one-line" >actual && + git diff expect actual && + git-tag -n 1 -l | grep "^tag-one-line" >actual && + git diff expect actual && + git-tag -n -l | grep "^tag-one-line" >actual && + git diff expect actual && + git-tag -n 1 -l tag-one-line >actual && + git diff expect actual && + git-tag -n 2 -l tag-one-line >actual && + git diff expect actual && + git-tag -n 999 -l tag-one-line >actual && + git diff expect actual +' + +test_expect_success \ + 'listing the zero-lines message of a non-signed tag should succeed' ' + git-tag -m "" tag-zero-lines && + + echo "tag-zero-lines" >expect && + git-tag -l | grep "^tag-zero-lines" >actual && + git diff expect actual && + git-tag -n 0 -l | grep "^tag-zero-lines" >actual && + git diff expect actual && + git-tag -n 0 -l tag-zero-lines >actual && + git diff expect actual && + + echo "tag-zero-lines " >expect && + git-tag -n 1 -l | grep "^tag-zero-lines" >actual && + git diff expect actual && + git-tag -n -l | grep "^tag-zero-lines" >actual && + git diff expect actual && + git-tag -n 1 -l tag-zero-lines >actual && + git diff expect actual && + git-tag -n 2 -l tag-zero-lines >actual && + git diff expect actual && + git-tag -n 999 -l tag-zero-lines >actual && + git diff expect actual +' + +echo 'tag line one' >annotagmsg +echo 'tag line two' >>annotagmsg +echo 'tag line three' >>annotagmsg +test_expect_success \ + 'listing many message lines of a non-signed tag should succeed' ' + git-tag -F annotagmsg tag-lines && + + echo "tag-lines" >expect && + git-tag -l | grep "^tag-lines" >actual && + git diff expect actual && + git-tag -n 0 -l | grep "^tag-lines" >actual && + git diff expect actual && + git-tag -n 0 -l tag-lines >actual && + git diff expect actual && + + echo "tag-lines tag line one" >expect && + git-tag -n 1 -l | grep "^tag-lines" >actual && + git diff expect actual && + git-tag -n -l | grep "^tag-lines" >actual && + git diff expect actual && + git-tag -n 1 -l tag-lines >actual && + git diff expect actual && + + echo " tag line two" >>expect && + git-tag -n 2 -l | grep "^ *tag.line" >actual && + git diff expect actual && + git-tag -n 2 -l tag-lines >actual && + git diff expect actual && + + echo " tag line three" >>expect && + git-tag -n 3 -l | grep "^ *tag.line" >actual && + git diff expect actual && + git-tag -n 3 -l tag-lines >actual && + git diff expect actual && + git-tag -n 4 -l | grep "^ *tag.line" >actual && + git diff expect actual && + git-tag -n 4 -l tag-lines >actual && + git diff expect actual && + git-tag -n 99 -l | grep "^ *tag.line" >actual && + git diff expect actual && + git-tag -n 99 -l tag-lines >actual && + git diff expect actual +' + # trying to verify annotated non-signed tags: test_expect_success \ @@ -651,6 +751,106 @@ test_expect_success \ git-tag -v commentnonlfile-signed-tag ' +# listing messages for signed tags: + +test_expect_success \ + 'listing the one-line message of a signed tag should succeed' ' + git-tag -s -m "A message line signed" stag-one-line && + + echo "stag-one-line" >expect && + git-tag -l | grep "^stag-one-line" >actual && + git diff expect actual && + git-tag -n 0 -l | grep "^stag-one-line" >actual && + git diff expect actual && + git-tag -n 0 -l stag-one-line >actual && + git diff expect actual && + + echo "stag-one-line A message line signed" >expect && + git-tag -n xxx -l | grep "^stag-one-line" >actual && + git diff expect actual && + git-tag -n "" -l | grep "^stag-one-line" >actual && + git diff expect actual && + git-tag -n 1 -l | grep "^stag-one-line" >actual && + git diff expect actual && + git-tag -n -l | grep "^stag-one-line" >actual && + git diff expect actual && + git-tag -n 1 -l stag-one-line >actual && + git diff expect actual && + git-tag -n 2 -l stag-one-line >actual && + git diff expect actual && + git-tag -n 999 -l stag-one-line >actual && + git diff expect actual +' + +test_expect_success \ + 'listing the zero-lines message of a signed tag should succeed' ' + git-tag -s -m "" stag-zero-lines && + + echo "stag-zero-lines" >expect && + git-tag -l | grep "^stag-zero-lines" >actual && + git diff expect actual && + git-tag -n 0 -l | grep "^stag-zero-lines" >actual && + git diff expect actual && + git-tag -n 0 -l stag-zero-lines >actual && + git diff expect actual && + + echo "stag-zero-lines " >expect && + git-tag -n 1 -l | grep "^stag-zero-lines" >actual && + git diff expect actual && + git-tag -n -l | grep "^stag-zero-lines" >actual && + git diff expect actual && + git-tag -n 1 -l stag-zero-lines >actual && + git diff expect actual && + git-tag -n 2 -l stag-zero-lines >actual && + git diff expect actual && + git-tag -n 999 -l stag-zero-lines >actual && + git diff expect actual +' + +echo 'stag line one' >sigtagmsg +echo 'stag line two' >>sigtagmsg +echo 'stag line three' >>sigtagmsg +test_expect_success \ + 'listing many message lines of a signed tag should succeed' ' + git-tag -s -F sigtagmsg stag-lines && + + echo "stag-lines" >expect && + git-tag -l | grep "^stag-lines" >actual && + git diff expect actual && + git-tag -n 0 -l | grep "^stag-lines" >actual && + git diff expect actual && + git-tag -n 0 -l stag-lines >actual && + git diff expect actual && + + echo "stag-lines stag line one" >expect && + git-tag -n 1 -l | grep "^stag-lines" >actual && + git diff expect actual && + git-tag -n -l | grep "^stag-lines" >actual && + git diff expect actual && + git-tag -n 1 -l stag-lines >actual && + git diff expect actual && + + echo " stag line two" >>expect && + git-tag -n 2 -l | grep "^ *stag.line" >actual && + git diff expect actual && + git-tag -n 2 -l stag-lines >actual && + git diff expect actual && + + echo " stag line three" >>expect && + git-tag -n 3 -l | grep "^ *stag.line" >actual && + git diff expect actual && + git-tag -n 3 -l stag-lines >actual && + git diff expect actual && + git-tag -n 4 -l | grep "^ *stag.line" >actual && + git diff expect actual && + git-tag -n 4 -l stag-lines >actual && + git diff expect actual && + git-tag -n 99 -l | grep "^ *stag.line" >actual && + git diff expect actual && + git-tag -n 99 -l stag-lines >actual && + git diff expect actual +' + # tags pointing to objects different from commits: tree=$(git rev-parse HEAD^{tree}) From b42f69273bf5ae2d5bb0c7479bfa9827e7b351ac Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 10 Jul 2007 18:48:40 +0100 Subject: [PATCH 164/213] Add for_each_remote() function, and extend remote_find_tracking() The function for_each_remote() does exactly what the name suggests. The function remote_find_tracking() was extended to be able to search remote refs for a given local ref. The caller sets either src or dst (but not both) in the refspec parameter, and remote_find_tracking() will fill in the other and return 0. Both changes are required for the next step: simplification of git-branch's --track functionality. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- remote.c | 60 +++++++++++++++++++++++++++++++++++++++-------------- remote.h | 5 ++++- send-pack.c | 4 ++-- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/remote.c b/remote.c index 09c427906d..bb774d0bcc 100644 --- a/remote.c +++ b/remote.c @@ -279,6 +279,25 @@ struct remote *remote_get(const char *name) return ret; } +int for_each_remote(each_remote_fn fn, void *priv) +{ + int i, result = 0; + read_config(); + for (i = 0; i < allocated_remotes && !result; i++) { + struct remote *r = remotes[i]; + if (!r) + continue; + if (!r->fetch) + r->fetch = parse_ref_spec(r->fetch_refspec_nr, + r->fetch_refspec); + if (!r->push) + r->push = parse_ref_spec(r->push_refspec_nr, + r->push_refspec); + result = fn(r, priv); + } + return result; +} + int remote_has_uri(struct remote *remote, const char *uri) { int i; @@ -291,32 +310,43 @@ int remote_has_uri(struct remote *remote, const char *uri) int remote_find_tracking(struct remote *remote, struct refspec *refspec) { + int find_src = refspec->src == NULL; + char *needle, **result; int i; + + if (find_src) { + if (refspec->dst == NULL) + return error("find_tracking: need either src or dst"); + needle = refspec->dst; + result = &refspec->src; + } else { + needle = refspec->src; + result = &refspec->dst; + } + for (i = 0; i < remote->fetch_refspec_nr; i++) { struct refspec *fetch = &remote->fetch[i]; + const char *key = find_src ? fetch->dst : fetch->src; + const char *value = find_src ? fetch->src : fetch->dst; if (!fetch->dst) continue; if (fetch->pattern) { - if (!prefixcmp(refspec->src, fetch->src)) { - refspec->dst = - xmalloc(strlen(fetch->dst) + - strlen(refspec->src) - - strlen(fetch->src) + 1); - strcpy(refspec->dst, fetch->dst); - strcpy(refspec->dst + strlen(fetch->dst), - refspec->src + strlen(fetch->src)); - refspec->force = fetch->force; - return 0; - } - } else { - if (!strcmp(refspec->src, fetch->src)) { - refspec->dst = xstrdup(fetch->dst); + if (!prefixcmp(needle, key)) { + *result = xmalloc(strlen(value) + + strlen(needle) - + strlen(key) + 1); + strcpy(*result, value); + strcpy(*result + strlen(value), + needle + strlen(key)); refspec->force = fetch->force; return 0; } + } else if (!strcmp(needle, key)) { + *result = xstrdup(value); + refspec->force = fetch->force; + return 0; } } - refspec->dst = NULL; return -1; } diff --git a/remote.h b/remote.h index 080b7dab99..17b8b5b5d5 100644 --- a/remote.h +++ b/remote.h @@ -20,13 +20,16 @@ struct remote { struct remote *remote_get(const char *name); +typedef int each_remote_fn(struct remote *remote, void *priv); +int for_each_remote(each_remote_fn fn, void *priv); + int remote_has_uri(struct remote *remote, const char *uri); struct refspec { unsigned force : 1; unsigned pattern : 1; - const char *src; + char *src; char *dst; }; diff --git a/send-pack.c b/send-pack.c index fecbda981b..9fc8a812f4 100644 --- a/send-pack.c +++ b/send-pack.c @@ -305,8 +305,8 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha if (remote) { struct refspec rs; rs.src = ref->name; - remote_find_tracking(remote, &rs); - if (rs.dst) { + rs.dst = NULL; + if (!remote_find_tracking(remote, &rs)) { struct ref_lock *lock; fprintf(stderr, " Also local %s\n", rs.dst); if (will_delete_ref) { From 6f084a56fcb3543d88d252bb49c1d2bbf2bd0cf3 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 10 Jul 2007 18:50:44 +0100 Subject: [PATCH 165/213] branch --track: code cleanup and saner handling of local branches This patch cleans up some complicated code, and replaces it with a cleaner version, using code from remote.[ch], which got extended a little in the process. This also enables us to fix two cases: The earlier "fix" to setup tracking only when the original ref started with "refs/remotes" is wrong. You are absolutely allowed to use a separate layout for your tracking branches. The correct fix, of course, is to set up tracking information only when there is a matching remote..fetch line containing a colon. Another corner case was not handled properly. If two remotes write to the original ref, just warn the user and do not set up tracking. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/config.txt | 5 +- Documentation/git-checkout.txt | 5 +- builtin-branch.c | 168 +++++++++++---------------------- t/t3200-branch.sh | 21 +++-- 4 files changed, 68 insertions(+), 131 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index aeece848a5..4b67f0adf7 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -309,10 +309,7 @@ branch.autosetupmerge:: so that gitlink:git-pull[1] will appropriately merge from that remote branch. Note that even if this option is not set, this behavior can be chosen per-branch using the `--track` - and `--no-track` options. This option can have values - 'false' (never touch the configuration), 'all' (do this - for all branches), or 'true' (do this only when - branching from a remote tracking branch), and defaults to 'true'. + and `--no-track` options. This option defaults to false. branch..remote:: When in branch , it tells `git fetch` which remote to fetch. diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 82929523c7..818b720b91 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -52,9 +52,8 @@ OPTIONS set up configuration so that git-pull will automatically retrieve data from the remote branch. Set the branch.autosetupmerge configuration variable to true if you - want git-checkout and git-branch to behave as if - '--track' were given when you branch from a remote - tracking branch. + want git-checkout and git-branch to always behave as if + '--track' were given. --no-track:: When -b is given and a branch is created off a remote branch, diff --git a/builtin-branch.c b/builtin-branch.c index 423c30194c..3f9e7c2def 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -10,6 +10,7 @@ #include "refs.h" #include "commit.h" #include "builtin.h" +#include "remote.h" static const char builtin_branch_usage[] = "git-branch [-r] (-d | -D) | [--track | --no-track] [-l] [-f] [] | (-m | -M) [] | [--color | --no-color] [-r | -a] [-v [--abbrev= | --no-abbrev]]"; @@ -22,7 +23,7 @@ static const char builtin_branch_usage[] = static const char *head; static unsigned char head_sha1[20]; -static int branch_track = 1; /* 0 = none, 1 = remotes, 2 = all */ +static int branch_track = 1; static int branch_use_color; static char branch_colors[][COLOR_MAXLEN] = { @@ -66,12 +67,8 @@ static int git_branch_config(const char *var, const char *value) color_parse(value, var, branch_colors[slot]); return 0; } - if (!strcmp(var, "branch.autosetupmerge")) { - if (!strcmp(value, "all")) - branch_track = 2; - else + if (!strcmp(var, "branch.autosetupmerge")) branch_track = git_config_bool(var, value); - } return git_default_config(var, value); } @@ -328,125 +325,70 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev) free_ref_list(&ref_list); } -static char *config_repo; -static char *config_remote; -static const char *start_ref; +struct tracking { + struct refspec spec; + char *src; + const char *remote; + int matches; +}; -static int get_remote_branch_name(const char *value) +static int find_tracked_branch(struct remote *remote, void *priv) { - const char *colon; - const char *end; + struct tracking *tracking = priv; - if (*value == '+') - value++; - - colon = strchr(value, ':'); - if (!colon) - return 0; - - end = value + strlen(value); - - /* - * Try an exact match first. I.e. handle the case where the - * value is "$anything:refs/foo/bar/baz" and start_ref is exactly - * "refs/foo/bar/baz". Then the name at the remote is $anything. - */ - if (!strcmp(colon + 1, start_ref)) { - /* Truncate the value before the colon. */ - nfasprintf(&config_repo, "%.*s", colon - value, value); - return 1; + if (!remote_find_tracking(remote, &tracking->spec)) { + if (++tracking->matches == 1) { + tracking->src = tracking->spec.src; + tracking->remote = remote->name; + } else { + free(tracking->spec.src); + if (tracking->src) { + free(tracking->src); + tracking->src = NULL; + } + } + tracking->spec.src = NULL; } - /* - * Is this a wildcard match? - */ - if ((end - 2 <= value) || end[-2] != '/' || end[-1] != '*' || - (colon - 2 <= value) || colon[-2] != '/' || colon[-1] != '*') - return 0; - - /* - * Value is "refs/foo/bar/:refs/baz/boa/" - * and start_ref begins with "refs/baz/boa/"; the name at the - * remote is refs/foo/bar/ with the remaining part of the - * start_ref. The length of the prefix on the RHS is (end - - * colon - 2), including the slash immediately before the - * asterisk. - */ - if ((strlen(start_ref) < end - colon - 2) || - memcmp(start_ref, colon + 1, end - colon - 2)) - return 0; /* does not match prefix */ - - /* Replace the asterisk with the remote branch name. */ - nfasprintf(&config_repo, "%.*s%s", - (colon - 1) - value, value, - start_ref + (end - colon - 2)); - return 1; -} - -static int get_remote_config(const char *key, const char *value) -{ - const char *var; - if (prefixcmp(key, "remote.")) - return 0; - - var = strrchr(key, '.'); - if (var == key + 6 || strcmp(var, ".fetch")) - return 0; - /* - * Ok, we are looking at key == "remote.$foo.fetch"; - */ - if (get_remote_branch_name(value)) - nfasprintf(&config_remote, "%.*s", var - (key + 7), key + 7); - return 0; } -static void set_branch_merge(const char *name, const char *config_remote, - const char *config_repo) + +/* + * This is called when new_ref is branched off of orig_ref, and tries + * to infer the settings for branch..{remote,merge} from the + * config. + */ +static int setup_tracking(const char *new_ref, const char *orig_ref) { char key[1024]; - if (sizeof(key) <= - snprintf(key, sizeof(key), "branch.%s.remote", name)) - die("what a long branch name you have!"); - git_config_set(key, config_remote); + struct tracking tracking; - /* - * We do not have to check if we have enough space for - * the 'merge' key, since it's shorter than the - * previous 'remote' key, which we already checked. - */ - snprintf(key, sizeof(key), "branch.%s.merge", name); - git_config_set(key, config_repo); -} + if (strlen(new_ref) > 1024 - 7 - 7 - 1) + return error("Tracking not set up: name too long: %s", + new_ref); -static void set_branch_defaults(const char *name, const char *real_ref) -{ - /* - * name is the name of new branch under refs/heads; - * real_ref is typically refs/remotes/$foo/$bar, where - * $foo is the remote name (there typically are no slashes) - * and $bar is the branch name we map from the remote - * (it could have slashes). - */ - start_ref = real_ref; - git_config(get_remote_config); - if (!config_repo && !config_remote && - !prefixcmp(real_ref, "refs/heads/")) { - set_branch_merge(name, ".", real_ref); - printf("Branch %s set up to track local branch %s.\n", - name, real_ref); - } + memset(&tracking, 0, sizeof(tracking)); + tracking.spec.dst = (char *)orig_ref; + if (for_each_remote(find_tracked_branch, &tracking) || + !tracking.matches) + return 1; - if (config_repo && config_remote) { - set_branch_merge(name, config_remote, config_repo); + if (tracking.matches > 1) + return error("Not tracking: ambiguous information for ref %s", + orig_ref); + + if (tracking.matches == 1) { + sprintf(key, "branch.%s.remote", new_ref); + git_config_set(key, tracking.remote ? tracking.remote : "."); + sprintf(key, "branch.%s.merge", new_ref); + git_config_set(key, tracking.src); + free(tracking.src); printf("Branch %s set up to track remote branch %s.\n", - name, real_ref); + new_ref, orig_ref); } - if (config_repo) - free(config_repo); - if (config_remote) - free(config_remote); + return 0; } static void create_branch(const char *name, const char *start_name, @@ -508,10 +450,8 @@ static void create_branch(const char *name, const char *start_name, /* When branching off a remote branch, set up so that git-pull automatically merges from there. So far, this is only done for remotes registered via .git/config. */ - if (real_ref && (track == 2 || - (track == 1 && - !prefixcmp(real_ref, "refs/remotes/")))) - set_branch_defaults(name, real_ref); + if (real_ref && track) + setup_tracking(name, real_ref); if (write_ref_sha1(lock, sha1, msg) < 0) die("Failed to write ref: %s.", strerror(errno)); @@ -582,7 +522,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) break; } if (!strcmp(arg, "--track")) { - track = 2; + track = 1; continue; } if (!strcmp(arg, "--no-track")) { diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index a19e961cb3..ef1eeb7d8a 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -148,13 +148,14 @@ test_expect_success 'test tracking setup via config' \ test $(git config branch.my3.remote) = local && test $(git config branch.my3.merge) = refs/heads/master' -test_expect_success 'autosetupmerge = all' ' +test_expect_success 'avoid ambiguous track' ' git config branch.autosetupmerge true && + git config remote.ambi1.url = lalala && + git config remote.ambi1.fetch = refs/heads/lalala:refs/heads/master && + git config remote.ambi2.url = lilili && + git config remote.ambi2.fetch = refs/heads/lilili:refs/heads/master && git branch all1 master && - test -z "$(git config branch.all1.merge)" && - git config branch.autosetupmerge all && - git branch all2 master && - test $(git config branch.all2.merge) = refs/heads/master + test -z "$(git config branch.all1.merge)" ' test_expect_success 'test overriding tracking setup via --no-track' \ @@ -167,10 +168,10 @@ test_expect_success 'test overriding tracking setup via --no-track' \ ! test "$(git config branch.my2.remote)" = local && ! test "$(git config branch.my2.merge)" = refs/heads/master' -test_expect_success 'test local tracking setup' \ +test_expect_success 'no tracking without .fetch entries' \ 'git branch --track my6 s && - test $(git config branch.my6.remote) = . && - test $(git config branch.my6.merge) = refs/heads/s' + test -z "$(git config branch.my6.remote)" && + test -z "$(git config branch.my6.merge)"' test_expect_success 'test tracking setup via --track but deeper' \ 'git config remote.local.url . && @@ -182,8 +183,8 @@ test_expect_success 'test tracking setup via --track but deeper' \ test_expect_success 'test deleting branch deletes branch config' \ 'git branch -d my7 && - test "$(git config branch.my7.remote)" = "" && - test "$(git config branch.my7.merge)" = ""' + test -z "$(git config branch.my7.remote)" && + test -z "$(git config branch.my7.merge)"' test_expect_success 'test deleting branch without config' \ 'git branch my7 s && From 73f893605050c291dd8c4d8f3f50b8fec47dcf51 Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Wed, 11 Jul 2007 22:02:25 -0500 Subject: [PATCH 166/213] Pack information tool This tool will print vaguely pretty information about a pack. It expects the output of "git-verify-pack -v" as input on stdin. $ git-verify-pack -v | packinfo.pl See the documentation in the script (contrib/stats/packinfo.pl) for more information. Signed-off-by: Brian Downing Signed-off-by: Junio C Hamano --- contrib/stats/packinfo.pl | 212 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100755 contrib/stats/packinfo.pl diff --git a/contrib/stats/packinfo.pl b/contrib/stats/packinfo.pl new file mode 100755 index 0000000000..792673a325 --- /dev/null +++ b/contrib/stats/packinfo.pl @@ -0,0 +1,212 @@ +#!/bin/perl +# +# This tool will print vaguely pretty information about a pack. It +# expects the output of "git-verify-pack -v" as input on stdin. +# +# $ git-verify-pack -v | packinfo.pl +# +# This prints some full-pack statistics; currently "all sizes", "all +# path sizes", "tree sizes", "tree path sizes", and "depths". +# +# * "all sizes" stats are across every object size in the file; +# full sizes for base objects, and delta size for deltas. +# * "all path sizes" stats are across all object's "path sizes". +# A path size is the sum of the size of the delta chain, including the +# base object. In other words, it's how many bytes need be read to +# reassemble the file from deltas. +# * "tree sizes" are object sizes grouped into delta trees. +# * "tree path sizes" are path sizes grouped into delta trees. +# * "depths" should be obvious. +# +# When run as: +# +# $ git-verify-pack -v | packinfo.pl -tree +# +# the trees of objects are output along with the stats. This looks +# like: +# +# 0 commit 031321c6... 803 803 +# +# 0 blob 03156f21... 1767 1767 +# 1 blob f52a9d7f... 10 1777 +# 2 blob a8cc5739... 51 1828 +# 3 blob 660e90b1... 15 1843 +# 4 blob 0cb8e3bb... 33 1876 +# 2 blob e48607f0... 311 2088 +# size: count 6 total 2187 min 10 max 1767 mean 364.50 median 51 std_dev 635.85 +# path size: count 6 total 11179 min 1767 max 2088 mean 1863.17 median 1843 std_dev 107.26 +# +# The first number after the sha1 is the object size, the second +# number is the path size. The statistics are across all objects in +# the previous delta tree. Obviously they are omitted for trees of +# one object. +# +# When run as: +# +# $ git-verify-pack -v | packinfo.pl -tree -filenames +# +# it adds filenames to the tree. Getting this information is slow: +# +# 0 blob 03156f21... 1767 1767 Documentation/git-lost-found.txt @ tags/v1.2.0~142 +# 1 blob f52a9d7f... 10 1777 Documentation/git-lost-found.txt @ tags/v1.5.0-rc1~74 +# 2 blob a8cc5739... 51 1828 Documentation/git-lost+found.txt @ tags/v0.99.9h^0 +# 3 blob 660e90b1... 15 1843 Documentation/git-lost+found.txt @ master~3222^2~2 +# 4 blob 0cb8e3bb... 33 1876 Documentation/git-lost+found.txt @ master~3222^2~3 +# 2 blob e48607f0... 311 2088 Documentation/git-lost-found.txt @ tags/v1.5.2-rc3~4 +# size: count 6 total 2187 min 10 max 1767 mean 364.50 median 51 std_dev 635.85 +# path size: count 6 total 11179 min 1767 max 2088 mean 1863.17 median 1843 std_dev 107.26 +# +# When run as: +# +# $ git-verify-pack -v | packinfo.pl -dump +# +# it prints out "sha1 size pathsize depth" for each sha1 in lexical +# order. +# +# 000079a2eaef17b7eae70e1f0f635557ea67b644 30 472 7 +# 00013cafe6980411aa6fdd940784917b5ff50f0a 44 1542 4 +# 000182eacf99cde27d5916aa415921924b82972c 499 499 0 +# ... +# +# This is handy for comparing two packs. Adding "-filenames" will add +# filenames, as per "-tree -filenames" above. + +use strict; +use Getopt::Long; + +my $filenames = 0; +my $tree = 0; +my $dump = 0; +GetOptions("tree" => \$tree, + "filenames" => \$filenames, + "dump" => \$dump); + +my %parents; +my %children; +my %sizes; +my @roots; +my %paths; +my %types; +my @commits; +my %names; +my %depths; +my @depths; + +while () { + my ($sha1, $type, $size, $offset, $depth, $parent) = split(/\s+/, $_); + next unless ($sha1 =~ /^[0-9a-f]{40}$/); + $depths{$sha1} = $depth || 0; + push(@depths, $depth || 0); + push(@commits, $sha1) if ($type eq 'commit'); + push(@roots, $sha1) unless $parent; + $parents{$sha1} = $parent; + $types{$sha1} = $type; + push(@{$children{$parent}}, $sha1); + $sizes{$sha1} = $size; +} + +if ($filenames && ($tree || $dump)) { + open(NAMES, "git-name-rev --all|"); + while () { + if (/^(\S+)\s+(.*)$/) { + my ($sha1, $name) = ($1, $2); + $names{$sha1} = $name; + } + } + close NAMES; + + for my $commit (@commits) { + my $name = $names{$commit}; + open(TREE, "git-ls-tree -t -r $commit|"); + print STDERR "Plumbing tree $name\n"; + while () { + if (/^(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) { + my ($mode, $type, $sha1, $path) = ($1, $2, $3, $4); + $paths{$sha1} = "$path @ $name"; + } + } + close TREE; + } +} + +sub stats { + my @data = sort {$a <=> $b} @_; + my $min = $data[0]; + my $max = $data[$#data]; + my $total = 0; + my $count = scalar @data; + for my $datum (@data) { + $total += $datum; + } + my $mean = $total / $count; + my $median = $data[int(@data / 2)]; + my $diff_sum = 0; + for my $datum (@data) { + $diff_sum += ($datum - $mean)**2; + } + my $std_dev = sqrt($diff_sum / $count); + return ($count, $total, $min, $max, $mean, $median, $std_dev); +} + +sub print_stats { + my $name = shift; + my ($count, $total, $min, $max, $mean, $median, $std_dev) = stats(@_); + printf("%s: count %s total %s min %s max %s mean %.2f median %s std_dev %.2f\n", + $name, $count, $total, $min, $max, $mean, $median, $std_dev); +} + +my @sizes; +my @path_sizes; +my @all_sizes; +my @all_path_sizes; +my %path_sizes; + +sub dig { + my ($sha1, $depth, $path_size) = @_; + $path_size += $sizes{$sha1}; + push(@sizes, $sizes{$sha1}); + push(@all_sizes, $sizes{$sha1}); + push(@path_sizes, $path_size); + push(@all_path_sizes, $path_size); + $path_sizes{$sha1} = $path_size; + if ($tree) { + printf("%3d%s %6s %s %8d %8d %s\n", + $depth, (" " x $depth), $types{$sha1}, + $sha1, $sizes{$sha1}, $path_size, $paths{$sha1}); + } + for my $child (@{$children{$sha1}}) { + dig($child, $depth + 1, $path_size); + } +} + +my @tree_sizes; +my @tree_path_sizes; + +for my $root (@roots) { + undef @sizes; + undef @path_sizes; + dig($root, 0, 0); + my ($aa, $sz_total) = stats(@sizes); + my ($bb, $psz_total) = stats(@path_sizes); + push(@tree_sizes, $sz_total); + push(@tree_path_sizes, $psz_total); + if ($tree) { + if (@sizes > 1) { + print_stats(" size", @sizes); + print_stats("path size", @path_sizes); + } + print "\n"; + } +} + +if ($dump) { + for my $sha1 (sort keys %sizes) { + print "$sha1 $sizes{$sha1} $path_sizes{$sha1} $depths{$sha1} $paths{$sha1}\n"; + } +} else { + print_stats(" all sizes", @all_sizes); + print_stats(" all path sizes", @all_path_sizes); + print_stats(" tree sizes", @tree_sizes); + print_stats("tree path sizes", @tree_path_sizes); + print_stats(" depths", @depths); +} From 975e0daf5edba09060147d643e628b8c89e1d467 Mon Sep 17 00:00:00 2001 From: Carlos Rica Date: Wed, 11 Jul 2007 20:50:34 +0200 Subject: [PATCH 167/213] Function stripspace now gets a buffer instead file descriptors. An implementation easier to call from builtins. It is designed to be used from the upcoming builtin-tag.c and builtin-commit.c, because both need to remove unwanted spaces from messages. Signed-off-by: Carlos Rica Signed-off-by: Junio C Hamano --- builtin-stripspace.c | 61 +++++++++++++++++++++++++++----------------- builtin.h | 2 +- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/builtin-stripspace.c b/builtin-stripspace.c index d8358e28f0..0c970aa945 100644 --- a/builtin-stripspace.c +++ b/builtin-stripspace.c @@ -2,12 +2,11 @@ #include "cache.h" /* - * Remove trailing spaces from a line. + * Returns the length of a line, without trailing spaces. * * If the line ends with newline, it will be removed too. - * Returns the new length of the string. */ -static int cleanup(char *line, int len) +static size_t cleanup(char *line, size_t len) { if (len) { if (line[len - 1] == '\n') @@ -19,7 +18,6 @@ static int cleanup(char *line, int len) break; len--; } - line[len] = 0; } return len; } @@ -28,52 +26,67 @@ static int cleanup(char *line, int len) * Remove empty lines from the beginning and end * and also trailing spaces from every line. * + * Note that the buffer will not be NUL-terminated. + * * Turn multiple consecutive empty lines between paragraphs * into just one empty line. * * If the input has only empty lines and spaces, * no output will be produced. * + * If last line has a newline at the end, it will be removed. + * * Enable skip_comments to skip every line starting with "#". */ -void stripspace(FILE *in, FILE *out, int skip_comments) +size_t stripspace(char *buffer, size_t length, int skip_comments) { int empties = -1; - int alloc = 1024; - char *line = xmalloc(alloc); + size_t i, j, len, newlen; + char *eol; - while (fgets(line, alloc, in)) { - int len = strlen(line); + for (i = j = 0; i < length; i += len, j += newlen) { + eol = memchr(buffer + i, '\n', length - i); + len = eol ? eol - (buffer + i) + 1 : length - i; - while (len == alloc - 1 && line[len - 1] != '\n') { - alloc = alloc_nr(alloc); - line = xrealloc(line, alloc); - fgets(line + len, alloc - len, in); - len += strlen(line + len); - } - - if (skip_comments && line[0] == '#') + if (skip_comments && len && buffer[i] == '#') { + newlen = 0; continue; - len = cleanup(line, len); + } + newlen = cleanup(buffer + i, len); /* Not just an empty line? */ - if (len) { + if (newlen) { + if (empties != -1) + buffer[j++] = '\n'; if (empties > 0) - fputc('\n', out); + buffer[j++] = '\n'; empties = 0; - fputs(line, out); - fputc('\n', out); + memmove(buffer + j, buffer + i, newlen); continue; } if (empties < 0) continue; empties++; } - free(line); + + return j; } int cmd_stripspace(int argc, const char **argv, const char *prefix) { - stripspace(stdin, stdout, 0); + char *buffer; + unsigned long size; + + size = 1024; + buffer = xmalloc(size); + if (read_pipe(0, &buffer, &size)) + die("could not read the input"); + + size = stripspace(buffer, size, 0); + write_or_die(1, buffer, size); + if (size) + putc('\n', stdout); + + free(buffer); return 0; } diff --git a/builtin.h b/builtin.h index 661a92f787..4cc228dace 100644 --- a/builtin.h +++ b/builtin.h @@ -7,7 +7,7 @@ extern const char git_version_string[]; extern const char git_usage_string[]; extern void help_unknown_cmd(const char *cmd); -extern void stripspace(FILE *in, FILE *out, int skip_comments); +extern size_t stripspace(char *buffer, size_t length, int skip_comments); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); extern void prune_packed_objects(int); From d972cce06da6e4e6cfcdce8417910bb4a7772ae2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 11 Jul 2007 22:52:45 -0700 Subject: [PATCH 168/213] Re-code builtin-branch.c in UTF-8 Signed-off-by: Junio C Hamano --- builtin-branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin-branch.c b/builtin-branch.c index 3f9e7c2def..5f5c1823cb 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -1,7 +1,7 @@ /* * Builtin "git branch" * - * Copyright (c) 2006 Kristian Hgsberg + * Copyright (c) 2006 Kristian Høgsberg * Based on git-branch.sh by Junio C Hamano. */ From b215883de9322b8b475a04b4768d6ba5455373d1 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 12 Jul 2007 02:45:23 -0400 Subject: [PATCH 169/213] git-gui: Change prior tree SHA-1 verification to use git_read This cat-file was done on maint, where we did not have git_read available to us. But here on master we do, so we should make use of it. Signed-off-by: Shawn O. Pearce --- lib/commit.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commit.tcl b/lib/commit.tcl index 3172d7cb60..46a78c158f 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -258,7 +258,7 @@ proc commit_committree {fd_wt curHEAD msg} { # -- Verify this wasn't an empty change. # if {$commit_type eq {normal}} { - set fd_ot [open "| git cat-file commit $PARENT" r] + set fd_ot [git_read cat-file commit $PARENT] fconfigure $fd_ot -encoding binary -translation lf set old_tree [gets $fd_ot] close $fd_ot From cdaee5db165ba8bae8d3b524950e61666fc36a84 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 12 Jul 2007 22:29:49 +1000 Subject: [PATCH 170/213] gitk: Improve handling of -- and ambiguous arguments This makes gitk more consistent with git rev-list and git log in its handling of arguments that could be either a revision or a filename; now gitk displays an error message and quits, rather than treating it as a revision and getting an error in the underlying git log. Now gitk always passes "--" to git log even if no filenames are being specified. It also makes gitk display errors in invoking git log in a window rather than on stderr, and makes gitk stop looking for a -d flag when it sees a "--" argument. Signed-off-by: Paul Mackerras --- gitk | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/gitk b/gitk index 468cf32228..b9219c2c70 100755 --- a/gitk +++ b/gitk @@ -87,19 +87,15 @@ proc start_rev_list {view} { set startmsecs [clock clicks -milliseconds] set commitidx($view) 0 - set args $viewargs($view) - if {$viewfiles($view) ne {}} { - set args [concat $args "--" $viewfiles($view)] - } set order "--topo-order" if {$datemode} { set order "--date-order" } if {[catch { - set fd [open [concat | git log -z --pretty=raw $order \ - --parents --boundary $args] r] + set fd [open [concat | git log -z --pretty=raw $order --parents \ + --boundary $viewargs($view) "--" $viewfiles($view)] r] } err]} { - puts stderr "Error executing git rev-list: $err" + error_popup "Error executing git rev-list: $err" exit 1 } set commfd($view) $fd @@ -7471,17 +7467,6 @@ catch {source ~/.gitk} font create optionfont -family sans-serif -size -12 -set revtreeargs {} -foreach arg $argv { - switch -regexp -- $arg { - "^$" { } - "^-d" { set datemode 1 } - default { - lappend revtreeargs $arg - } - } -} - # check that we can find a .git directory somewhere... set gitdir [gitdir] if {![file isdirectory $gitdir]} { @@ -7489,17 +7474,41 @@ if {![file isdirectory $gitdir]} { exit 1 } +set revtreeargs {} set cmdline_files {} -set i [lsearch -exact $revtreeargs "--"] -if {$i >= 0} { - set cmdline_files [lrange $revtreeargs [expr {$i + 1}] end] - set revtreeargs [lrange $revtreeargs 0 [expr {$i - 1}]] -} elseif {$revtreeargs ne {}} { +set i 0 +foreach arg $argv { + switch -regexp -- $arg { + "^$" { } + "^-d" { set datemode 1 } + "--" { + set cmdline_files [lrange $argv [expr {$i + 1}] end] + break + } + default { + lappend revtreeargs $arg + } + } + incr i +} + +if {$i >= [llength $argv] && $revtreeargs ne {}} { + # no -- on command line, but some arguments (other than -d) if {[catch { set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs] set cmdline_files [split $f "\n"] set n [llength $cmdline_files] set revtreeargs [lrange $revtreeargs 0 end-$n] + # Unfortunately git rev-parse doesn't produce an error when + # something is both a revision and a filename. To be consistent + # with git log and git rev-list, check revtreeargs for filenames. + foreach arg $revtreeargs { + if {[file exists $arg]} { + show_error {} . "Ambiguous argument '$arg': both revision\ + and filename" + exit 1 + } + } } err]} { # unfortunately we get both stdout and stderr in $err, # so look for "fatal:". From baafd6e76522d4f20c9e1755537005f1cfd2f492 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 12 Jul 2007 14:17:26 -0700 Subject: [PATCH 171/213] Update list of older git docs --- Documentation/git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/git.txt b/Documentation/git.txt index 10c7bb3f45..33614ec050 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -42,9 +42,10 @@ unreleased) version of git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.5.2.3/git.html[documentation for release 1.5.2.3] +* link:v1.5.2.4/git.html[documentation for release 1.5.2.4] * release notes for + link:RelNotes-1.5.2.4.txt[1.5.2.4], link:RelNotes-1.5.2.3.txt[1.5.2.3], link:RelNotes-1.5.2.2.txt[1.5.2.2], link:RelNotes-1.5.2.1.txt[1.5.2.1], From c83f032e09e49e5bc60686663f7c78d36f72cef4 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 12 Jul 2007 14:33:21 -0400 Subject: [PATCH 172/213] apply delta depth bias to already deltified objects We already apply a bias on the initial delta attempt with max_size being a function of the base object depth. This has the effect of favoring shallower deltas even if deeper deltas could be smaller, and therefore creating a wider delta tree (see commits 4e8da195 and c3b06a69). This principle should also be applied to all delta attempts for the same object and not only the first attempt. With this the criteria for the best delta is not only its size but also its depth, so that a shallower delta might be selected even if it is larger than a deeper one. Even if some deltas get larger, they allow for wider delta trees making the depth limit less quickly reached and therefore better deltas can be subsequently found, keeping the resulting pack size even smaller. Runtime access to the pack should also benefit from shallower deltas. Testing on different repositories showed slighter faster repacks, smaller resulting packs, and a much nicer curve for delta depth distribution with no more peak at the maximum depth level. Improvements are even more significant with smaller depth limits. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- builtin-pack-objects.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 54b9d268da..b4f3e7c2eb 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1303,6 +1303,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, struct object_entry *trg_entry = trg->entry; struct object_entry *src_entry = src->entry; unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz; + unsigned ref_depth; enum object_type type; void *delta_buf; @@ -1332,12 +1333,17 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, /* Now some size filtering heuristics. */ trg_size = trg_entry->size; - max_size = trg_size/2 - 20; - max_size = max_size * (max_depth - src_entry->depth) / max_depth; + if (!trg_entry->delta) { + max_size = trg_size/2 - 20; + ref_depth = 1; + } else { + max_size = trg_entry->delta_size; + ref_depth = trg_entry->depth; + } + max_size = max_size * (max_depth - src_entry->depth) / + (max_depth - ref_depth + 1); if (max_size == 0) return 0; - if (trg_entry->delta && trg_entry->delta_size <= max_size) - max_size = trg_entry->delta_size; src_size = src_entry->size; sizediff = src_size < trg_size ? trg_size - src_size : 0; if (sizediff >= max_size) From 750bd6ac350079cf1f76c24acb7686ad89a95102 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 12 Jul 2007 03:40:18 -0400 Subject: [PATCH 173/213] script to display a distribution of longest common hash prefixes This script was originally posted on the git mailing list by Randal L. Schwartz . Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- contrib/stats/git-common-hash | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 contrib/stats/git-common-hash diff --git a/contrib/stats/git-common-hash b/contrib/stats/git-common-hash new file mode 100755 index 0000000000..e27fd088be --- /dev/null +++ b/contrib/stats/git-common-hash @@ -0,0 +1,26 @@ +#!/bin/sh + +# This script displays the distribution of longest common hash prefixes. +# This can be used to determine the minimum prefix length to use +# for object names to be unique. + +git rev-list --objects --all | sort | perl -lne ' + substr($_, 40) = ""; + # uncomment next line for a distribution of bits instead of hex chars + # $_ = unpack("B*",pack("H*",$_)); + if (defined $p) { + ($p ^ $_) =~ /^(\0*)/; + $common = length $1; + if (defined $pcommon) { + $count[$pcommon > $common ? $pcommon : $common]++; + } else { + $count[$common]++; # first item + } + } + $p = $_; + $pcommon = $common; + END { + $count[$common]++; # last item + print "$_: $count[$_]" for 0..$#count; + } +' From b492bbd8362840f9ac1e5389cdfaa8dd73ca793b Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Thu, 12 Jul 2007 09:16:11 -0500 Subject: [PATCH 174/213] Correct shebang line for contrib/stats/packinfo.pl "/bin/perl"? What was I thinking? Signed-off-by: Brian Downing Signed-off-by: Junio C Hamano --- contrib/stats/packinfo.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/stats/packinfo.pl b/contrib/stats/packinfo.pl index 792673a325..aab501ea08 100755 --- a/contrib/stats/packinfo.pl +++ b/contrib/stats/packinfo.pl @@ -1,4 +1,4 @@ -#!/bin/perl +#!/usr/bin/perl # # This tool will print vaguely pretty information about a pack. It # expects the output of "git-verify-pack -v" as input on stdin. From a1dab41af4c575bb72231c73df26ecb2af4814d6 Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Thu, 12 Jul 2007 07:55:47 -0500 Subject: [PATCH 175/213] Don't try to delta if target is much smaller than source Add a new try_delta heuristic. Don't bother trying to make a delta if the target object size is much smaller (currently 1/32) than the source, as it's very likely not going to get a match. Even if it does, you will have to read at least 32x the size of the new file to reassemble it, which isn't such a good deal. This leads to a considerable performance improvement when deltifying a mix of small and large files with a very large window, because you don't have to wait for the large files to percolate out of the window before things start going fast again. Signed-off-by: Brian Downing Acked-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- builtin-pack-objects.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index b4f3e7c2eb..54f304c115 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1348,6 +1348,8 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, sizediff = src_size < trg_size ? trg_size - src_size : 0; if (sizediff >= max_size) return 0; + if (trg_size < src_size / 32) + return 0; /* Load data if not already done */ if (!trg->data) { From 11779e79078c9da604753e570d02134c8d4bae6a Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Thu, 12 Jul 2007 07:55:48 -0500 Subject: [PATCH 176/213] Support fetching the memory usage of a delta index Delta indices, at least on 64-bit platforms, tend to be larger than the actual uncompressed data. As such, keeping track of this storage is important if you want to successfully limit the memory size of your pack window. Squirrel away the total allocation size inside the delta_index struct, and add an accessor "sizeof_delta_index" to access it. Signed-off-by: Brian Downing Acked-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- delta.h | 7 +++++++ diff-delta.c | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/delta.h b/delta.h index 7b3f86d85f..40ccf5a1e9 100644 --- a/delta.h +++ b/delta.h @@ -23,6 +23,13 @@ create_delta_index(const void *buf, unsigned long bufsize); */ extern void free_delta_index(struct delta_index *index); +/* + * sizeof_delta_index: returns memory usage of delta index + * + * Given pointer must be what create_delta_index() returned, or NULL. + */ +extern unsigned long sizeof_delta_index(struct delta_index *index); + /* * create_delta: create a delta from given index for the given buffer * diff --git a/diff-delta.c b/diff-delta.c index faf96e4713..3af583536f 100644 --- a/diff-delta.c +++ b/diff-delta.c @@ -119,6 +119,7 @@ struct index_entry { }; struct delta_index { + unsigned long memsize; const void *src_buf; unsigned long src_size; unsigned int hash_mask; @@ -159,6 +160,7 @@ struct delta_index * create_delta_index(const void *buf, unsigned long bufsize) mem = hash + hsize; entry = mem; + index->memsize = memsize; index->src_buf = buf; index->src_size = bufsize; index->hash_mask = hmask; @@ -228,6 +230,14 @@ void free_delta_index(struct delta_index *index) free(index); } +unsigned long sizeof_delta_index(struct delta_index *index) +{ + if (index) + return index->memsize; + else + return 0; +} + /* * The maximum size for any opcode sequence, including the initial header * plus Rabin window plus biggest copy. From 0b87b6e081e75170ffa40e92aebde1e22ad3161e Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Thu, 12 Jul 2007 08:32:26 -0500 Subject: [PATCH 177/213] Add functions for parsing integers with size suffixes Split out the nnn{k,m,g} parsing code from git_config_int into git_parse_long, so command-line parameters can enjoy the same functionality. Also add get_parse_ulong for unsigned values. Make git_config_int use git_parse_long, and add get_config_ulong as well. Signed-off-by: Brian Downing Acked-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- cache.h | 3 +++ config.c | 56 +++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/cache.h b/cache.h index e64071e2e3..917a7e34f1 100644 --- a/cache.h +++ b/cache.h @@ -521,7 +521,10 @@ typedef int (*config_fn_t)(const char *, const char *); extern int git_default_config(const char *, const char *); extern int git_config_from_file(config_fn_t fn, const char *); extern int git_config(config_fn_t fn); +extern int git_parse_long(const char *, long *); +extern int git_parse_ulong(const char *, unsigned long *); extern int git_config_int(const char *, const char *); +extern unsigned long git_config_ulong(const char *, const char *); extern int git_config_bool(const char *, const char *); extern int git_config_set(const char *, const char *); extern int git_config_set_multivar(const char *, const char *, const char *, int); diff --git a/config.c b/config.c index 561ee3b576..f89a611915 100644 --- a/config.c +++ b/config.c @@ -233,21 +233,55 @@ static int git_parse_file(config_fn_t fn) die("bad config file line %d in %s", config_linenr, config_file_name); } -int git_config_int(const char *name, const char *value) +static unsigned long get_unit_factor(const char *end) +{ + if (!*end) + return 1; + else if (!strcasecmp(end, "k")) + return 1024; + else if (!strcasecmp(end, "m")) + return 1024 * 1024; + else if (!strcasecmp(end, "g")) + return 1024 * 1024 * 1024; + die("unknown unit: '%s'", end); +} + +int git_parse_long(const char *value, long *ret) { if (value && *value) { char *end; - int val = strtol(value, &end, 0); - if (!*end) - return val; - if (!strcasecmp(end, "k")) - return val * 1024; - if (!strcasecmp(end, "m")) - return val * 1024 * 1024; - if (!strcasecmp(end, "g")) - return val * 1024 * 1024 * 1024; + long val = strtol(value, &end, 0); + *ret = val * get_unit_factor(end); + return 1; } - die("bad config value for '%s' in %s", name, config_file_name); + return 0; +} + +int git_parse_ulong(const char *value, unsigned long *ret) +{ + if (value && *value) { + char *end; + unsigned long val = strtoul(value, &end, 0); + *ret = val * get_unit_factor(end); + return 1; + } + return 0; +} + +int git_config_int(const char *name, const char *value) +{ + long ret; + if (!git_parse_long(value, &ret)) + die("bad config value for '%s' in %s", name, config_file_name); + return ret; +} + +unsigned long git_config_ulong(const char *name, const char *value) +{ + unsigned long ret; + if (!git_parse_ulong(value, &ret)) + die("bad config value for '%s' in %s", name, config_file_name); + return ret; } int git_config_bool(const char *name, const char *value) From a97773ce7e4fb635615d3b363f144d8c8a780fea Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Thu, 12 Jul 2007 08:07:46 -0500 Subject: [PATCH 178/213] Add pack-objects window memory usage limit This adds an option (--window-memory=N) and configuration variable (pack.windowMemory = N) to limit the memory size of the pack-objects delta search window. This works by removing the oldest unpacked objects whenever the total size goes above the limit. It will always leave at least one object, though, so as not to completely eliminate the possibility of computing deltas. This is an extra limit on top of the normal window size (--window=N); the window will not dynamically grow above the fixed number of entries specified to fill the memory limit. With this, repacking a repository with a mix of large and small objects is possible even with a very large window. Cleaner and correct circular buffer handling courtesy of Nicolas Pitre. Signed-off-by: Brian Downing Acked-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- builtin-pack-objects.c | 52 +++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 54f304c115..a94ec78971 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -16,8 +16,9 @@ #include "progress.h" static const char pack_usage[] = "\ -git-pack-objects [{ -q | --progress | --all-progress }] [--max-pack-size=N] \n\ - [--local] [--incremental] [--window=N] [--depth=N] \n\ +git-pack-objects [{ -q | --progress | --all-progress }] \n\ + [--max-pack-size=N] [--local] [--incremental] \n\ + [--window=N] [--window-memory=N] [--depth=N] \n\ [--no-reuse-delta] [--no-reuse-object] [--delta-base-offset] \n\ [--non-empty] [--revs [--unpacked | --all]*] [--reflog] \n\ [--stdout | base-name] [idx.sha1), sz, trg_size); + window_memory_usage += sz; } if (!src->data) { src->data = read_sha1_file(src_entry->idx.sha1, &type, &sz); if (sz != src_size) die("object %s inconsistent object length (%lu vs %lu)", sha1_to_hex(src_entry->idx.sha1), sz, src_size); + window_memory_usage += sz; } if (!src->index) { src->index = create_delta_index(src->data, src_size); @@ -1372,6 +1378,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, warning("suboptimal pack - out of memory"); return 0; } + window_memory_usage += sizeof_delta_index(src->index); } delta_buf = create_delta(src->index, trg->data, trg_size, &delta_size, max_size); @@ -1414,9 +1421,22 @@ static unsigned int check_delta_limit(struct object_entry *me, unsigned int n) return m; } +static void free_unpacked(struct unpacked *n) +{ + window_memory_usage -= sizeof_delta_index(n->index); + free_delta_index(n->index); + n->index = NULL; + if (n->data) { + free(n->data); + n->data = NULL; + window_memory_usage -= n->entry->size; + } + n->entry = NULL; +} + static void find_deltas(struct object_entry **list, int window, int depth) { - uint32_t i = nr_objects, idx = 0, processed = 0; + uint32_t i = nr_objects, idx = 0, count = 0, processed = 0; unsigned int array_size = window * sizeof(struct unpacked); struct unpacked *array; int max_depth; @@ -1451,12 +1471,17 @@ static void find_deltas(struct object_entry **list, int window, int depth) if (entry->no_try_delta) continue; - free_delta_index(n->index); - n->index = NULL; - free(n->data); - n->data = NULL; + free_unpacked(n); n->entry = entry; + while (window_memory_limit && + window_memory_usage > window_memory_limit && + count > 1) { + uint32_t tail = (idx + window - count) % window; + free_unpacked(array + tail); + count--; + } + /* * If the current object is at pack edge, take the depth the * objects that depend on the current object into account @@ -1491,6 +1516,8 @@ static void find_deltas(struct object_entry **list, int window, int depth) next: idx++; + if (count + 1 < window) + count++; if (idx >= window) idx = 0; } while (i > 0); @@ -1529,7 +1556,11 @@ static int git_pack_config(const char *k, const char *v) window = git_config_int(k, v); return 0; } - if(!strcmp(k, "pack.depth")) { + if (!strcmp(k, "pack.windowmemory")) { + window_memory_limit = git_config_ulong(k, v); + return 0; + } + if (!strcmp(k, "pack.depth")) { depth = git_config_int(k, v); return 0; } @@ -1705,6 +1736,11 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) usage(pack_usage); continue; } + if (!prefixcmp(arg, "--window-memory=")) { + if (!git_parse_ulong(arg+16, &window_memory_limit)) + usage(pack_usage); + continue; + } if (!prefixcmp(arg, "--depth=")) { char *end; depth = strtoul(arg+8, &end, 0); From 121b42a5b4839c7d8756b0da3e6ed18e720b1295 Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Thu, 12 Jul 2007 07:55:51 -0500 Subject: [PATCH 179/213] Add --window-memory option to git-repack Signed-off-by: Brian Downing Acked-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- git-repack.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git-repack.sh b/git-repack.sh index b5c667110d..156c5e8f4a 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Linus Torvalds # -USAGE='[-a] [-d] [-f] [-l] [-n] [-q] [--max-pack-size=N] [--window=N] [--depth=N]' +USAGE='[-a] [-d] [-f] [-l] [-n] [-q] [--max-pack-size=N] [--window=N] [--window-memory=N] [--depth=N]' SUBDIRECTORY_OK='Yes' . git-sh-setup @@ -20,6 +20,7 @@ do -l) local=--local ;; --max-pack-size=*) extra="$extra $1" ;; --window=*) extra="$extra $1" ;; + --window-memory=*) extra="$extra $1" ;; --depth=*) extra="$extra $1" ;; *) usage ;; esac From e93b15cd7441369f28dd4841ab504cea83c18b10 Mon Sep 17 00:00:00 2001 From: Brian Downing Date: Thu, 12 Jul 2007 07:55:52 -0500 Subject: [PATCH 180/213] Add documentation for --window-memory, pack.windowMemory Signed-off-by: Brian Downing Acked-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- Documentation/config.txt | 6 ++++++ Documentation/git-pack-objects.txt | 11 +++++++++++ Documentation/git-repack.txt | 11 +++++++++++ 3 files changed, 28 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 4b67f0adf7..11b332117c 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -589,6 +589,12 @@ pack.depth:: The maximum delta depth used by gitlink:git-pack-objects[1] when no maximum depth is given on the command line. Defaults to 50. +pack.windowMemory:: + The window memory size limit used by gitlink:git-pack-objects[1] + when no limit is given on the command line. The value can be + suffixed with "k", "m", or "g". Defaults to 0, meaning no + limit. + pack.compression:: An integer -1..9, indicating the compression level for objects in a pack file. -1 is the zlib default. 0 means no diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt index e3549b5044..6f17cff24a 100644 --- a/Documentation/git-pack-objects.txt +++ b/Documentation/git-pack-objects.txt @@ -85,6 +85,17 @@ base-name:: times to get to the necessary object. The default value for --window is 10 and --depth is 50. +--window-memory=[N]:: + This option provides an additional limit on top of `--window`; + the window size will dynamically scale down so as to not take + up more than N bytes in memory. This is useful in + repositories with a mix of large and small objects to not run + out of memory with a large window, but still be able to take + advantage of the large window for the smaller objects. The + size can be suffixed with "k", "m", or "g". + `--window-memory=0` makes memory usage unlimited, which is the + default. + --max-pack-size=:: Maximum size of each output packfile, expressed in MiB. If specified, multiple packfiles may be created. diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index 28949397ca..5283ef84a9 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -68,6 +68,17 @@ OPTIONS to be applied that many times to get to the necessary object. The default value for --window is 10 and --depth is 50. +--window-memory=[N]:: + This option provides an additional limit on top of `--window`; + the window size will dynamically scale down so as to not take + up more than N bytes in memory. This is useful in + repositories with a mix of large and small objects to not run + out of memory with a large window, but still be able to take + advantage of the large window for the smaller objects. The + size can be suffixed with "k", "m", or "g". + `--window-memory=0` makes memory usage unlimited, which is the + default. + --max-pack-size=:: Maximum size of each output packfile, expressed in MiB. If specified, multiple packfiles may be created. From 5a235b5ed02fa0f9f67c4fbec703e3126eb3c7f5 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 12 Jul 2007 17:07:59 -0400 Subject: [PATCH 181/213] reduce git-pack-objects memory usage a little more The delta depth doesn't have to be stored in the global object array structure since it is only used during the deltification pass. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- builtin-pack-objects.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index a94ec78971..a43d6040ca 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -26,9 +26,6 @@ git-pack-objects [{ -q | --progress | --all-progress }] \n\ struct object_entry { struct pack_idx_entry idx; unsigned long size; /* uncompressed size */ - - unsigned int hash; /* name hint hash */ - unsigned int depth; /* delta depth */ struct packed_git *in_pack; /* already in pack */ off_t in_pack_offset; struct object_entry *delta; /* delta base object */ @@ -38,6 +35,7 @@ struct object_entry { */ void *delta_data; /* cached delta (uncompressed) */ unsigned long delta_size; /* delta data size (uncompressed) */ + unsigned int hash; /* name hint hash */ enum object_type type; enum object_type in_pack_type; /* could be delta */ unsigned char in_pack_header_size; @@ -1274,6 +1272,7 @@ struct unpacked { struct object_entry *entry; void *data; struct delta_index *index; + unsigned depth; }; static int delta_cacheable(struct unpacked *trg, struct unpacked *src, @@ -1332,7 +1331,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, return 0; /* Let's not bust the allowed depth. */ - if (src_entry->depth >= max_depth) + if (src->depth >= max_depth) return 0; /* Now some size filtering heuristics. */ @@ -1342,9 +1341,9 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, ref_depth = 1; } else { max_size = trg_entry->delta_size; - ref_depth = trg_entry->depth; + ref_depth = trg->depth; } - max_size = max_size * (max_depth - src_entry->depth) / + max_size = max_size * (max_depth - src->depth) / (max_depth - ref_depth + 1); if (max_size == 0) return 0; @@ -1388,17 +1387,17 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, if (trg_entry->delta_data) { /* Prefer only shallower same-sized deltas. */ if (delta_size == trg_entry->delta_size && - src_entry->depth + 1 >= trg_entry->depth) { + src->depth + 1 >= trg->depth) { free(delta_buf); return 0; } delta_cache_size -= trg_entry->delta_size; free(trg_entry->delta_data); + trg_entry->delta_data = NULL; } - trg_entry->delta_data = 0; trg_entry->delta = src_entry; trg_entry->delta_size = delta_size; - trg_entry->depth = src_entry->depth + 1; + trg->depth = src->depth + 1; if (delta_cacheable(src, trg, src_size, trg_size, delta_size)) { trg_entry->delta_data = xrealloc(delta_buf, delta_size); @@ -1511,7 +1510,7 @@ static void find_deltas(struct object_entry **list, int window, int depth) * depth, leaving it in the window is pointless. we * should evict it first. */ - if (entry->delta && depth <= entry->depth) + if (entry->delta && depth <= n->depth) continue; next: From 4f50f6a966dc9a1ff7d11b2ca5eb116fa9dd139a Mon Sep 17 00:00:00 2001 From: Steven Walter Date: Thu, 12 Jul 2007 10:52:30 -0400 Subject: [PATCH 182/213] Documentation for git-log --follow After vainly searching the Documentation for how to follow renames, I finally broke down and grepped the source. It would appear that Linus didn't add write and docs for this feature when he wrote it. The following patch rectifies that, hopefully sparing future users from resorting to the source code. Signed-off-by: Steven Walter Signed-off-by: Junio C Hamano --- Documentation/git-log.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 7adcdefacf..63c1dbe812 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -61,6 +61,9 @@ include::pretty-options.txt[] the specified paths; this means that "..." limits only commits, and doesn't limit diff for those commits. +--follow:: + Continue listing the history of a file beyond renames. + ...:: Show only commits that affect the specified paths. @@ -91,6 +94,12 @@ git log -r --name-status release..test:: in the "release" branch, along with the list of paths each commit modifies. +git log --follow builtin-rev-list.c:: + + Shows the commits that changed builtin-rev-list.c, including + those commits that occurred before the file was given its + present name. + Discussion ---------- From 248c648a0de945ec37af13e0a9b8671da525c323 Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Thu, 12 Jul 2007 16:48:48 +0200 Subject: [PATCH 183/213] Add missing functions to contrib/emacs/vc-git.el This is necessary to make several editing functions work, like C-u C-x v = Signed-off-by: David Kastrup Signed-off-by: Junio C Hamano --- contrib/emacs/vc-git.el | 65 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/contrib/emacs/vc-git.el b/contrib/emacs/vc-git.el index e456ab9712..b8f6be5c0a 100644 --- a/contrib/emacs/vc-git.el +++ b/contrib/emacs/vc-git.el @@ -81,6 +81,71 @@ (match-string 2 str) str))) +(defun vc-git-symbolic-commit (commit) + "Translate COMMIT string into symbolic form. +Returns nil if not possible." + (and commit + (with-temp-buffer + (and + (zerop + (call-process "git" nil '(t nil) nil "name-rev" + "--name-only" "--tags" + commit)) + (goto-char (point-min)) + (= (forward-line 2) 1) + (bolp) + (buffer-substring-no-properties (point-min) (1- (point-max))))))) + +(defun vc-git-previous-version (file rev) + "git-specific version of `vc-previous-version'." + (let ((default-directory (file-name-directory (expand-file-name file))) + (file (file-name-nondirectory file))) + (vc-git-symbolic-commit + (with-temp-buffer + (and + (zerop + (call-process "git" nil '(t nil) nil "rev-list" + "-2" rev "--" file)) + (goto-char (point-max)) + (bolp) + (zerop (forward-line -1)) + (not (bobp)) + (buffer-substring-no-properties + (point) + (1- (point-max)))))))) + +(defun vc-git-next-version (file rev) + "git-specific version of `vc-next-version'." + (let* ((default-directory (file-name-directory + (expand-file-name file))) + (file (file-name-nondirectory file)) + (current-rev + (with-temp-buffer + (and + (zerop + (call-process "git" nil '(t nil) nil "rev-list" + "-1" rev "--" file)) + (goto-char (point-max)) + (bolp) + (zerop (forward-line -1)) + (bobp) + (buffer-substring-no-properties + (point) + (1- (point-max))))))) + (and current-rev + (vc-git-symbolic-commit + (with-temp-buffer + (and + (zerop + (call-process "git" nil '(t nil) nil "rev-list" + "HEAD" "--" file)) + (goto-char (point-min)) + (search-forward current-rev nil t) + (zerop (forward-line -1)) + (buffer-substring-no-properties + (point) + (progn (forward-line 1) (1- (point)))))))))) + (defun vc-git-revert (file &optional contents-done) "Revert FILE to the version stored in the git repository." (if contents-done From 868bc068bb45e3b9d135151f2126ce3dba849426 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 12 Jul 2007 20:39:27 +0200 Subject: [PATCH 184/213] gitweb: new cgi parameter: opt Currently the only supported value is '--no-merges' for the 'rss', 'atom', 'log', 'shortlog' and 'history' actions, but it can be easily extended to allow other parameters for other actions. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 27580b5670..c8ba3a27a3 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -386,6 +386,23 @@ if (defined $hash_base) { } } +my %allowed_options = ( + "--no-merges" => [ qw(rss atom log shortlog history) ], +); + +our @extra_options = $cgi->param('opt'); +if (defined @extra_options) { + foreach(@extra_options) + { + if (not grep(/^$_$/, keys %allowed_options)) { + die_error(undef, "Invalid option parameter"); + } + if (not grep(/^$action$/, @{$allowed_options{$_}})) { + die_error(undef, "Invalid option parameter for this action"); + } + } +} + our $hash_parent_base = $cgi->param('hpb'); if (defined $hash_parent_base) { if (!validate_refname($hash_parent_base)) { @@ -537,6 +554,7 @@ sub href(%) { action => "a", file_name => "f", file_parent => "fp", + extra_options => "opt", hash => "h", hash_parent => "hp", hash_base => "hb", @@ -1773,6 +1791,7 @@ sub parse_commits { ($arg ? ($arg) : ()), ("--max-count=" . $maxcount), ("--skip=" . $skip), + @extra_options, $commit_id, "--", ($filename ? ($filename) : ()) From 61c3f9086a733124258168f5c8e7437e3c56f3c3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 12 Jul 2007 14:54:33 -0700 Subject: [PATCH 185/213] GIT v1.5.3-rc1 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.3.txt | 10 +++++++++- GIT-VERSION-GEN | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/RelNotes-1.5.3.txt b/Documentation/RelNotes-1.5.3.txt index e2e809e3c8..63e33b9d27 100644 --- a/Documentation/RelNotes-1.5.3.txt +++ b/Documentation/RelNotes-1.5.3.txt @@ -21,6 +21,9 @@ Updates since v1.5.2 * New commands and options. + - The hunk header output from "git diff" family can be customized + with the attributes mechanism. See gitattributes(5) for details. + - "git stash" allows you to quickly save away your work in progress and replay it later on an updated state. @@ -184,6 +187,11 @@ Updates since v1.5.2 small enough delta results it creates while looking for the best delta candidates. + - git-pack-objects learned a new heuristcs to prefer delta + that is shallower in depth over the smallest delta + possible. This improves both overall packfile access + performance and packfile density. + - diff-delta code that is used for packing has been improved to work better on big files. @@ -210,6 +218,6 @@ this release, unless otherwise noted. -- exec >/var/tmp/1 -O=v1.5.3-rc0 +O=v1.5.3-rc1 echo O=`git describe refs/heads/master` git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 06c360b267..3c0032cec5 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.5.2.GIT +DEF_VER=v1.5.3.GIT LF=' ' From 7d7baa5e15b9ad6768d782d9bae5badc4e51d4ea Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 12 Jul 2007 22:27:12 -0400 Subject: [PATCH 186/213] Pack-objects: properly initialize the depth value Commit 5a235b5e was missing this little detail. Otherwise your pack will explode. Problem noted by Brian Downing. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- builtin-pack-objects.c | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index a43d6040ca..5e9d1fd86c 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1431,6 +1431,7 @@ static void free_unpacked(struct unpacked *n) window_memory_usage -= n->entry->size; } n->entry = NULL; + n->depth = 0; } static void find_deltas(struct object_entry **list, int window, int depth) From dbddb714b0e69ef15fba64e74f34244ab95f0610 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 13 Jul 2007 01:54:06 +0200 Subject: [PATCH 187/213] Update git-merge documentation. Add "Configuration" section to describe merge.summary configuration variable (which is mentioned in git-fmt-merge-msg(1) man page, but it is a plumbing command), and merge.verbosity configuration variable (so there is a place to make reference from "Environment Variables" section of git(7) man page) to the git-merge(1) man page. Also describe GIT_MERGE_VERBOSITY environment. The configuration variable merge.verbosity and environment variable GIT_MERGE_VERBOSITY were introduced in commit 8c3275ab, which also documented configuration variable but not environment variable. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- Documentation/config.txt | 1 + Documentation/git-merge.txt | 15 +++++++++++++++ Documentation/git.txt | 5 +++++ 3 files changed, 21 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 11b332117c..d0e9a175f4 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -567,6 +567,7 @@ merge.verbosity:: message if conflicts were detected. Level 1 outputs only conflicts, 2 outputs conflicts and file changes. Level 5 and above outputs debugging information. The default is level 2. + Can be overriden by 'GIT_MERGE_VERBOSITY' environment variable. merge..name:: Defines a human readable name for a custom low-level diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index d285cba033..2c9db98a3c 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -43,6 +43,21 @@ If you tried a merge which resulted in a complex conflicts and would want to start over, you can recover with gitlink:git-reset[1]. +CONFIGURATION +------------- + +merge.summary:: + Whether to include summaries of merged commits in newly + created merge commit. False by default. + +merge.verbosity:: + Controls the amount of output shown by the recursive merge + strategy. Level 0 outputs nothing except a final error + message if conflicts were detected. Level 1 outputs only + conflicts, 2 outputs conflicts and file changes. Level 5 and + above outputs debugging information. The default is level 2. + Can be overriden by 'GIT_MERGE_VERBOSITY' environment variable. + HOW MERGE WORKS --------------- diff --git a/Documentation/git.txt b/Documentation/git.txt index 33614ec050..3fbfd45ffe 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -411,6 +411,11 @@ parameter, . other ~~~~~ +'GIT_MERGE_VERBOSITY':: + A number controlling the amount of output shown by + the recursive merge strategy. Overrides merge.verbosity. + See gitlink:git-merge[1] + 'GIT_PAGER':: This environment variable overrides `$PAGER`. From fd0368f985c2d6179d76cdf3569b0798d42f9196 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 13 Jul 2007 01:54:07 +0200 Subject: [PATCH 188/213] Document long options '--message=' and '--no-commit' Document that '--message=' is long version of '-m ' in git-commit, and that '--no-checkout' is long version of '-n' in git-clone. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 1 + Documentation/git-commit.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 2f39864b8e..a0a10e3e26 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -64,6 +64,7 @@ OPTIONS Operate quietly. This flag is passed to "rsync" and "git-fetch-pack" commands when given. +--no-checkout:: -n:: No checkout of HEAD is performed after the clone is complete. diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 53a7bb0895..352a494cb4 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -71,7 +71,7 @@ OPTIONS Override the author name used in the commit. Use `A U Thor ` format. --m :: +-m |--message=:: Use the given as the commit message. -s|--signoff:: From af83bed6903256c581f081ba7bba372f19804b30 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 13 Jul 2007 01:54:08 +0200 Subject: [PATCH 189/213] Document git commit --untracked-files and --verbose Documentation based on description of commit 443f8338 which added '-u'|'--untracked-files' option to git-status, and on git-runstatus(1) man page. Note that those options apply also to git-status. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- Documentation/git-commit.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 352a494cb4..f96142f96a 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -8,7 +8,7 @@ git-commit - Record changes to the repository SYNOPSIS -------- [verse] -'git-commit' [-a | --interactive] [-s] [-v] +'git-commit' [-a | --interactive] [-s] [-v] [-u] [(-c | -C) | -F | -m | --amend] [--no-verify] [-e] [--author ] [--] [[-i | -o ]...] @@ -115,6 +115,19 @@ but can be used to amend a merge commit. as well. This is usually not what you want unless you are concluding a conflicted merge. +-u|--untracked-files:: + Show all untracked files, also those in uninteresting + directories, in the "Untracked files:" section of commit + message template. Without this option only its name and + a trailing slash are displayed for each untracked + directory. + +-v|--verbose:: + Show unified diff between the HEAD commit and what + would be committed at the bottom of the commit message + template. Note that this diff output doesn't have its + lines prefixed with '#'. + -q|--quiet:: Suppress commit summary message. From 6ebedabf2d0f77c2c765ecc5effee1a7e3ffdedb Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 13 Jul 2007 13:45:55 +1000 Subject: [PATCH 190/213] gitk: Fix bug introduced by previous commit When I added the "--" case to the code scanning the arguments, I missed the fact that since the switch statement uses -regexp, the "--" case will match any argument containing "--", e.g. "--all". This fixes it by taking out the -regexp (since we don't actually need regular expression matching) and adjusting the match strings. A side effect of this is that previously any argument starting with "-d" would be taken to indicate date mode; now the argument has to be exactly "-d" if you want date mode. Signed-off-by: Paul Mackerras --- gitk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gitk b/gitk index b9219c2c70..39e452aba9 100755 --- a/gitk +++ b/gitk @@ -7478,9 +7478,9 @@ set revtreeargs {} set cmdline_files {} set i 0 foreach arg $argv { - switch -regexp -- $arg { - "^$" { } - "^-d" { set datemode 1 } + switch -- $arg { + "" { } + "-d" { set datemode 1 } "--" { set cmdline_files [lrange $argv [expr {$i + 1}] end] break From b06c6bc831cbb9e9eb82fd3ffd5a2b674cd940d0 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 12 Jul 2007 21:17:49 -0700 Subject: [PATCH 191/213] make git-send-email.perl handle email addresses with no names when Email::Valid is present When using git-send-email.perl on a changeset that has: Cc: in the body of the description, and the Email::Valid perl module is installed on the system, the email address will be deemed "invalid" for some reason (Email::Valid isn't smart enough to handle this?) and complain and not send the address the email. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Junio C Hamano --- git-send-email.perl | 1 + 1 file changed, 1 insertion(+) diff --git a/git-send-email.perl b/git-send-email.perl index 89f7c36ee5..a847d5ed52 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -410,6 +410,7 @@ sub extract_valid_address { return $address if ($address =~ /^($local_part_regexp)$/); if ($have_email_valid) { + $address =~ s/^<(.*)>$/$1/; return scalar Email::Valid->address($address); } else { # less robust/correct than the monster regexp in Email::Valid, From 689b4d552b8108d2c92c63258990ecd2bc791739 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 13 Jul 2007 08:54:06 -0700 Subject: [PATCH 192/213] send-email: discard blank around address in extract_valid_address as well. Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-send-email.perl b/git-send-email.perl index a847d5ed52..7552caca4b 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -410,7 +410,7 @@ sub extract_valid_address { return $address if ($address =~ /^($local_part_regexp)$/); if ($have_email_valid) { - $address =~ s/^<(.*)>$/$1/; + $address =~ s/^\s*<(.*)>\s*$/$1/; return scalar Email::Valid->address($address); } else { # less robust/correct than the monster regexp in Email::Valid, From 9a4cbdca34f6aa9424fce8a55fe9dd6f7c25d97b Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 13 Jul 2007 16:14:50 +0200 Subject: [PATCH 193/213] lockfile.c: schedule remove_lock_file only once. Removing a lockfile once should be enough. Signed-off-by: Sven Verdoolaege Signed-off-by: Junio C Hamano --- lockfile.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lockfile.c b/lockfile.c index 5ad2858b48..fb8f13bbb9 100644 --- a/lockfile.c +++ b/lockfile.c @@ -31,16 +31,16 @@ static int lock_file(struct lock_file *lk, const char *path) sprintf(lk->filename, "%s.lock", path); fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666); if (0 <= fd) { + if (!lock_file_list) { + signal(SIGINT, remove_lock_file_on_signal); + atexit(remove_lock_file); + } lk->owner = getpid(); if (!lk->on_list) { lk->next = lock_file_list; lock_file_list = lk; lk->on_list = 1; } - if (lock_file_list) { - signal(SIGINT, remove_lock_file_on_signal); - atexit(remove_lock_file); - } if (adjust_shared_perm(lk->filename)) return error("cannot fix permission bits on %s", lk->filename); From 793ad04198a79c14094bd1311a9c42f1293c6183 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Fri, 13 Jul 2007 00:30:35 +0200 Subject: [PATCH 194/213] Fix git-rebase -i to allow squashing of fast-forwardable commits Without this change the commits will be left standalone, with duplicated commit message. Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index d9563ec46f..f3950767ea 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -84,6 +84,7 @@ pick_one () { current_sha1=$(git rev-parse --verify HEAD) if [ $current_sha1 = $parent_sha1 ]; then git reset --hard $sha1 + test "a$1" = a-n && git reset --soft $current_sha1 sha1=$(git rev-parse --short $sha1) warn Fast forward to $sha1 else @@ -193,14 +194,14 @@ do_next () { die "Cannot 'squash' without a previous commit" mark_action_done - failed=f - pick_one -n $sha1 || failed=t MSG="$DOTEST"/message echo "# This is a combination of two commits." > "$MSG" echo "# The first commit's message is:" >> "$MSG" echo >> "$MSG" git cat-file commit HEAD | sed -e '1,/^$/d' >> "$MSG" echo >> "$MSG" + failed=f + pick_one -n $sha1 || failed=t echo "# And this is the 2nd commit message:" >> "$MSG" echo >> "$MSG" git cat-file commit $sha1 | sed -e '1,/^$/d' >> "$MSG" From ee8f838e0346751b21250f8d107049829b855a98 Mon Sep 17 00:00:00 2001 From: Robin Rosenberg Date: Sat, 14 Jul 2007 01:00:42 +0200 Subject: [PATCH 195/213] Support output ISO 8601 format dates Support output of full ISO 8601 style dates in e.g. git log and other places that use interpolation for formatting. Signed-off-by: Robin Rosenberg Signed-off-by: Junio C Hamano --- Documentation/pretty-formats.txt | 2 ++ cache.h | 2 +- commit.c | 6 +++++- date.c | 7 +++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index c551ea61d2..0193c3ce58 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -106,12 +106,14 @@ The placeholders are: - '%aD': author date, RFC2822 style - '%ar': author date, relative - '%at': author date, UNIX timestamp +- '%ai': author date, ISO 8601 format - '%cn': committer name - '%ce': committer email - '%cd': committer date - '%cD': committer date, RFC2822 style - '%cr': committer date, relative - '%ct': committer date, UNIX timestamp +- '%ci': committer date, ISO 8601 format - '%e': encoding - '%s': subject - '%b': body diff --git a/cache.h b/cache.h index 917a7e34f1..b39557dd01 100644 --- a/cache.h +++ b/cache.h @@ -409,7 +409,7 @@ extern void *read_object_with_reference(const unsigned char *sha1, unsigned long *size, unsigned char *sha1_ret); -enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL }; +enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL, DATE_ISO8601 }; const char *show_date(unsigned long time, int timezone, enum date_mode mode); const char *show_rfc2822_date(unsigned long time, int timezone); int parse_date(const char *date, char *buf, int bufsize); diff --git a/commit.c b/commit.c index 03436b1b07..d11941c7f4 100644 --- a/commit.c +++ b/commit.c @@ -781,6 +781,7 @@ static void fill_person(struct interp *table, const char *msg, int len) interp_set_entry(table, 2, show_date(date, tz, 0)); interp_set_entry(table, 3, show_rfc2822_date(date, tz)); interp_set_entry(table, 4, show_date(date, tz, 1)); + interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601)); } static long format_commit_message(const struct commit *commit, @@ -799,12 +800,14 @@ static long format_commit_message(const struct commit *commit, { "%aD" }, /* author date, RFC2822 style */ { "%ar" }, /* author date, relative */ { "%at" }, /* author date, UNIX timestamp */ + { "%ai" }, /* author date, ISO 8601 */ { "%cn" }, /* committer name */ { "%ce" }, /* committer email */ { "%cd" }, /* committer date */ { "%cD" }, /* committer date, RFC2822 style */ { "%cr" }, /* committer date, relative */ { "%ct" }, /* committer date, UNIX timestamp */ + { "%ci" }, /* committer date, ISO 8601 */ { "%e" }, /* encoding */ { "%s" }, /* subject */ { "%b" }, /* body */ @@ -821,10 +824,11 @@ static long format_commit_message(const struct commit *commit, IPARENTS, IPARENTS_ABBREV, IAUTHOR_NAME, IAUTHOR_EMAIL, IAUTHOR_DATE, IAUTHOR_DATE_RFC2822, IAUTHOR_DATE_RELATIVE, - IAUTHOR_TIMESTAMP, + IAUTHOR_TIMESTAMP, IAUTHOR_ISO8601, ICOMMITTER_NAME, ICOMMITTER_EMAIL, ICOMMITTER_DATE, ICOMMITTER_DATE_RFC2822, ICOMMITTER_DATE_RELATIVE, ICOMMITTER_TIMESTAMP, + ICOMMITTER_ISO8601, IENCODING, ISUBJECT, IBODY, diff --git a/date.c b/date.c index 316841e8ad..735d8f3bed 100644 --- a/date.c +++ b/date.c @@ -137,6 +137,13 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode) if (mode == DATE_SHORT) sprintf(timebuf, "%04d-%02d-%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); + else if (mode == DATE_ISO8601) + sprintf(timebuf, "%04d-%02d-%02d %02d:%02d:%02d %+05d", + tm->tm_year + 1900, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, + tz); else sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d%c%+05d", weekday_names[tm->tm_wday], From 73013afd14c14ba178ab2aaa458168ec1d5506de Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 13 Jul 2007 23:14:52 -0700 Subject: [PATCH 196/213] Make show_rfc2822_date() just another date output format. These days, show_date() takes a date_mode parameter to specify the output format, and a separate specialized function for dates in E-mails does not make much sense anymore. This retires show_rfc2822_date() function and make it just another date output format. Signed-off-by: Junio C Hamano --- cache.h | 11 +++++++++-- commit.c | 8 ++++---- date.c | 20 +++++--------------- refs.c | 4 ++-- sha1_name.c | 2 +- 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/cache.h b/cache.h index b39557dd01..328c1ad411 100644 --- a/cache.h +++ b/cache.h @@ -409,9 +409,16 @@ extern void *read_object_with_reference(const unsigned char *sha1, unsigned long *size, unsigned char *sha1_ret); -enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL, DATE_ISO8601 }; +enum date_mode { + DATE_NORMAL = 0, + DATE_RELATIVE, + DATE_SHORT, + DATE_LOCAL, + DATE_ISO8601, + DATE_RFC2822 +}; + const char *show_date(unsigned long time, int timezone, enum date_mode mode); -const char *show_rfc2822_date(unsigned long time, int timezone); int parse_date(const char *date, char *buf, int bufsize); void datestamp(char *buf, int bufsize); unsigned long approxidate(const char *); diff --git a/commit.c b/commit.c index d11941c7f4..4c5dfa9af0 100644 --- a/commit.c +++ b/commit.c @@ -585,7 +585,7 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, break; case CMIT_FMT_EMAIL: ret += sprintf(buf + ret, "Date: %s\n", - show_rfc2822_date(time, tz)); + show_date(time, tz, DATE_RFC2822)); break; case CMIT_FMT_FULLER: ret += sprintf(buf + ret, "%sDate: %s\n", what, @@ -778,9 +778,9 @@ static void fill_person(struct interp *table, const char *msg, int len) tz = -tz; } - interp_set_entry(table, 2, show_date(date, tz, 0)); - interp_set_entry(table, 3, show_rfc2822_date(date, tz)); - interp_set_entry(table, 4, show_date(date, tz, 1)); + interp_set_entry(table, 2, show_date(date, tz, DATE_NORMAL)); + interp_set_entry(table, 3, show_date(date, tz, DATE_RFC2822)); + interp_set_entry(table, 4, show_date(date, tz, DATE_RELATIVE)); interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601)); } diff --git a/date.c b/date.c index 735d8f3bed..45b0b1deb3 100644 --- a/date.c +++ b/date.c @@ -144,6 +144,11 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode) tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tz); + else if (mode == DATE_RFC2822) + sprintf(timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d", + weekday_names[tm->tm_wday], tm->tm_mday, + month_names[tm->tm_mon], tm->tm_year + 1900, + tm->tm_hour, tm->tm_min, tm->tm_sec, tz); else sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d%c%+05d", weekday_names[tm->tm_wday], @@ -156,21 +161,6 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode) return timebuf; } -const char *show_rfc2822_date(unsigned long time, int tz) -{ - struct tm *tm; - static char timebuf[200]; - - tm = time_to_tm(time, tz); - if (!tm) - return NULL; - sprintf(timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d", - weekday_names[tm->tm_wday], tm->tm_mday, - month_names[tm->tm_mon], tm->tm_year + 1900, - tm->tm_hour, tm->tm_min, tm->tm_sec, tz); - return timebuf; -} - /* * Check these. And note how it doesn't do the summer-time conversion. * diff --git a/refs.c b/refs.c index 4dc7e8b476..2694e7066d 100644 --- a/refs.c +++ b/refs.c @@ -1300,7 +1300,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char * if (hashcmp(logged_sha1, sha1)) { fprintf(stderr, "warning: Log %s has gap after %s.\n", - logfile, show_rfc2822_date(date, tz)); + logfile, show_date(date, tz, DATE_RFC2822)); } } else if (date == at_time) { @@ -1313,7 +1313,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char * if (hashcmp(logged_sha1, sha1)) { fprintf(stderr, "warning: Log %s unexpectedly ended on %s.\n", - logfile, show_rfc2822_date(date, tz)); + logfile, show_date(date, tz, DATE_RFC2822)); } } munmap(log_mapped, mapsz); diff --git a/sha1_name.c b/sha1_name.c index 858f08c34a..2d727d54dc 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -370,7 +370,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) fprintf(stderr, "warning: Log for '%.*s' only goes " "back to %s.\n", len, str, - show_rfc2822_date(co_time, co_tz)); + show_date(co_time, co_tz, DATE_RFC2822)); else fprintf(stderr, "warning: Log for '%.*s' only has " From b727a235a786423c93ce4f09eee296fbb5a919d1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 13 Jul 2007 23:03:37 -0700 Subject: [PATCH 197/213] Wire new date formats to --date= parser. Now we can use all internally supported date formats with git log --date= syntax. Earlier, we only allowed relative/local/default. Signed-off-by: Junio C Hamano --- revision.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/revision.c b/revision.c index 27cce090a1..28b5f2eace 100644 --- a/revision.c +++ b/revision.c @@ -1133,6 +1133,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch if (!strncmp(arg, "--date=", 7)) { if (!strcmp(arg + 7, "relative")) revs->date_mode = DATE_RELATIVE; + else if (!strcmp(arg + 7, "iso8601") || + !strcmp(arg + 7, "iso")) + revs->date_mode = DATE_ISO8601; + else if (!strcmp(arg + 7, "rfc2822") || + !strcmp(arg + 7, "rfc")) + revs->date_mode = DATE_RFC2822; + else if (!strcmp(arg + 7, "short")) + revs->date_mode = DATE_SHORT; else if (!strcmp(arg + 7, "local")) revs->date_mode = DATE_LOCAL; else if (!strcmp(arg + 7, "default")) From 1701872fc2cfc48c740175848c1ef6fc10eb0e10 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 13 Jul 2007 23:48:03 -0700 Subject: [PATCH 198/213] Document new --date= Now, git-log family can take full range of internally supported date format to their --date= argument. Document it. Signed-off-by: Junio C Hamano --- Documentation/git-rev-list.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index 20dcac6252..08e7573b9e 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -28,7 +28,7 @@ SYNOPSIS [ \--encoding[=] ] [ \--(author|committer|grep)= ] [ \--regexp-ignore-case ] [ \--extended-regexp ] - [ \--date={local|relative|default} ] + [ \--date={local|relative|default|iso|rfc|short} ] [ [\--objects | \--objects-edge] [ \--unpacked ] ] [ \--pretty | \--header ] [ \--bisect ] @@ -96,7 +96,7 @@ include::pretty-options.txt[] Synonym for `--date=relative`. ---date={relative,local,default}:: +--date={relative,local,default,iso,rfc}:: Only takes effect for dates shown in human-readable format, such as when using "--pretty". @@ -106,6 +106,13 @@ e.g. "2 hours ago". + `--date=local` shows timestamps in user's local timezone. + +`--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format. ++ +`--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822 +format, often found in E-mail messages. ++ +`--date=short` shows only date but not time, in `YYYY-MM-DD` fomat. ++ `--date=default` shows timestamps in the original timezone (either committer's or author's). From bdecd9d41b3528e17aea2290344c584412e2424e Mon Sep 17 00:00:00 2001 From: Matthieu Moy Date: Fri, 13 Jul 2007 19:41:38 +0200 Subject: [PATCH 199/213] More permissive "git-rm --cached" behavior without -f. In the previous behavior, "git-rm --cached" (without -f) had the same restriction as "git-rm". This forced the user to use the -f flag in situations which weren't actually dangerous, like: $ git add foo # oops, I didn't want this $ git rm --cached foo # back to initial situation Previously, the index had to match the file *and* the HEAD. With --cached, the index must now match the file *or* the HEAD. The behavior without --cached is unchanged, but provides better error messages. Signed-off-by: Matthieu Moy Signed-off-by: Junio C Hamano --- Documentation/git-rm.txt | 3 ++- builtin-rm.c | 32 ++++++++++++++++++++++++++------ t/t3600-rm.sh | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index 78f45dca2e..be61a82164 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -14,7 +14,8 @@ DESCRIPTION Remove files from the working tree and from the index. The files have to be identical to the tip of the branch, and no updates to its contents must have been placed in the staging -area (aka index). +area (aka index). When --cached is given, the staged content has to +match either the tip of the branch *or* the file on disk. OPTIONS diff --git a/builtin-rm.c b/builtin-rm.c index 4a0bd93c8b..9a808c1bf9 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -46,7 +46,7 @@ static int remove_file(const char *name) return ret; } -static int check_local_mod(unsigned char *head) +static int check_local_mod(unsigned char *head, int index_only) { /* items in list are already sorted in the cache order, * so we could do this a lot more efficiently by using @@ -65,6 +65,8 @@ static int check_local_mod(unsigned char *head) const char *name = list.name[i]; unsigned char sha1[20]; unsigned mode; + int local_changes = 0; + int staged_changes = 0; pos = cache_name_pos(name, strlen(name)); if (pos < 0) @@ -87,14 +89,32 @@ static int check_local_mod(unsigned char *head) continue; } if (ce_match_stat(ce, &st, 0)) - errs = error("'%s' has local modifications " - "(hint: try -f)", ce->name); + local_changes = 1; if (no_head || get_tree_entry(head, name, sha1, &mode) || ce->ce_mode != create_ce_mode(mode) || hashcmp(ce->sha1, sha1)) - errs = error("'%s' has changes staged in the index " - "(hint: try -f)", name); + staged_changes = 1; + + if (local_changes && staged_changes) + errs = error("'%s' has staged content different " + "from both the file and the HEAD\n" + "(use -f to force removal)", name); + else if (!index_only) { + /* It's not dangerous to git-rm --cached a + * file if the index matches the file or the + * HEAD, since it means the deleted content is + * still available somewhere. + */ + if (staged_changes) + errs = error("'%s' has changes staged in the index\n" + "(use --cached to keep the file, " + "or -f to force removal)", name); + if (local_changes) + errs = error("'%s' has local modifications\n" + "(use --cached to keep the file, " + "or -f to force removal)", name); + } } return errs; } @@ -192,7 +212,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) unsigned char sha1[20]; if (get_sha1("HEAD", sha1)) hashclr(sha1); - if (check_local_mod(sha1)) + if (check_local_mod(sha1, index_only)) exit(1); } diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 13a461f31b..5c001aa489 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -45,6 +45,40 @@ test_expect_success \ 'Test that git rm foo succeeds' \ 'git rm --cached foo' +test_expect_success \ + 'Test that git rm --cached foo succeeds if the index matches the file' \ + 'echo content > foo + git add foo + git rm --cached foo' + +test_expect_success \ + 'Test that git rm --cached foo succeeds if the index matches the file' \ + 'echo content > foo + git add foo + git commit -m foo + echo "other content" > foo + git rm --cached foo' + +test_expect_failure \ + 'Test that git rm --cached foo fails if the index matches neither the file nor HEAD' \ + 'echo content > foo + git add foo + git commit -m foo + echo "other content" > foo + git add foo + echo "yet another content" > foo + git rm --cached foo' + +test_expect_success \ + 'Test that git rm --cached -f foo works in case where --cached only did not' \ + 'echo content > foo + git add foo + git commit -m foo + echo "other content" > foo + git add foo + echo "yet another content" > foo + git rm --cached -f foo' + test_expect_success \ 'Post-check that foo exists but is not in index after git rm foo' \ '[ -f foo ] && ! git ls-files --error-unmatch foo' From 9d6f220cc8ffbd71b4c68765b52c3a7c41dd729b Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 14 Jul 2007 01:05:43 -0700 Subject: [PATCH 200/213] Remove useless uses of cat, and replace with filename arguments Replace uses of cat that do nothing but writing the contents of a single file to another command via pipe. [jc: Original patch from Josh was somewhat buggy and rewrote "cat $file | wc -l" to "wc -l $file", but this one should be Ok.] Signed-off-by: Junio C Hamano --- git-commit.sh | 2 +- git-filter-branch.sh | 4 ++-- git-ls-remote.sh | 2 +- git-quiltimport.sh | 7 ++++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/git-commit.sh b/git-commit.sh index f3cd8ee978..3f3de1729e 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -593,7 +593,7 @@ then tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) && rm -f "$TMP_INDEX" fi && - commit=$(cat "$GIT_DIR"/COMMIT_MSG | git commit-tree $tree $PARENTS) && + commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") && rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) && git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" && rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" && diff --git a/git-filter-branch.sh b/git-filter-branch.sh index d77902d34d..54019706dc 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -171,7 +171,7 @@ case "$filter_subdir" in git rev-list --reverse --topo-order --default HEAD \ --parents --full-history "$@" -- "$filter_subdir" esac > ../revs -commits=$(cat ../revs | wc -l | tr -d " ") +commits=$(wc -l <../revs | tr -d " ") test $commits -eq 0 && die "Found nothing to rewrite" @@ -241,7 +241,7 @@ case "$target_head" in ;; *) git update-ref refs/heads/"$dstbranch" $target_head - if [ $(cat ../map/$src_head | wc -l) -gt 1 ]; then + if [ $(wc -l <../map/$src_head) -gt 1 ]; then echo "WARNING: Your commit filter caused the head commit to expand to several rewritten commits. Only the first such commit was recorded as the current $dstbranch head but you will need to resolve the situation now (probably by manually merging the other commits). These are all the commits:" >&2 sed 's/^/ /' ../map/$src_head >&2 ret=1 diff --git a/git-ls-remote.sh b/git-ls-remote.sh index 3671f3433e..b7e5d04584 100755 --- a/git-ls-remote.sh +++ b/git-ls-remote.sh @@ -82,7 +82,7 @@ rsync://* ) (cd $tmpdir && find refs -type f) | while read path do - cat "$tmpdir/$path" | tr -d '\012' + tr -d '\012' <"$tmpdir/$path" echo " $path" done && rm -fr $tmpdir diff --git a/git-quiltimport.sh b/git-quiltimport.sh index 2124df9e4a..9de54d19fb 100755 --- a/git-quiltimport.sh +++ b/git-quiltimport.sh @@ -70,10 +70,11 @@ tmp_info="$tmp_dir/info" commit=$(git rev-parse HEAD) mkdir $tmp_dir || exit 2 -for patch_name in $(cat "$QUILT_PATCHES/series" | grep -v '^#'); do +for patch_name in $(grep -v '^#' < "$QUILT_PATCHES/series" ); do echo $patch_name - (cat $QUILT_PATCHES/$patch_name | git mailinfo "$tmp_msg" "$tmp_patch" > "$tmp_info") || exit 3 - test -s .dotest/patch || { + git mailinfo "$tmp_msg" "$tmp_patch" \ + <"$QUILT_PATCHES/$patch_name" >"$tmp_info" || exit 3 + test -s "$tmp_patch" || { echo "Patch is empty. Was it split wrong?" exit 1 } From af6861b14488a91ab932c63852979eaf78b549d2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 14 Jul 2007 13:43:09 -0700 Subject: [PATCH 201/213] Add contrib/stats/mailmap.pl script This script reads the existing commit log and .mailmap file, and outputs author e-mail addresses that would map to more than one names (most likely due to difference in the way they are spelled, but some are due to ancient botched commits). Signed-off-by: Junio C Hamano --- contrib/stats/mailmap.pl | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 contrib/stats/mailmap.pl diff --git a/contrib/stats/mailmap.pl b/contrib/stats/mailmap.pl new file mode 100755 index 0000000000..4b852e2455 --- /dev/null +++ b/contrib/stats/mailmap.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl -w +my %mailmap = (); +open I, "<", ".mailmap"; +while () { + chomp; + next if /^#/; + if (my ($author, $mail) = /^(.*?)\s+<(.+)>$/) { + $mailmap{$mail} = $author; + } +} +close I; + +my %mail2author = (); +open I, "git log --pretty='format:%ae %an' |"; +while () { + chomp; + my ($mail, $author) = split(/\t/, $_); + next if exists $mailmap{$mail}; + $mail2author{$mail} ||= {}; + $mail2author{$mail}{$author} ||= 0; + $mail2author{$mail}{$author}++; +} +close I; + +while (my ($mail, $authorcount) = each %mail2author) { + # %$authorcount is ($author => $count); + # sort and show the names from the most frequent ones. + my @names = (map { $_->[0] } + sort { $b->[1] <=> $a->[1] } + map { [$_, $authorcount->{$_}] } + keys %$authorcount); + if (1 < @names) { + for (@names) { + print "$_ <$mail>\n"; + } + } +} + From 94008931716e9db59afcc82cf5319f8278e5a907 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 14 Jul 2007 13:44:58 -0700 Subject: [PATCH 202/213] Update .mailmap The script "contrib/stats/mailmap.pl" found a few missed ones. Signed-off-by: Junio C Hamano --- .mailmap | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.mailmap b/.mailmap index 71ec16acca..5529b198e8 100644 --- a/.mailmap +++ b/.mailmap @@ -19,12 +19,14 @@ Horst H. von Brand Joachim Berdal Haga Jon Loeliger Jon Seymour +Junio C Hamano Karl Hasselström Kent Engstrom Lars Doelle Lars Doelle Lukas Sandström Martin Langhoff +Michael Coleman Michele Ballabio Nanako Shiraishi Nguyễn Thái Ngọc Duy @@ -42,6 +44,7 @@ Uwe Kleine-König Uwe Kleine-König Uwe Kleine-König Ville Skyttä +William Pursell YOSHIFUJI Hideaki anonymous anonymous From 46cf98baa5a1d74a9d00dc1092b29e4af93e8615 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 14 Jul 2007 12:40:32 -0700 Subject: [PATCH 203/213] git-svn: remove leading slashes from fetch lines in the generate config We were previously sensitive to leading slashes in the fetch lines and incorrectly writing them to the config if the user used them (needlessly) in the command-line. This fixes the issue and allows us to play nicely with legacy configs that have leading slashes in fetch lines. Thanks to Bradford Smith for figuring this out for me: > > This works: > > git-svn clone https://my.server.net/repos/path/ -Ttrunk/testing > -ttags/testing -bbranches/testing testing > > This doesn't: > > git-svn clone https://my.server.net/repos/path -T/trunk/testing > -t/tags/testing -b/branches/testing testing Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/git-svn.perl b/git-svn.perl index b3dffccf38..299b40f938 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1026,7 +1026,9 @@ sub read_all_remotes { my $r = {}; foreach (grep { s/^svn-remote\.// } command(qw/config -l/)) { if (m!^(.+)\.fetch=\s*(.*)\s*:\s*refs/remotes/(.+)\s*$!) { - $r->{$1}->{fetch}->{$2} = $3; + my ($remote, $local_ref, $remote_ref) = ($1, $2, $3); + $local_ref =~ s{^/}{}; + $r->{$remote}->{fetch}->{$local_ref} = $remote_ref; } elsif (m!^(.+)\.url=\s*(.*)\s*$!) { $r->{$1}->{url} = $2; } elsif (m!^(.+)\.(branches|tags)= @@ -1146,6 +1148,7 @@ sub init_remote_config { unless ($no_write) { command_noisy('config', "svn-remote.$self->{repo_id}.url", $url); + $self->{path} =~ s{^/}{}; command_noisy('config', '--add', "svn-remote.$self->{repo_id}.fetch", "$self->{path}:".$self->refname); From 48b4c3d5ab1610c6dc0198fe94334d78e8a82e16 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Fri, 13 Jul 2007 14:39:05 +0200 Subject: [PATCH 204/213] Fix git-p4 on Windows to not use the Posix sysconf function. Add condition for Windows, since it doesn't support the os.sysconf module. We hardcode the commandline limit to 2K, as that should work on most Windows platforms. Signed-off-by: Marius Storm-Olsen Acked-by: Simon Hausmann Signed-off-by: Shawn O. Pearce --- contrib/fast-import/git-p4 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 54a05eb99c..d877150f41 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -717,7 +717,11 @@ class P4Sync(Command): # POSIX says it's 4096 bytes, default for Linux seems to be 130 K. # and all OS from the table below seems to be higher than POSIX. # See http://www.in-ulm.de/~mascheck/various/argmax/ - argmax = min(4000, os.sysconf('SC_ARG_MAX')) + if (self.isWindows): + argmax = 2000 + else: + argmax = min(4000, os.sysconf('SC_ARG_MAX')) + chunk = '' filedata = [] for i in xrange(len(files)): From b6f3481bb456acbbb990a1045344bb06e5a40283 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 15 Jul 2007 01:40:37 -0400 Subject: [PATCH 205/213] Teach fast-import to recursively copy files/directories Some source material (e.g. Subversion dump files) perform directory renames by telling us the directory was copied, then deleted in the same revision. This makes it difficult for a frontend to convert such data formats to a fast-import stream, as all the frontend has on hand is "Copy a/ to b/; Delete a/" with no details about what files are in a/, unless the frontend also kept track of all files. The new 'C' subcommand within a commit allows the frontend to make a recursive copy of one path to another path within the branch, without needing to keep track of the individual file paths. The metadata copy is performed in memory efficiently, but is implemented as a copy-immediately operation, rather than copy-on-write. With this new 'C' subcommand frontends could obviously implement an 'R' (rename) on their own as a combination of 'C' and 'D' (delete), but since we have already offered up 'R' in the past and it is a trivial thing to keep implemented I'm not going to deprecate it. Signed-off-by: Shawn O. Pearce --- Documentation/git-fast-import.txt | 40 +++++++++++++-- fast-import.c | 81 ++++++++++++++++++++++++++++-- t/t9300-fast-import.sh | 83 +++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+), 9 deletions(-) diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index bf1ba67ad0..30ee98d17f 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -302,7 +302,7 @@ change to the project. data ('from' SP LF)? ('merge' SP LF)? - (filemodify | filedelete | filerename | filedeleteall)* + (filemodify | filedelete | filecopy | filerename | filedeleteall)* LF .... @@ -325,13 +325,13 @@ commit message use a 0 length data. Commit messages are free-form and are not interpreted by Git. Currently they must be encoded in UTF-8, as fast-import does not permit other encodings to be specified. -Zero or more `filemodify`, `filedelete`, `filerename` and -`filedeleteall` commands +Zero or more `filemodify`, `filedelete`, `filecopy`, `filerename` +and `filedeleteall` commands may be included to update the contents of the branch prior to creating the commit. These commands may be supplied in any order. However it is recommended that a `filedeleteall` command preceed -all `filemodify` and `filerename` commands in the same commit, as -`filedeleteall` +all `filemodify`, `filecopy` and `filerename` commands in the same +commit, as `filedeleteall` wipes the branch clean (see below). `author` @@ -497,6 +497,27 @@ here `` is the complete path of the file or subdirectory to be removed from the branch. See `filemodify` above for a detailed description of ``. +`filecopy` +^^^^^^^^^^^^ +Recursively copies an existing file or subdirectory to a different +location within the branch. The existing file or directory must +exist. If the destination exists it will be completely replaced +by the content copied from the source. + +.... + 'C' SP SP LF +.... + +here the first `` is the source location and the second +`` is the destination. See `filemodify` above for a detailed +description of what `` may look like. To use a source path +that contains SP the path must be quoted. + +A `filecopy` command takes effect immediately. Once the source +location has been copied to the destination any future commands +applied to the source location will not impact the destination of +the copy. + `filerename` ^^^^^^^^^^^^ Renames an existing file or subdirectory to a different location @@ -517,6 +538,15 @@ location has been renamed to the destination any future commands applied to the source location will create new files there and not impact the destination of the rename. +Note that a `filerename` is the same as a `filecopy` followed by a +`filedelete` of the source location. There is a slight performance +advantage to using `filerename`, but the advantage is so small +that it is never worth trying to convert a delete/add pair in +source material into a rename for fast-import. This `filerename` +command is provided just to simplify frontends that already have +rename information and don't want bother with decomposing it into a +`filecopy` followed by a `filedelete`. + `filedeleteall` ^^^^^^^^^^^^^^^ Included in a `commit` command to remove all files (and also all diff --git a/fast-import.c b/fast-import.c index a1cb13f09b..99a19d89e8 100644 --- a/fast-import.c +++ b/fast-import.c @@ -26,10 +26,16 @@ Format of STDIN stream: lf; commit_msg ::= data; - file_change ::= file_clr | file_del | file_rnm | file_obm | file_inm; + file_change ::= file_clr + | file_del + | file_rnm + | file_cpy + | file_obm + | file_inm; file_clr ::= 'deleteall' lf; file_del ::= 'D' sp path_str lf; file_rnm ::= 'R' sp path_str sp path_str lf; + file_cpy ::= 'C' sp path_str sp path_str lf; file_obm ::= 'M' sp mode sp (hexsha1 | idnum) sp path_str lf; file_inm ::= 'M' sp mode sp 'inline' sp path_str lf data; @@ -623,6 +629,31 @@ static void release_tree_entry(struct tree_entry *e) avail_tree_entry = e; } +static struct tree_content *dup_tree_content(struct tree_content *s) +{ + struct tree_content *d; + struct tree_entry *a, *b; + unsigned int i; + + if (!s) + return NULL; + d = new_tree_content(s->entry_count); + for (i = 0; i < s->entry_count; i++) { + a = s->entries[i]; + b = new_tree_entry(); + memcpy(b, a, sizeof(*a)); + if (a->tree && is_null_sha1(b->versions[1].sha1)) + b->tree = dup_tree_content(a->tree); + else + b->tree = NULL; + d->entries[i] = b; + } + d->entry_count = s->entry_count; + d->delta_depth = s->delta_depth; + + return d; +} + static void start_packfile(void) { static char tmpfile[PATH_MAX]; @@ -1273,6 +1304,43 @@ del_entry: return 1; } +static int tree_content_get( + struct tree_entry *root, + const char *p, + struct tree_entry *leaf) +{ + struct tree_content *t = root->tree; + const char *slash1; + unsigned int i, n; + struct tree_entry *e; + + slash1 = strchr(p, '/'); + if (slash1) + n = slash1 - p; + else + n = strlen(p); + + for (i = 0; i < t->entry_count; i++) { + e = t->entries[i]; + if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) { + if (!slash1) { + memcpy(leaf, e, sizeof(*leaf)); + if (e->tree && is_null_sha1(e->versions[1].sha1)) + leaf->tree = dup_tree_content(e->tree); + else + leaf->tree = NULL; + return 1; + } + if (!S_ISDIR(e->versions[1].mode)) + return 0; + if (!e->tree) + load_tree(e); + return tree_content_get(e, slash1 + 1, leaf); + } + } + return 0; +} + static int update_branch(struct branch *b) { static const char *msg = "fast-import"; @@ -1658,7 +1726,7 @@ static void file_change_d(struct branch *b) free(p_uq); } -static void file_change_r(struct branch *b) +static void file_change_cr(struct branch *b, int rename) { const char *s, *d; char *s_uq, *d_uq; @@ -1694,7 +1762,10 @@ static void file_change_r(struct branch *b) } memset(&leaf, 0, sizeof(leaf)); - tree_content_remove(&b->branch_tree, s, &leaf); + if (rename) + tree_content_remove(&b->branch_tree, s, &leaf); + else + tree_content_get(&b->branch_tree, s, &leaf); if (!leaf.versions[1].mode) die("Path %s not in branch", s); tree_content_set(&b->branch_tree, d, @@ -1874,7 +1945,9 @@ static void cmd_new_commit(void) else if (!prefixcmp(command_buf.buf, "D ")) file_change_d(b); else if (!prefixcmp(command_buf.buf, "R ")) - file_change_r(b); + file_change_cr(b, 1); + else if (!prefixcmp(command_buf.buf, "C ")) + file_change_cr(b, 0); else if (!strcmp("deleteall", command_buf.buf)) file_change_deleteall(b); else diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index bf3720d762..4b920be331 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -648,4 +648,87 @@ test_expect_success \ git diff-tree -M -r M3^ M3 >actual && compare_diff_raw expect actual' +### +### series N +### + +test_tick +cat >input < $GIT_COMMITTER_DATE +data <expect <actual && + compare_diff_raw expect actual' + +cat >input < $GIT_COMMITTER_DATE +data < $GIT_COMMITTER_DATE +data <expect <actual && + compare_diff_raw expect actual' + +cat >input < $GIT_COMMITTER_DATE +data < Date: Sun, 15 Jul 2007 01:14:45 +0200 Subject: [PATCH 206/213] Make every builtin-*.c file #include "builtin.h" Make every builtin-*.c file #include "builtin.h". Also takes care of some declaration/definition mismatches. Signed-off-by: Peter Hagervall Signed-off-by: Junio C Hamano --- builtin-bundle.c | 1 + builtin-checkout-index.c | 1 + builtin-fetch--tool.c | 1 + builtin-for-each-ref.c | 3 ++- builtin-fsck.c | 3 ++- builtin-gc.c | 1 + builtin-merge-base.c | 1 + builtin-merge-file.c | 7 ++++--- builtin-pack-refs.c | 1 + builtin-rerere.c | 1 + builtin-runstatus.c | 1 + builtin-show-ref.c | 1 + 12 files changed, 17 insertions(+), 5 deletions(-) diff --git a/builtin-bundle.c b/builtin-bundle.c index 306ad29597..6ae5ab04c9 100644 --- a/builtin-bundle.c +++ b/builtin-bundle.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "object.h" #include "commit.h" diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c index 8460f97b66..75377b9cab 100644 --- a/builtin-checkout-index.c +++ b/builtin-checkout-index.c @@ -36,6 +36,7 @@ * of "-a" causing problems (not possible in the above example, * but get used to it in scripting!). */ +#include "builtin.h" #include "cache.h" #include "strbuf.h" #include "quote.h" diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c index ed4d5de5d5..e2f8ede9ae 100644 --- a/builtin-fetch--tool.c +++ b/builtin-fetch--tool.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "refs.h" #include "commit.h" diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index 2b218425aa..0afa1c5c41 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "refs.h" #include "object.h" @@ -796,7 +797,7 @@ static struct ref_sort *default_sort(void) return sort; } -int cmd_for_each_ref(int ac, const char **av, char *prefix) +int cmd_for_each_ref(int ac, const char **av, const char *prefix) { int i, num_refs; const char *format = NULL; diff --git a/builtin-fsck.c b/builtin-fsck.c index a6ef65ea32..350ec5e144 100644 --- a/builtin-fsck.c +++ b/builtin-fsck.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "commit.h" #include "tree.h" @@ -659,7 +660,7 @@ static const char fsck_usage[] = "git-fsck [--tags] [--root] [[--unreachable] [--cache] [--full] " "[--strict] [--verbose] *]"; -int cmd_fsck(int argc, char **argv, const char *prefix) +int cmd_fsck(int argc, const char **argv, const char *prefix) { int i, heads; diff --git a/builtin-gc.c b/builtin-gc.c index 45025fba30..9397482610 100644 --- a/builtin-gc.c +++ b/builtin-gc.c @@ -10,6 +10,7 @@ * Copyright (c) 2006 Shawn O. Pearce */ +#include "builtin.h" #include "cache.h" #include "run-command.h" diff --git a/builtin-merge-base.c b/builtin-merge-base.c index e35d362f26..0108e22ade 100644 --- a/builtin-merge-base.c +++ b/builtin-merge-base.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "commit.h" diff --git a/builtin-merge-file.c b/builtin-merge-file.c index 10ec63b17e..58deb62ac0 100644 --- a/builtin-merge-file.c +++ b/builtin-merge-file.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "xdiff/xdiff.h" #include "xdiff-interface.h" @@ -5,9 +6,9 @@ static const char merge_file_usage[] = "git merge-file [-p | --stdout] [-q | --quiet] [-L name1 [-L orig [-L name2]]] file1 orig_file file2"; -int cmd_merge_file(int argc, char **argv, char **envp) +int cmd_merge_file(int argc, const char **argv, const char *prefix) { - char *names[3]; + const char *names[3]; mmfile_t mmfs[3]; mmbuffer_t result = {NULL, 0}; xpparam_t xpp = {XDF_NEED_MINIMAL}; @@ -51,7 +52,7 @@ int cmd_merge_file(int argc, char **argv, char **envp) free(mmfs[i].ptr); if (ret >= 0) { - char *filename = argv[1]; + const char *filename = argv[1]; FILE *f = to_stdout ? stdout : fopen(filename, "wb"); if (!f) diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c index 758499238f..09df4e11a8 100644 --- a/builtin-pack-refs.c +++ b/builtin-pack-refs.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "refs.h" #include "object.h" diff --git a/builtin-rerere.c b/builtin-rerere.c index 6ffc43d864..29d057c98c 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "path-list.h" #include "xdiff/xdiff.h" diff --git a/builtin-runstatus.c b/builtin-runstatus.c index 4b489b1214..2db25c88bf 100644 --- a/builtin-runstatus.c +++ b/builtin-runstatus.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "wt-status.h" diff --git a/builtin-show-ref.c b/builtin-show-ref.c index 9463ff0e69..65051d14fd 100644 --- a/builtin-show-ref.c +++ b/builtin-show-ref.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "refs.h" #include "object.h" From a82830a4577dfe93d329918e7624741fee13842c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 14 Jul 2007 22:56:47 -0700 Subject: [PATCH 207/213] Documentation/git-commit-tree: remove description of a nonexistent limitation Noticed by Geoff Richards. Signed-off-by: Junio C Hamano --- Documentation/git-commit-tree.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 9586b97291..5870c2ce47 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -72,7 +72,7 @@ GIT_AUTHOR_EMAIL: name = "Your Name" email = "your@email.address.xz" -A commit comment is read from stdin (max 999 chars). If a changelog +A commit comment is read from stdin. If a changelog entry is not provided via "<" redirection, "git-commit-tree" will just wait for one to be entered and terminated with ^D. From 4cb08df553e270ab516a140caeeddd8e94f1e497 Mon Sep 17 00:00:00 2001 From: Emil Medve Date: Sat, 14 Jul 2007 12:51:44 -0500 Subject: [PATCH 208/213] Use $(RM) in Makefiles instead of 'rm -f' Signed-off-by: Emil Medve Signed-off-by: Junio C Hamano --- Documentation/Makefile | 15 +++++----- Makefile | 67 +++++++++++++++++++++--------------------- contrib/emacs/Makefile | 3 +- t/Makefile | 3 +- templates/Makefile | 3 +- 5 files changed, 48 insertions(+), 43 deletions(-) diff --git a/Documentation/Makefile b/Documentation/Makefile index f3a6c733b6..b06275726d 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -41,6 +41,7 @@ ifdef ASCIIDOC8 ASCIIDOC_EXTRA += -a asciidoc7compatible endif INSTALL?=install +RM ?= rm -f DOC_REF = origin/man -include ../config.mak.autogen @@ -84,7 +85,7 @@ install: man # Determine "include::" file references in asciidoc files. # doc.dep : $(wildcard *.txt) build-docdep.perl - rm -f $@+ $@ + $(RM) $@+ $@ perl ./build-docdep.perl >$@+ mv $@+ $@ @@ -109,11 +110,11 @@ cmd-list.made: cmd-list.perl $(MAN1_TXT) git.7 git.html: git.txt core-intro.txt clean: - rm -f *.xml *.xml+ *.html *.html+ *.1 *.5 *.7 howto-index.txt howto/*.html doc.dep - rm -f $(cmds_txt) *.made + $(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7 howto-index.txt howto/*.html doc.dep + $(RM) $(cmds_txt) *.made %.html : %.txt - rm -f $@+ $@ + $(RM) $@+ $@ $(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \ $(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $< mv $@+ $@ @@ -122,7 +123,7 @@ clean: xmlto -m callouts.xsl man $< %.xml : %.txt - rm -f $@+ $@ + $(RM) $@+ $@ $(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \ $(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $< mv $@+ $@ @@ -137,7 +138,7 @@ user-manual.html: user-manual.xml xsltproc $(XSLTOPTS) -o $@ $(XSLT) $< howto-index.txt: howto-index.sh $(wildcard howto/*.txt) - rm -f $@+ $@ + $(RM) $@+ $@ sh ./howto-index.sh $(wildcard howto/*.txt) >$@+ mv $@+ $@ @@ -147,7 +148,7 @@ $(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt WEBDOC_DEST = /pub/software/scm/git/docs $(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt - rm -f $@+ $@ + $(RM) $@+ $@ sed -e '1,/^$$/d' $< | $(ASCIIDOC) -b xhtml11 - >$@+ mv $@+ $@ diff --git a/Makefile b/Makefile index d7541b403b..5db3fb4ce1 100644 --- a/Makefile +++ b/Makefile @@ -176,6 +176,7 @@ export prefix bindir gitexecdir sharedir template_dir sysconfdir CC = gcc AR = ar +RM = rm -f TAR = tar INSTALL = install RPMBUILD = rpmbuild @@ -729,7 +730,7 @@ export TAR INSTALL DESTDIR SHELL_PATH all:: $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) ifneq (,$X) - $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), rm -f '$p';) + $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$p';) endif all:: @@ -743,7 +744,7 @@ strip: $(PROGRAMS) git$X $(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X gitk-wish: gitk GIT-GUI-VARS - $(QUIET_GEN)rm -f $@ $@+ && \ + $(QUIET_GEN)$(RM) $@ $@+ && \ sed -e '1,3s|^exec .* "$$0"|exec $(subst |,'\|',$(TCLTK_PATH_SQ)) "$$0"|' $@+ && \ chmod +x $@+ && \ mv -f $@+ $@ @@ -759,10 +760,10 @@ git$X: git.o $(BUILTIN_OBJS) $(GITLIBS) help.o: common-cmds.h git-merge-subtree$X: git-merge-recursive$X - $(QUIET_BUILT_IN)rm -f $@ && ln git-merge-recursive$X $@ + $(QUIET_BUILT_IN)$(RM) $@ && ln git-merge-recursive$X $@ $(BUILT_INS): git$X - $(QUIET_BUILT_IN)rm -f $@ && ln git$X $@ + $(QUIET_BUILT_IN)$(RM) $@ && ln git$X $@ common-cmds.h: ./generate-cmdlist.sh @@ -770,7 +771,7 @@ common-cmds.h: $(wildcard Documentation/git-*.txt) $(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh - $(QUIET_GEN)rm -f $@ $@+ && \ + $(QUIET_GEN)$(RM) $@ $@+ && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ @@ -782,7 +783,7 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh $(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak $(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py - rm -f $@ $@+ + $(RM) $@ $@+ sed -e '1s|#!.*/python|#!$(PYTHON_PATH_SQ)|' \ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ @@ -794,7 +795,7 @@ perl/perl.mak: GIT-CFLAGS $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F) $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl - $(QUIET_GEN)rm -f $@ $@+ && \ + $(QUIET_GEN)$(RM) $@ $@+ && \ INSTLIBDIR=`$(MAKE) -C perl -s --no-print-directory instlibdir` && \ sed -e '1{' \ -e ' s|#!.*perl|#!$(PERL_PATH_SQ)|' \ @@ -813,7 +814,7 @@ git-status: git-commit $(QUIET_GEN)cp $< $@+ && mv $@+ $@ gitweb/gitweb.cgi: gitweb/gitweb.perl - $(QUIET_GEN)rm -f $@ $@+ && \ + $(QUIET_GEN)$(RM) $@ $@+ && \ sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \ -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \ -e 's|++GIT_BINDIR++|$(bindir)|g' \ @@ -836,7 +837,7 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl mv $@+ $@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css - $(QUIET_GEN)rm -f $@ $@+ && \ + $(QUIET_GEN)$(RM) $@ $@+ && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ @@ -849,11 +850,11 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css mv $@+ $@ configure: configure.ac - $(QUIET_GEN)rm -f $@ $<+ && \ + $(QUIET_GEN)$(RM) $@ $<+ && \ sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ $< > $<+ && \ autoconf -o $@ $<+ && \ - rm -f $<+ + $(RM) $<+ # These can record GIT_VERSION git.o git.spec \ @@ -908,7 +909,7 @@ $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) $(DIFF_OBJS): diffcore.h $(LIB_FILE): $(LIB_OBJS) - $(QUIET_AR)rm -f $@ && $(AR) rcs $@ $(LIB_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \ xdiff/xmerge.o @@ -916,7 +917,7 @@ $(XDIFF_OBJS): xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \ xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h $(XDIFF_LIB): $(XDIFF_OBJS) - $(QUIET_AR)rm -f $@ && $(AR) rcs $@ $(XDIFF_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS) perl/Makefile: perl/Git.pm perl/Makefile.PL GIT-CFLAGS @@ -927,11 +928,11 @@ doc: $(MAKE) -C Documentation all TAGS: - rm -f TAGS + $(RM) TAGS find . -name '*.[hcS]' -print | xargs etags -a tags: - rm -f tags + $(RM) tags find . -name '*.[hcS]' -print | xargs ctags -a ### Detect prefix changes @@ -1010,9 +1011,9 @@ endif cp '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \ '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'; \ fi - $(foreach p,$(BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;) + $(foreach p,$(BUILT_INS), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;) ifneq (,$X) - $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p';) + $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p';) endif install-doc: @@ -1042,7 +1043,7 @@ dist: git.spec git-archive configure $(GIT_TARNAME)/configure \ $(GIT_TARNAME)/version \ $(GIT_TARNAME)/git-gui/version - @rm -rf $(GIT_TARNAME) + @$(RM) -r $(GIT_TARNAME) gzip -f -9 $(GIT_TARNAME).tar rpm: dist @@ -1051,13 +1052,13 @@ rpm: dist htmldocs = git-htmldocs-$(GIT_VERSION) manpages = git-manpages-$(GIT_VERSION) dist-doc: - rm -fr .doc-tmp-dir + $(RM) -r .doc-tmp-dir mkdir .doc-tmp-dir $(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar . gzip -n -9 -f $(htmldocs).tar : - rm -fr .doc-tmp-dir + $(RM) -r .doc-tmp-dir mkdir -p .doc-tmp-dir/man1 .doc-tmp-dir/man5 .doc-tmp-dir/man7 $(MAKE) -C Documentation DESTDIR=./ \ man1dir=../.doc-tmp-dir/man1 \ @@ -1066,31 +1067,31 @@ dist-doc: install cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar . gzip -n -9 -f $(manpages).tar - rm -fr .doc-tmp-dir + $(RM) -r .doc-tmp-dir ### Cleaning rules clean: - rm -f *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \ + $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \ $(LIB_FILE) $(XDIFF_LIB) - rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X - rm -f $(TEST_PROGRAMS) - rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags - rm -rf autom4te.cache - rm -f configure config.log config.mak.autogen config.mak.append config.status config.cache - rm -rf $(GIT_TARNAME) .doc-tmp-dir - rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz - rm -f $(htmldocs).tar.gz $(manpages).tar.gz - rm -f gitweb/gitweb.cgi + $(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X + $(RM) $(TEST_PROGRAMS) + $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags + $(RM) -r autom4te.cache + $(RM) configure config.log config.mak.autogen config.mak.append config.status config.cache + $(RM) -r $(GIT_TARNAME) .doc-tmp-dir + $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz + $(RM) $(htmldocs).tar.gz $(manpages).tar.gz + $(RM) gitweb/gitweb.cgi $(MAKE) -C Documentation/ clean $(MAKE) -C perl clean $(MAKE) -C templates/ clean $(MAKE) -C t/ clean ifndef NO_TCLTK - rm -f gitk-wish + $(RM) gitk-wish $(MAKE) -C git-gui clean endif - rm -f GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS + $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS .PHONY: all install clean strip .PHONY: .FORCE-GIT-VERSION-FILE TAGS tags .FORCE-GIT-CFLAGS diff --git a/contrib/emacs/Makefile b/contrib/emacs/Makefile index 98aa0aae9b..5e94d6fcd3 100644 --- a/contrib/emacs/Makefile +++ b/contrib/emacs/Makefile @@ -7,6 +7,7 @@ INSTALL ?= install INSTALL_ELC = $(INSTALL) -m 644 prefix ?= $(HOME) emacsdir = $(prefix)/share/emacs/site-lisp +RM ?= rm -f all: $(ELC) @@ -17,4 +18,4 @@ install: all %.elc: %.el $(EMACS) -batch -f batch-byte-compile $< -clean:; rm -f $(ELC) +clean:; $(RM) $(ELC) diff --git a/t/Makefile b/t/Makefile index b25caca887..72d7884232 100644 --- a/t/Makefile +++ b/t/Makefile @@ -6,6 +6,7 @@ #GIT_TEST_OPTS=--verbose --debug SHELL_PATH ?= $(SHELL) TAR ?= $(TAR) +RM ?= rm -f # Shell quote; SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) @@ -19,7 +20,7 @@ $(T): @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) clean: - rm -fr trash + $(RM) -r trash # we can test NO_OPTIMIZE_COMMITS independently of LC_ALL full-svn-test: diff --git a/templates/Makefile b/templates/Makefile index aaa39d30fa..6f4dbd362f 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -6,6 +6,7 @@ endif INSTALL ?= install TAR ?= tar +RM ?= rm -f prefix ?= $(HOME) template_dir ?= $(prefix)/share/git-core/templates # DESTDIR= @@ -42,7 +43,7 @@ custom: $(QUIET): no custom templates yet clean: - rm -rf blt boilerplates.made + $(RM) -r blt boilerplates.made install: all $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(template_dir_SQ)' From a5e407988b35b7353bd03c770afc647670c25981 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sat, 14 Jul 2007 20:48:42 +0200 Subject: [PATCH 209/213] git-cvsserver: detect/diagnose write failure, etc. There were many operations that did not notice and report errors to the CVS client, which would have resulted in corrupt working tree. Signed-off-by: Jim Meyering Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 50 ++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 10aba507d7..ae7d511589 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -623,8 +623,12 @@ sub req_Modified my ( $cmd, $data ) = @_; my $mode = ; + defined $mode + or (print "E end of file reading mode for $data\n"), return; chomp $mode; my $size = ; + defined $size + or (print "E end of file reading size of $data\n"), return; chomp $size; # Grab config information @@ -644,7 +648,8 @@ sub req_Modified $bytesleft -= $blocksize; } - close $fh; + close $fh + or (print "E failed to write temporary, $filename: $!\n"), return; # Ensure we have something sensible for the file mode if ( $mode =~ /u=(\w+)/ ) @@ -901,8 +906,13 @@ sub req_update # projects (heads in this case) to checkout. # if ($state->{module} eq '') { + my $heads_dir = $state->{CVSROOT} . '/refs/heads'; + if (!opendir HEADS, $heads_dir) { + print "E [server aborted]: Failed to open directory, " + . "$heads_dir: $!\nerror\n"; + return 0; + } print "E cvs update: Updating .\n"; - opendir HEADS, $state->{CVSROOT} . '/refs/heads'; while (my $head = readdir(HEADS)) { if (-f $state->{CVSROOT} . '/refs/heads/' . $head) { print "E cvs update: New directory `$head'\n"; @@ -1737,14 +1747,16 @@ sub req_annotate system("git-read-tree", $lastseenin); unless ($? == 0) { - die "Error running git-read-tree $lastseenin $file_index $!"; + print "E error running git-read-tree $lastseenin $file_index $!\n"; + return; } $log->info("Created index '$file_index' with commit $lastseenin - exit status $?"); # do a checkout of the file system('git-checkout-index', '-f', '-u', $filename); unless ($? == 0) { - die "Error running git-checkout-index -f -u $filename : $!"; + print "E error running git-checkout-index -f -u $filename : $!\n"; + return; } $log->info("Annotate $filename"); @@ -1754,7 +1766,11 @@ sub req_annotate # git-jsannotate telling us about commits we are hiding # from the client. - open(ANNOTATEHINTS, ">$tmpdir/.annotate_hints") or die "Error opening > $tmpdir/.annotate_hints $!"; + my $a_hints = "$tmpdir/.annotate_hints"; + if (!open(ANNOTATEHINTS, '>', $a_hints)) { + print "E failed to open '$a_hints' for writing: $!\n"; + return; + } for (my $i=0; $i < @$revisions; $i++) { print ANNOTATEHINTS $revisions->[$i][2]; @@ -1765,11 +1781,14 @@ sub req_annotate } print ANNOTATEHINTS "\n"; - close ANNOTATEHINTS; + close ANNOTATEHINTS + or (print "E failed to write $a_hints: $!\n"), return; - my $annotatecmd = 'git-annotate'; - open(ANNOTATE, "-|", $annotatecmd, '-l', '-S', "$tmpdir/.annotate_hints", $filename) - or die "Error invoking $annotatecmd -l -S $tmpdir/.annotate_hints $filename : $!"; + my @cmd = (qw(git-annotate -l -S), $a_hints, $filename); + if (!open(ANNOTATE, "-|", @cmd)) { + print "E error invoking ". join(' ',@cmd) .": $!\n"; + return; + } my $metadata = {}; print "E Annotations for $filename\n"; print "E ***************\n"; @@ -1996,12 +2015,12 @@ sub transmitfile { open NEWFILE, ">", $targetfile or die("Couldn't open '$targetfile' for writing : $!"); print NEWFILE $_ while ( <$fh> ); - close NEWFILE; + close NEWFILE or die("Failed to write '$targetfile': $!"); } else { print "$size\n"; print while ( <$fh> ); } - close $fh or die ("Couldn't close filehandle for transmitfile()"); + close $fh or die ("Couldn't close filehandle for transmitfile(): $!"); } else { die("Couldn't execute git-cat-file"); } @@ -2501,17 +2520,14 @@ sub update if ($parent eq $lastpicked) { next; } - open my $p, 'git-merge-base '. $lastpicked . ' ' - . $parent . '|'; - my @output = (<$p>); - close $p; - my $base = join('', @output); + my $base = safe_pipe_capture('git-merge-base', + $lastpicked, $parent); chomp $base; if ($base) { my @merged; # print "want to log between $base $parent \n"; open(GITLOG, '-|', 'git-log', "$base..$parent") - or die "Cannot call git-log: $!"; + or die "Cannot call git-log: $!"; my $mergedhash; while () { chomp; From f97949235470920578dff360f100e848894f73d4 Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 15 Jul 2007 15:49:33 -0400 Subject: [PATCH 210/213] Remove "WITH_P4IMPORT" knob from the Makefile Signed-off-by: Sean Estabrooks Signed-off-by: Junio C Hamano --- Makefile | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/Makefile b/Makefile index 5db3fb4ce1..73b487fba9 100644 --- a/Makefile +++ b/Makefile @@ -112,8 +112,6 @@ all:: # Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's # MakeMaker (e.g. using ActiveState under Cygwin). # -# Define WITH_P4IMPORT to build and install Python git-p4import script. -# # Define NO_TCLTK if you do not want Tcl/Tk GUI. # # The TCL_PATH variable governs the location of the Tcl interpreter @@ -223,20 +221,9 @@ SCRIPT_PERL = \ git-svnimport.perl git-cvsexportcommit.perl \ git-send-email.perl git-svn.perl -SCRIPT_PYTHON = \ - git-p4import.py - -ifdef WITH_P4IMPORT -SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ - $(patsubst %.perl,%,$(SCRIPT_PERL)) \ - $(patsubst %.py,%,$(SCRIPT_PYTHON)) \ - git-status git-instaweb -else SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ $(patsubst %.perl,%,$(SCRIPT_PERL)) \ git-status git-instaweb -endif - # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS = \ @@ -286,9 +273,6 @@ endif ifndef PERL_PATH PERL_PATH = /usr/bin/perl endif -ifndef PYTHON_PATH - PYTHON_PATH = /usr/local/bin/python -endif export PERL_PATH @@ -711,7 +695,6 @@ prefix_SQ = $(subst ','\'',$(prefix)) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) -PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH)) TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH)) LIBS = $(GITLIBS) $(EXTLIBS) @@ -782,15 +765,6 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh $(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak -$(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py - $(RM) $@ $@+ - sed -e '1s|#!.*/python|#!$(PYTHON_PATH_SQ)|' \ - -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ - -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ - $@.py >$@+ - chmod +x $@+ - mv $@+ $@ - perl/perl.mak: GIT-CFLAGS $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F) From 21ad54467a41f742491bc1d6223e9dd944ce8c97 Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 15 Jul 2007 15:51:01 -0400 Subject: [PATCH 211/213] Remove p4 rpm from git.spec.in. Signed-off-by: Sean Estabrooks Signed-off-by: Junio C Hamano --- git.spec.in | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/git.spec.in b/git.spec.in index 27182baa84..fe7b3d8215 100644 --- a/git.spec.in +++ b/git.spec.in @@ -12,7 +12,7 @@ URL: http://kernel.org/pub/software/scm/git/ Source: http://kernel.org/pub/software/scm/git/%{name}-%{version}.tar.gz BuildRequires: zlib-devel >= 1.2, openssl-devel, curl-devel, expat-devel %{!?_without_docs:, xmlto, asciidoc > 6.0.3} BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Requires: git-core, git-svn, git-cvs, git-arch, git-email, gitk, git-gui, git-p4, perl-Git +Requires: git-core, git-svn, git-cvs, git-arch, git-email, gitk, git-gui, perl-Git %description Git is a fast, scalable, distributed revision control system with an @@ -53,13 +53,6 @@ Requires: git-core = %{version}-%{release}, tla %description arch Git tools for importing Arch repositories. -%package p4 -Summary: Git tools for importing Perforce repositories -Group: Development/Tools -Requires: git-core = %{version}-%{release}, python -%description p4 -Git tools for importing Perforce repositories. - %package email Summary: Git tools for sending email Group: Development/Tools @@ -95,14 +88,14 @@ Perl interface to Git %setup -q %build -make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_P4IMPORT=YesPlease \ +make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" \ ETC_GITCONFIG=/etc/gitconfig \ - prefix=%{_prefix} PYTHON_PATH=%{python_path} all %{!?_without_docs: doc} + prefix=%{_prefix} all %{!?_without_docs: doc} %install rm -rf $RPM_BUILD_ROOT make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" DESTDIR=$RPM_BUILD_ROOT \ - WITH_P4IMPORT=YesPlease prefix=%{_prefix} mandir=%{_mandir} \ + prefix=%{_prefix} mandir=%{_mandir} \ ETC_GITCONFIG=/etc/gitconfig \ PYTHON_PATH=%{python_path} \ INSTALLDIRS=vendor install %{!?_without_docs: install-doc} @@ -110,10 +103,10 @@ find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';' find $RPM_BUILD_ROOT -type f -name '*.bs' -empty -exec rm -f {} ';' find $RPM_BUILD_ROOT -type f -name perllocal.pod -exec rm -f {} ';' -(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "p4import|archimport|svn|cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files +(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "archimport|svn|cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files (find $RPM_BUILD_ROOT%{perl_vendorlib} -type f | sed -e s@^$RPM_BUILD_ROOT@@) >> perl-files %if %{!?_without_docs:1}0 -(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "p4import|archimport|svn|git-cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files +(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "archimport|svn|git-cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files %else rm -rf $RPM_BUILD_ROOT%{_mandir} %endif @@ -145,13 +138,6 @@ rm -rf $RPM_BUILD_ROOT %{!?_without_docs: %{_mandir}/man1/git-archimport.1*} %{!?_without_docs: %doc Documentation/git-archimport.html } -%files p4 -%defattr(-,root,root) -%doc Documentation/git-p4import.txt -%{_bindir}/git-p4import -%{!?_without_docs: %{_mandir}/man1/git-p4import.1*} -%{!?_without_docs: %doc Documentation/git-p4import.html } - %files email %defattr(-,root,root) %doc Documentation/*email*.txt @@ -187,6 +173,9 @@ rm -rf $RPM_BUILD_ROOT %{!?_without_docs: %doc Documentation/technical} %changelog +* Sun Jul 15 2007 Sean Estabrooks +- Removed p4import. + * Tue Jun 26 2007 Quy Tonthat - Fixed problems looking for wrong manpages. From e3b4968f9caa04e83b2f27b64182187b13b86dab Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 15 Jul 2007 15:52:32 -0400 Subject: [PATCH 212/213] Demote git-p4import to contrib status. Move git-p4import.py and Documentation/git-p4import.txt into a contrib/p4import directory. Add a README there directing people to contrib/fast-import/git-p4 as a better alternative. Signed-off-by: Sean Estabrooks Signed-off-by: Junio C Hamano --- contrib/p4import/README | 1 + git-p4import.py => contrib/p4import/git-p4import.py | 0 {Documentation => contrib/p4import}/git-p4import.txt | 0 3 files changed, 1 insertion(+) create mode 100644 contrib/p4import/README rename git-p4import.py => contrib/p4import/git-p4import.py (100%) rename {Documentation => contrib/p4import}/git-p4import.txt (100%) diff --git a/contrib/p4import/README b/contrib/p4import/README new file mode 100644 index 0000000000..b9892b6793 --- /dev/null +++ b/contrib/p4import/README @@ -0,0 +1 @@ +Please see contrib/fast-import/git-p4 for a better Perforce importer. diff --git a/git-p4import.py b/contrib/p4import/git-p4import.py similarity index 100% rename from git-p4import.py rename to contrib/p4import/git-p4import.py diff --git a/Documentation/git-p4import.txt b/contrib/p4import/git-p4import.txt similarity index 100% rename from Documentation/git-p4import.txt rename to contrib/p4import/git-p4import.txt From 9dfdf14b3805e89aa2782458bda15b3dfae24c09 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 15 Jul 2007 16:41:17 -0700 Subject: [PATCH 213/213] GIT v1.5.3-rc2 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.3.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Documentation/RelNotes-1.5.3.txt b/Documentation/RelNotes-1.5.3.txt index 63e33b9d27..896ff1d95a 100644 --- a/Documentation/RelNotes-1.5.3.txt +++ b/Documentation/RelNotes-1.5.3.txt @@ -21,6 +21,8 @@ Updates since v1.5.2 * New commands and options. + - "git log --date=" can use more formats: iso8601, rfc2822. + - The hunk header output from "git diff" family can be customized with the attributes mechanism. See gitattributes(5) for details. @@ -68,6 +70,10 @@ Updates since v1.5.2 - "git gc --aggressive" tells the command to spend more cycles to optimize the repository harder. + - "git repack" learned a "window-memory" limit which + dynamically reduces the window size to stay within the + specified memory usage. + - "git repack" can be told to split resulting packs to avoid exceeding limit specified with "--max-pack-size". @@ -99,6 +105,9 @@ Updates since v1.5.2 * Updated behavior of existing commands. + - "git rm --cached" does not complain when removing a newly + added file from the index anymore. + - "git svn dcommit" retains local merge information. - "git config" to set values also honors type flags like --bool @@ -175,6 +184,11 @@ Updates since v1.5.2 concatenate them into a single line and treat the result as "oneline". + - "git p4import" has been demoted to contrib status. For + a superior option, checkout the git-p4 front end to + git-fast-import (also in contrib). The man page and p4 + rpm have been removed as well. + * Builds - old-style function definitions (most notably, a function @@ -218,6 +232,6 @@ this release, unless otherwise noted. -- exec >/var/tmp/1 -O=v1.5.3-rc1 +O=v1.5.3-rc2 echo O=`git describe refs/heads/master` git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint