From aca085e577688108a2480b96a2f7077424a74e4d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 3 Dec 2006 20:42:47 +0100 Subject: [PATCH 01/10] git-mv: search more precisely for source directory in index A move of a directory should find the entries in the index by searching for the name _including_ the slash. Otherwise, the directory can be shadowed by a file when it matches the prefix and is lexicographically smaller, e.g. "ab.c" shadows "ab/". Noticed by Sergey Vlasov. [jc: added Sergey's original reproduction recipe as a test case at the end of t7001.] Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-mv.c | 11 +++++++---- t/t7001-mv.sh | 13 +++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/builtin-mv.c b/builtin-mv.c index 54dd3bfe8a..d14a4a7f5c 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -146,21 +146,24 @@ int cmd_mv(int argc, const char **argv, const char *prefix) && lstat(dst, &st) == 0) bad = "cannot move directory over file"; else if (src_is_dir) { + const char *src_w_slash = add_slash(src); + int len_w_slash = length + 1; int first, last; modes[i] = WORKING_DIRECTORY; - first = cache_name_pos(src, length); + first = cache_name_pos(src_w_slash, len_w_slash); if (first >= 0) - die ("Huh? %s/ is in index?", src); + die ("Huh? %.*s is in index?", + len_w_slash, src_w_slash); first = -1 - first; for (last = first; last < active_nr; last++) { const char *path = active_cache[last]->name; - if (strncmp(path, src, length) - || path[length] != '/') + if (strncmp(path, src_w_slash, len_w_slash)) break; } + free((char *)src_w_slash); if (last - first < 1) bad = "source directory is empty"; diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 23a1eff3bb..2f4ff82e14 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -105,4 +105,17 @@ test_expect_success "Michael Cassar's test case" ' } ' +rm -fr papers partA path? + +test_expect_success "Sergey Vlasov's test case" ' + rm -fr .git && + git init-db && + mkdir ab && + date >ab.c && + date >ab/d && + git add ab.c ab && + git commit -m 'initial' && + git mv ab a +' + test_done From 7c0f7028ee04f135c7481671f05ca4a66072c78f Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 4 Dec 2006 08:44:08 +0100 Subject: [PATCH 02/10] Set permissions of each new file before "cvs add"ing it. Otherwise, an executable script in git would end up being checked into the CVS repository without the execute bit. [jc: with an additional test script from Robin Rosenberg.] Signed-off-by: Jim Meyering Signed-off-by: Junio C Hamano --- git-cvsexportcommit.perl | 13 +++++++++++++ t/t9200-git-cvsexportcommit.sh | 16 ++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 7bac16e946..c9d1d88f2e 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -116,6 +116,7 @@ if ($opt_a) { close MSG; my (@afiles, @dfiles, @mfiles, @dirs); +my %amodes; my @files = safe_pipe_capture('git-diff-tree', '-r', $parent, $commit); #print @files; $? && die "Error in git-diff-tree"; @@ -124,6 +125,7 @@ foreach my $f (@files) { my @fields = split(m!\s+!, $f); if ($fields[4] eq 'A') { my $path = $fields[5]; + $amodes{$path} = $fields[1]; push @afiles, $path; # add any needed parent directories $path = dirname $path; @@ -268,6 +270,7 @@ if (($? >> 8) == 2) { } foreach my $f (@afiles) { + set_new_file_permissions($f, $amodes{$f}); if (grep { $_ eq $f } @bfiles) { system('cvs', 'add','-kb',$f); } else { @@ -342,3 +345,13 @@ sub safe_pipe_capture { } return wantarray ? @output : join('',@output); } + +# For any file we want to add to cvs, we must first set its permissions +# properly, *before* the "cvs add ..." command. Otherwise, it is impossible +# to change the permission of the file in the CVS repository using only cvs +# commands. This should be fixed in cvs-1.12.14. +sub set_new_file_permissions { + my ($file, $perm) = @_; + chmod oct($perm), $file + or die "failed to set permissions of \"$file\": $!\n"; +} diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index 6e566d4409..c1024790e4 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -142,4 +142,20 @@ test_expect_success \ diff F/newfile6.png ../F/newfile6.png )' +test_expect_success 'Retain execute bit' ' + mkdir G && + echo executeon >G/on && + chmod +x G/on && + echo executeoff >G/off && + git add G/on && + git add G/off && + git commit -a -m "Execute test" && + ( + cd "$CVSWORK" && + git-cvsexportcommit -c HEAD + test -x G/on && + ! test -x G/off + ) +' + test_done From 396db813f2e9b56460cd783c73daf15150e36b41 Mon Sep 17 00:00:00 2001 From: David Miller Date: Sun, 3 Dec 2006 23:17:00 -0800 Subject: [PATCH 03/10] Pass -M to diff in request-pull Linus recommended this, otherwise any renames cause the diffstat output to be ridiculous in some circumstances. Because the corresponding "git-pull" done when the requestee actually makes pull shows the stat with rename detection enabled, it makes sense to match what the request message includes to that output, to make the result easier to verify. Signed-off-by: David S. Miller Signed-off-by: Junio C Hamano --- git-request-pull.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-request-pull.sh b/git-request-pull.sh index 4319e35c62..4eacc3a059 100755 --- a/git-request-pull.sh +++ b/git-request-pull.sh @@ -30,4 +30,4 @@ echo " $url" echo git log $baserev..$headrev | git-shortlog ; -git diff --stat --summary $baserev..$headrev +git diff -M --stat --summary $baserev..$headrev From f848718a6980ebda0eb5afb2ca49c3bc1e7b2b1d Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Mon, 4 Dec 2006 10:50:04 +0100 Subject: [PATCH 04/10] Make perl/ build procedure ActiveState friendly. On Cygwin + ActivateState Perl, Makefile generated with MakeMaker is not usable because of line-endings and back-slashes. This teaches perl/Makefile to write a handcrafted equivalent perl.mak file with 'make NO_PERL_MAKEMAKER=NoThanks'. Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- Makefile | 22 ++++++++++++++++------ perl/.gitignore | 3 ++- perl/Makefile | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 perl/Makefile diff --git a/Makefile b/Makefile index de3e9f38ec..a1861de2cc 100644 --- a/Makefile +++ b/Makefile @@ -91,6 +91,10 @@ all: # # Define USE_STDEV below if you want git to care about the underlying device # change being considered an inode change from the update-cache perspective. +# +# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's +# MakeMaker (e.g. using ActiveState under Cygwin). +# GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE @$(SHELL_PATH) ./GIT-VERSION-GEN @@ -539,6 +543,9 @@ endif ifdef NO_ACCURATE_DIFF BASIC_CFLAGS += -DNO_ACCURATE_DIFF endif +ifdef NO_PERL_MAKEMAKER + export NO_PERL_MAKEMAKER +endif # Shell quote (do not use $(call) to accommodate ancient setups); @@ -568,8 +575,8 @@ export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk gitweb/gitweb.cgi -all: perl/Makefile - $(MAKE) -C perl +all: + $(MAKE) -C perl PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all $(MAKE) -C templates strip: $(PROGRAMS) git$X @@ -602,7 +609,11 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh chmod +x $@+ mv $@+ $@ -$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/Makefile +$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak + +perl/perl.mak: GIT-CFLAGS + $(MAKE) -C perl PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F) + $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl rm -f $@ $@+ INSTLIBDIR=`$(MAKE) -C perl -s --no-print-directory instlibdir` && \ @@ -796,7 +807,7 @@ install: all $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)' $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install - $(MAKE) -C perl install + $(MAKE) -C perl prefix='$(prefix_SQ)' install if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \ then \ ln -f '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \ @@ -866,8 +877,7 @@ clean: rm -f $(htmldocs).tar.gz $(manpages).tar.gz rm -f gitweb/gitweb.cgi $(MAKE) -C Documentation/ clean - [ ! -f perl/Makefile ] || $(MAKE) -C perl/ clean || $(MAKE) -C perl/ clean - rm -f perl/ppport.h perl/Makefile.old + $(MAKE) -C perl clean $(MAKE) -C templates/ clean $(MAKE) -C t/ clean rm -f GIT-VERSION-FILE GIT-CFLAGS diff --git a/perl/.gitignore b/perl/.gitignore index e990caeea7..98b24772c7 100644 --- a/perl/.gitignore +++ b/perl/.gitignore @@ -1,4 +1,5 @@ -Makefile +perl.mak +perl.mak.old blib blibdirs pm_to_blib diff --git a/perl/Makefile b/perl/Makefile new file mode 100644 index 0000000000..bd483b0997 --- /dev/null +++ b/perl/Makefile @@ -0,0 +1,39 @@ +# +# Makefile for perl support modules and routine +# +makfile:=perl.mak + +PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) +prefix_SQ = $(subst ','\'',$(prefix)) + +all install instlibdir: $(makfile) + $(MAKE) -f $(makfile) $@ + +clean: + test -f $(makfile) && $(MAKE) -f $(makfile) $@ || exit 0 + $(RM) ppport.h + $(RM) $(makfile) + $(RM) $(makfile).old + +ifdef NO_PERL_MAKEMAKER +instdir_SQ = $(subst ','\'',$(prefix)/lib) +$(makfile): ../GIT-CFLAGS Makefile + echo all: > $@ + echo ' :' >> $@ + echo install: >> $@ + echo ' mkdir -p $(instdir_SQ)' >> $@ + echo ' $(RM) $(instdir_SQ)/Git.pm; cp Git.pm $(instdir_SQ)' >> $@ + echo ' $(RM) $(instdir_SQ)/Error.pm; \ + cp private-Error.pm $(instdir_SQ)/Error.pm' >> $@ + echo instlibdir: >> $@ + echo ' echo $(instdir_SQ)' >> $@ +else +$(makfile): Makefile.PL ../GIT-CFLAGS + '$(PERL_PATH_SQ)' $< FIRST_MAKEFILE='$@' PREFIX='$(prefix_SQ)' +endif + +# this is just added comfort for calling make directly in perl dir +# (even though GIT-CFLAGS aren't used yet. If ever) +../GIT-CFLAGS: + $(MAKE) -C .. GIT-CFLAGS + From e1147267afc0afa269884767c4045847d9a2be8a Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 4 Dec 2006 14:09:43 +0100 Subject: [PATCH 05/10] gitweb: Fix Atom feed : it is $logo, not $logo_url Fix contents of Atom feed element; it should be URL of $logo, not URL pointed by logo link. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 093bd72058..ffe8ce13ff 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -4282,7 +4282,7 @@ XML } if (defined $logo_url) { # not twice as wide as tall: 72 x 27 pixels - print "" . esc_url($logo_url) . "\n"; + print "" . esc_url($logo) . "\n"; } if (! %latest_date) { # dummy date to keep the feed valid until commits trickle in: From b360cca0b100e14abffa4cae78521b493c783738 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 4 Dec 2006 14:29:09 +0100 Subject: [PATCH 06/10] git-clone: Rename --use-immingled-remote option to --no-separate-remote With making --use-separate-remote default when creating non-bare clone, there was need for the flag which would turn off this behavior. It was called --use-immingled-remote. Immingle means to blend, to combine into one, to intermingle, but it is a bit obscure word. I think it would be better to use simply --no-separate-remote as the opposite to --use-separate-remote option to git clone. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 4 ++-- git-clone.sh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 4cb42237b5..d5efa00dea 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -11,7 +11,7 @@ SYNOPSIS [verse] 'git-clone' [--template=] [-l [-s]] [-q] [-n] [--bare] [-o ] [-u ] [--reference ] - [--use-separate-remote | --use-immingled-remote] + [--use-separate-remote | --no-separate-remote] [] DESCRIPTION @@ -105,7 +105,7 @@ OPTIONS of `$GIT_DIR/refs/heads/`. Only the local master branch is saved in the latter. This is the default. ---use-immingled-remote:: +--no-separate-remote:: Save remotes heads in the same namespace as the local heads, `$GIT_DIR/refs/heads/'. In regular repositories, this is a legacy setup git-clone created by default in diff --git a/git-clone.sh b/git-clone.sh index d4ee93f75b..89640396e9 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -14,7 +14,7 @@ die() { } usage() { - die "Usage: $0 [--template=] [--use-immingled-remote] [--reference ] [--bare] [-l [-s]] [-q] [-u ] [--origin ] [-n] []" + die "Usage: $0 [--template=] [--no-separate-remote] [--reference ] [--bare] [-l [-s]] [-q] [-u ] [--origin ] [-n] []" } get_repo_base() { @@ -140,7 +140,7 @@ while *,--use-separate-remote) # default use_separate_remote=t ;; - *,--use-immingled-remote) + *,--no-separate-remote) use_separate_remote= ;; 1,--reference) usage ;; *,--reference) @@ -176,7 +176,7 @@ repo="$1" test -n "$repo" || die 'you must specify a repository to clone.' -# --bare implies --no-checkout and --use-immingled-remote +# --bare implies --no-checkout and --no-separate-remote if test yes = "$bare" then if test yes = "$origin_override" From 4cd75359ad5d4c90ba6ae6d68ffb6d00e5092b8a Mon Sep 17 00:00:00 2001 From: Michael Loeffler Date: Mon, 4 Dec 2006 20:34:34 +0100 Subject: [PATCH 07/10] git-fetch: ignore dereferenced tags in expand_refs_wildcard There was a little bug in the brace expansion which should remove the ^{} from the tagname. It used ${name#'^{}'} instead of $(name%'^{}'}, the difference is that '#' will remove the given pattern only from the beginning of a string and '%' only from the end of a string. Signed-off-by: Michael Loeffler Signed-off-by: Junio C Hamano --- git-parse-remote.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 19bc3857d1..da064a53f6 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -116,7 +116,7 @@ expand_refs_wildcard () { while read sha1 name do mapped=${name#"$from"} - if test "z$name" != "z${name#'^{}'}" || + if test "z$name" != "z${name%'^{}'}" || test "z$name" = "z$mapped" then continue From 562cefbdbfaeb92f91c961c67960a93a7772220c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 4 Dec 2006 14:24:12 -0800 Subject: [PATCH 08/10] receive-pack: do not insist on fast-forward outside refs/heads/ Especially refs/tags/ hierarchy should match what git-fetch checks. Signed-off-by: Junio C Hamano --- receive-pack.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/receive-pack.c b/receive-pack.c index d56898c9b2..f18915117e 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -118,7 +118,8 @@ static int update(struct command *cmd) return error("unpack should have generated %s, " "but I can't find it!", new_hex); } - if (deny_non_fast_forwards && !is_null_sha1(old_sha1)) { + if (deny_non_fast_forwards && !is_null_sha1(old_sha1) && + !strncmp(name, "refs/heads/", 11)) { struct commit *old_commit, *new_commit; struct commit_list *bases, *ent; From c7c24889bb694f93a12f41a28fab26d30e571c17 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 3 Dec 2006 19:25:34 +0100 Subject: [PATCH 09/10] diff -b: ignore whitespace at end of line This is _not_ the same as "treat eol as whitespace", since that would mean that multiple empty lines would be treated as equal to e.g. a space. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t4015-diff-whitespace.sh | 6 ++---- xdiff/xutils.c | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 1bc5b7a412..adf4993bac 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -109,12 +109,10 @@ index d99af23..8b32fb5 100644 + whitespace at beginning whitespace change -whitespace in the middle --whitespace at end +white space in the middle -+whitespace at end + whitespace at end unchanged line --CR at endQ -+CR at end + CR at endQ EOF git-diff -b > out test_expect_success 'another test, with -b' 'diff -u expect out' diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 9e4bb47ee9..1b899f32c4 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -230,7 +230,8 @@ unsigned long xdl_hash_record(char const **data, char const *top, long flags) { while (ptr + 1 < top && isspace(ptr[1]) && ptr[1] != '\n') ptr++; - if (flags & XDF_IGNORE_WHITESPACE_CHANGE) { + if (flags & XDF_IGNORE_WHITESPACE_CHANGE + && ptr[1] != '\n') { ha += (ha << 5); ha ^= (unsigned long) ' '; } From 8ebe185bbf3f1f4f59bcc61e3d1849a76f6af983 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 3 Dec 2006 17:24:41 +0100 Subject: [PATCH 10/10] Document git-diff whitespace flags -b and -w Document git diff options -b / --ignore-space-change and -w / --ignore-all-space, introduced by Johannes Schindelin in commit 0d21efa5, "Teach diff about -b and -w flags". The description of options is taken from GNU diff man page and GNU Diffutils info documentation. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- Documentation/diff-options.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index e112172ca5..9cdd171af7 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -129,5 +129,21 @@ -a:: Shorthand for "--text". +--ignore-space-change:: + Ignore changes in amount of white space. This ignores white + space at line end, and consider all other sequences of one or + more white space characters to be equivalent. + +-b:: + Shorthand for "--ignore-space-change". + +--ignore-all-space:: + Ignore white space when comparing lines. This ignores + difference even if one line has white space where the other + line has none. + +-w:: + Shorthand for "--ignore-all-space". + For more detailed explanation on these common options, see also link:diffcore.html[diffcore documentation].