From 255cae88bcc8fcb0088459df13b55fa3d311b9e2 Mon Sep 17 00:00:00 2001 From: Andy Parkins Date: Sun, 26 Nov 2006 12:10:52 +0000 Subject: Use .git/config for storing "origin" shortcut repository Rather than use a separate config .git/remotes/ for remote shortcuts, this patch adds the analagous definitions to .git/config using git-repo-config calls. For example what was previously .git/remotes/origin URL: proto://host/path Pull: refs/heads/master:refs/heads/origin Is now added to .git/config as [remote "origin"] url = proto://host/path fetch = refs/heads/master:refs/heads/origin Signed-off-by: Andy Parkins Signed-off-by: Junio C Hamano diff --git a/git-clone.sh b/git-clone.sh index d4ee93f..b2d0f08 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -377,9 +377,9 @@ then *) origin_track="$remote_top/$origin" git-update-ref "refs/heads/$origin" "$head_sha1" ;; esac && - echo >"$GIT_DIR/remotes/$origin" \ - "URL: $repo -Pull: refs/heads/$head_points_at:$origin_track" && + git-repo-config remote."$origin".url "$repo" && + git-repo-config remote."$origin".fetch \ + "refs/heads/$head_points_at:$origin_track" && (cd "$GIT_DIR/$remote_top" && find . -type f -print) | while read dotslref do @@ -393,8 +393,8 @@ Pull: refs/heads/$head_points_at:$origin_track" && then continue fi - echo "Pull: refs/heads/${name}:$remote_top/${name}" - done >>"$GIT_DIR/remotes/$origin" && + git-repo-config remote."$origin".fetch "refs/heads/${name}:$remote_top/${name}" '^$' + done && case "$use_separate_remote" in t) rm -f "refs/remotes/$origin/HEAD" -- cgit v0.10.2-6-g49f6 From aca085e577688108a2480b96a2f7077424a74e4d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 3 Dec 2006 20:42:47 +0100 Subject: 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 diff --git a/builtin-mv.c b/builtin-mv.c index 54dd3bf..d14a4a7 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 23a1eff..2f4ff82 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 -- cgit v0.10.2-6-g49f6 From 7c0f7028ee04f135c7481671f05ca4a66072c78f Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 4 Dec 2006 08:44:08 +0100 Subject: 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 diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 7bac16e..c9d1d88 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 6e566d4..c102479 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 -- cgit v0.10.2-6-g49f6 From 396db813f2e9b56460cd783c73daf15150e36b41 Mon Sep 17 00:00:00 2001 From: David Miller Date: Sun, 3 Dec 2006 23:17:00 -0800 Subject: 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 diff --git a/git-request-pull.sh b/git-request-pull.sh index 4319e35..4eacc3a 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 -- cgit v0.10.2-6-g49f6 From f848718a6980ebda0eb5afb2ca49c3bc1e7b2b1d Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Mon, 4 Dec 2006 10:50:04 +0100 Subject: 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 diff --git a/Makefile b/Makefile index de3e9f3..a1861de 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 e990cae..98b2477 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 0000000..bd483b0 --- /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 + -- cgit v0.10.2-6-g49f6 From e1147267afc0afa269884767c4045847d9a2be8a Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 4 Dec 2006 14:09:43 +0100 Subject: 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 diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 093bd72..ffe8ce1 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: -- cgit v0.10.2-6-g49f6 From b360cca0b100e14abffa4cae78521b493c783738 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 4 Dec 2006 14:29:09 +0100 Subject: 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 diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 4cb4223..d5efa00 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 d4ee93f..8964039 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" -- cgit v0.10.2-6-g49f6 From 4cd75359ad5d4c90ba6ae6d68ffb6d00e5092b8a Mon Sep 17 00:00:00 2001 From: Michael Loeffler Date: Mon, 4 Dec 2006 20:34:34 +0100 Subject: 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 diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 19bc385..da064a5 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 -- cgit v0.10.2-6-g49f6 From 562cefbdbfaeb92f91c961c67960a93a7772220c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 4 Dec 2006 14:24:12 -0800 Subject: 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 diff --git a/receive-pack.c b/receive-pack.c index d56898c..f189151 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; -- cgit v0.10.2-6-g49f6 From 0fb1eaa8850557249a8d1c43a4f0f3ac5a5f75ce Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 4 Dec 2006 02:11:39 -0800 Subject: unpack-trees: make sure "df_conflict_entry.name" is NUL terminated. The structure that ends with a flexible array member (or 0 length array with older GCC) "char name[FLEX_ARRAY]" is allocated on the stack and we use it after clearing its entire size with memset. That does not guarantee that "name" is properly NUL terminated as we intended on platforms with more forgiving structure alignment requirements. Reported breakage on m68k by Roman Zippel. Signed-off-by: Junio C Hamano diff --git a/unpack-trees.c b/unpack-trees.c index 7cfd628..47aa804 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -370,7 +370,7 @@ int unpack_trees(struct object_list *trees, struct unpack_trees_options *o) int i; struct object_list *posn = trees; struct tree_entry_list df_conflict_list; - struct cache_entry df_conflict_entry; + static struct cache_entry *dfc; memset(&df_conflict_list, 0, sizeof(df_conflict_list)); df_conflict_list.next = &df_conflict_list; @@ -381,8 +381,10 @@ int unpack_trees(struct object_list *trees, struct unpack_trees_options *o) state.refresh_cache = 1; o->merge_size = len; - memset(&df_conflict_entry, 0, sizeof(df_conflict_entry)); - o->df_conflict_entry = &df_conflict_entry; + + if (!dfc) + dfc = xcalloc(1, sizeof(struct cache_entry) + 1); + o->df_conflict_entry = dfc; if (len) { posns = xmalloc(len * sizeof(struct tree_entry_list *)); -- cgit v0.10.2-6-g49f6 From c7c24889bb694f93a12f41a28fab26d30e571c17 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 3 Dec 2006 19:25:34 +0100 Subject: 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 diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 1bc5b7a..adf4993 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 9e4bb47..1b899f3 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) ' '; } -- cgit v0.10.2-6-g49f6 From 8ebe185bbf3f1f4f59bcc61e3d1849a76f6af983 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 3 Dec 2006 17:24:41 +0100 Subject: 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 diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index e112172..9cdd171 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]. -- cgit v0.10.2-6-g49f6 From 3a9f1a55eec9cc508abccda6a3fee795b812d66d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 6 Dec 2006 13:27:40 +0100 Subject: cvs-migration document: make the need for "push" more obvious It really is an important concept to grasp for people coming from CVS. Even if it is briefly mentioned, it is not obvious enough to sink in. [jc: with wording updates from J. Bruce Fields] Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt index 6812683..9c2a395 100644 --- a/Documentation/cvs-migration.txt +++ b/Documentation/cvs-migration.txt @@ -24,6 +24,11 @@ First, note some ways that git differs from CVS: single shared repository which people can synchronize with; see below for details. + * Since every working tree contains a repository, a commit in your + private repository will not publish your changes; it will only create + a revision. You have to "push" your changes to a public repository to + make them visible to others. + Importing a CVS archive ----------------------- -- cgit v0.10.2-6-g49f6 From 4003a58e415e5f51a3becac0079505b72299a7bc Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 6 Dec 2006 12:19:50 -0500 Subject: cvs-migration: improved section titles, better push/commit explanation Rename the section titles to make the "how-to" content of the section obvious. Also clarify that changes have to be commited before they can be pushed. Signed-off-by: Junio C Hamano diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt index 9c2a395..a436180 100644 --- a/Documentation/cvs-migration.txt +++ b/Documentation/cvs-migration.txt @@ -81,8 +81,8 @@ variants of this model. With a small group, developers may just pull changes from each other's repositories without the need for a central maintainer. -Emulating the CVS Development Model ------------------------------------ +Creating a Shared Repository +---------------------------- Start with an ordinary git working directory containing the project, and remove the checked-out files, keeping just the bare .git directory: @@ -110,7 +110,10 @@ $ GIT_DIR=repo.git git repo-config core.sharedrepository true Make sure committers have a umask of at most 027, so that the directories they create are writable and searchable by other group members. -Suppose this repository is now set up in /pub/repo.git on the host +Performing Development on a Shared Repository +--------------------------------------------- + +Suppose a repository is now set up in /pub/repo.git on the host foo.com. Then as an individual committer you can clone the shared repository: @@ -139,15 +142,17 @@ Pull: master:origin ------------ ================================ -You can update the shared repository with your changes using: +You can update the shared repository with your changes by first commiting +your changes, and then using: ------------------------------------------------ $ git push origin master ------------------------------------------------ -If someone else has updated the repository more recently, `git push`, like -`cvs commit`, will complain, in which case you must pull any changes -before attempting the push again. +to "push" those commits to the shared repository. If someone else has +updated the repository more recently, `git push`, like `cvs commit`, will +complain, in which case you must pull any changes before attempting the +push again. In the `git push` command above we specify the name of the remote branch to update (`master`). If we leave that out, `git push` tries to update -- cgit v0.10.2-6-g49f6 From 49ed2bc4660c7cd0592cf21cc514080574d06320 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 4 Dec 2006 19:44:40 -0800 Subject: git-reset to remove "$GIT_DIR/MERGE_MSG" An earlier commit a9cb3c6e changed git-commit to use the contents of MERGE_MSG even when we do not have MERGE_HEAD (the rationale is in its log message). However, the change tricks the following sequence to include a merge message in a completely unrelated commit: $ git pull somewhere : oops, the conflicts are too much. forget it. $ git reset --hard : work work work $ git commit To fix this confusion, this patch makes "git reset" to remove the leftover MERGE_MSG that was prepared when the user abandoned the merge. Signed-off-by: Junio C Hamano Acked-by: Luben Tuikov Date: Wed, 6 Dec 2006 10:52:04 -0800 Subject: git-merge: squelch needless error message. While deciding if the new style command line argument is a tag or a branch, we checked it with "git show-ref -s --verify" to see if results in an error, but when it is not a branch, the check leaked the error message out, which was not needed to be shown to the end user. Signed-off-by: Junio C Hamano diff --git a/git-merge.sh b/git-merge.sh index 272f004..efdbabf 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -189,7 +189,7 @@ else merge_name=$(for remote do rh=$(git-rev-parse --verify "$remote"^0 2>/dev/null) && - bh=$(git show-ref -s --verify "refs/heads/$remote") && + bh=$(git show-ref -s --verify "refs/heads/$remote" 2>/dev/null) && if test "$rh" = "$bh" then echo "$rh branch '$remote' of ." -- cgit v0.10.2-6-g49f6 From 5a4cf3346d6c37007a7f5f94697868a5b2f2fa29 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 4 Dec 2006 23:47:22 +0100 Subject: gitweb: Allow PNG, GIF, JPEG images to be displayed in "blob" view Allow images in one of web formats (PNG, GIF, JPEG) - actually files with mimetype of image/png, image/git, image/jpeg - to be displayed in "blob" view using element, instead of using "blob_plain" view for them, like for all other files except also text/* mimetype files. This makes possible to easily go to file history, to HEAD version of the file, to appropriate commit etc; all of those are not available in "blob_plain" (raw) view. Only text files can have "blame" view link in the formats part of navbar. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index ffe8ce1..61e2ab2 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3229,10 +3229,13 @@ sub git_blob { open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash or die_error(undef, "Couldn't cat $file_name, $hash"); my $mimetype = blob_mimetype($fd, $file_name); - if ($mimetype !~ m/^text\//) { + if ($mimetype !~ m!^(?:text/|image/(?:gif|png|jpeg)$)!) { close $fd; return git_blob_plain($mimetype); } + # we can have blame only for text/* mimetype + $have_blame &&= ($mimetype =~ m!^text/!); + git_header_html(undef, $expires); my $formats_nav = ''; if (defined $hash_base && (my %co = parse_commit($hash_base))) { @@ -3269,13 +3272,24 @@ sub git_blob { } git_print_page_path($file_name, "blob", $hash_base); print "
\n"; - my $nr; - while (my $line = <$fd>) { - chomp $line; - $nr++; - $line = untabify($line); - printf "
%4i %s
\n", - $nr, $nr, $nr, esc_html($line, -nbsp=>1); + if ($mimetype =~ m!^text/!) { + my $nr; + while (my $line = <$fd>) { + chomp $line; + $nr++; + $line = untabify($line); + printf "
%4i %s
\n", + $nr, $nr, $nr, esc_html($line, -nbsp=>1); + } + } elsif ($mimetype =~ m!^image/!) { + print qq!$file_name$hash, + hash_base=>$hash_base, file_name=>$file_name) . + qq!" />\n!; } close $fd or print "Reading blob failed.\n"; -- cgit v0.10.2-6-g49f6 From ebdf7b952215946eff863e4da28f924178acea4f Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 4 Dec 2006 00:51:16 -0800 Subject: git-svn: avoid network timeouts for long-running fetches Long-running fetches run inside children to avoid memory leaks. When we refork, the connection in the parent can be idle for a long time; attempting to reuse it in the next child can result in timeouts. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano diff --git a/git-svn.perl b/git-svn.perl index d0bd0bd..747daf0 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -459,6 +459,7 @@ sub fetch_lib { $min = $max + 1; $max += $inc; $max = $head if ($max > $head); + $SVN = libsvn_connect($SVN_URL); } restore_index($index); return { revision => $last_rev, commit => $last_commit }; -- cgit v0.10.2-6-g49f6 From de51faf3888505fa3d661d4c35f32ecaf9fa1087 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 6 Dec 2006 11:22:55 -0800 Subject: git-merge: fix "fix confusion between tag and branch" for real An earlier commit 3683dc5a broke the merge message generation with a careless use of && where it was not needed, breaking the merge message for cases where non branches are given. Signed-off-by: Junio C Hamano diff --git a/git-merge.sh b/git-merge.sh index efdbabf..a948878 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -188,8 +188,9 @@ else # in this loop. merge_name=$(for remote do - rh=$(git-rev-parse --verify "$remote"^0 2>/dev/null) && - bh=$(git show-ref -s --verify "refs/heads/$remote" 2>/dev/null) && + rh=$(git-rev-parse --verify "$remote"^0 2>/dev/null) || + continue ;# not something we can merge + bh=$(git show-ref -s --verify "refs/heads/$remote" 2>/dev/null) if test "$rh" = "$bh" then echo "$rh branch '$remote' of ." -- cgit v0.10.2-6-g49f6 From cd976f5c52694acb4b23c3f2425ed4f0a47ec799 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 6 Dec 2006 23:18:05 -0500 Subject: Documentation: reorganize cvs-migration.txt Modify cvs-migration.txt so it explains first how to develop against a shared repository, then how to set up a shared repository, then how to import a repository from cvs. Though this seems chronologically backwards, it's still readable in this order, and it puts the more commonly needed material closer to the front. Remove the annotate/pickaxe section; perhaps it can find a place elsewhere in the future. Remove most of the "why git is better than cvs" stuff from the introduction. Add some minor clarifications, including two that have come up several times on the mailing list: 1. Recommend committing any changes before running pull. 2. Note that changes must be commited before they can be pushed. Update the clone discussion to reflect the new --use-separate-remotes default, and add a brief mention of git-cvsserver. Signed-off-by: J. Bruce Fields Signed-off-by: Junio C Hamano diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt index a436180..47846bd 100644 --- a/Documentation/cvs-migration.txt +++ b/Documentation/cvs-migration.txt @@ -1,121 +1,21 @@ git for CVS users ================= -So you're a CVS user. That's OK, it's a treatable condition. The job of -this document is to put you on the road to recovery, by helping you -convert an existing cvs repository to git, and by showing you how to use a -git repository in a cvs-like fashion. +Git differs from CVS in that every working tree contains a repository with +a full copy of the project history, and no repository is inherently more +important than any other. However, you can emulate the CVS model by +designating a single shared repository which people can synchronize with; +this document explains how to do that. Some basic familiarity with git is required. This link:tutorial.html[tutorial introduction to git] should be sufficient. -First, note some ways that git differs from CVS: +Developing against a shared repository +-------------------------------------- - * Commits are atomic and project-wide, not per-file as in CVS. - - * Offline work is supported: you can make multiple commits locally, - then submit them when you're ready. - - * Branching is fast and easy. - - * Every working tree contains a repository with a full copy of the - project history, and no repository is inherently more important than - any other. However, you can emulate the CVS model by designating a - single shared repository which people can synchronize with; see below - for details. - - * Since every working tree contains a repository, a commit in your - private repository will not publish your changes; it will only create - a revision. You have to "push" your changes to a public repository to - make them visible to others. - -Importing a CVS archive ------------------------ - -First, install version 2.1 or higher of cvsps from -link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make -sure it is in your path. The magic command line is then - -------------------------------------------- -$ git cvsimport -v -d -C -------------------------------------------- - -This puts a git archive of the named CVS module in the directory -, which will be created if necessary. The -v option makes -the conversion script very chatty. - -The import checks out from CVS every revision of every file. Reportedly -cvsimport can average some twenty revisions per second, so for a -medium-sized project this should not take more than a couple of minutes. -Larger projects or remote repositories may take longer. - -The main trunk is stored in the git branch named `origin`, and additional -CVS branches are stored in git branches with the same names. The most -recent version of the main trunk is also left checked out on the `master` -branch, so you can start adding your own changes right away. - -The import is incremental, so if you call it again next month it will -fetch any CVS updates that have been made in the meantime. For this to -work, you must not modify the imported branches; instead, create new -branches for your own changes, and merge in the imported branches as -necessary. - -Development Models ------------------- - -CVS users are accustomed to giving a group of developers commit access to -a common repository. In the next section we'll explain how to do this -with git. However, the distributed nature of git allows other development -models, and you may want to first consider whether one of them might be a -better fit for your project. - -For example, you can choose a single person to maintain the project's -primary public repository. Other developers then clone this repository -and each work in their own clone. When they have a series of changes that -they're happy with, they ask the maintainer to pull from the branch -containing the changes. The maintainer reviews their changes and pulls -them into the primary repository, which other developers pull from as -necessary to stay coordinated. The Linux kernel and other projects use -variants of this model. - -With a small group, developers may just pull changes from each other's -repositories without the need for a central maintainer. - -Creating a Shared Repository ----------------------------- - -Start with an ordinary git working directory containing the project, and -remove the checked-out files, keeping just the bare .git directory: - ------------------------------------------------- -$ mv project/.git /pub/repo.git -$ rm -r project/ ------------------------------------------------- - -Next, give every team member read/write access to this repository. One -easy way to do this is to give all the team members ssh access to the -machine where the repository is hosted. If you don't want to give them a -full shell on the machine, there is a restricted shell which only allows -users to do git pushes and pulls; see gitlink:git-shell[1]. - -Put all the committers in the same group, and make the repository -writable by that group: - ------------------------------------------------- -$ chgrp -R $group repo.git -$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s -$ GIT_DIR=repo.git git repo-config core.sharedrepository true ------------------------------------------------- - -Make sure committers have a umask of at most 027, so that the directories -they create are writable and searchable by other group members. - -Performing Development on a Shared Repository ---------------------------------------------- - -Suppose a repository is now set up in /pub/repo.git on the host +Suppose a shared repository is set up in /pub/repo.git on the host foo.com. Then as an individual committer you can clone the shared -repository: +repository over ssh with: ------------------------------------------------ $ git clone foo.com:/pub/repo.git/ my-project @@ -129,7 +29,8 @@ $ git pull origin ------------------------------------------------ which merges in any work that others might have done since the clone -operation. +operation. If there are uncommitted changes in your working tree, commit +them first before running git pull. [NOTE] ================================ @@ -137,8 +38,8 @@ The first `git clone` places the following in the `my-project/.git/remotes/origin` file, and that's why the previous step and the next step both work. ------------ -URL: foo.com:/pub/project.git/ my-project -Pull: master:origin +URL: foo.com:/pub/project.git/ +Pull: refs/heads/master:refs/remotes/origin/master ------------ ================================ @@ -161,21 +62,76 @@ in the local repository. So the last `push` can be done with either of: ------------ $ git push origin -$ git push repo.shared.xz:/pub/scm/project.git/ +$ git push foo.com:/pub/project.git/ ------------ as long as the shared repository does not have any branches other than `master`. -[NOTE] -============ -Because of this behavior, if the shared repository and the developer's -repository both have branches named `origin`, then a push like the above -attempts to update the `origin` branch in the shared repository from the -developer's `origin` branch. The results may be unexpected, so it's -usually best to remove any branch named `origin` from the shared -repository. -============ +Setting Up a Shared Repository +------------------------------ + +We assume you have already created a git repository for your project, +possibly created from scratch or from a tarball (see the +link:tutorial.html[tutorial]), or imported from an already existing CVS +repository (see the next section). + +If your project's working directory is /home/alice/myproject, you can +create a shared repository at /pub/repo.git with: + +------------------------------------------------ +$ git clone -bare /home/alice/myproject /pub/repo.git +------------------------------------------------ + +Next, give every team member read/write access to this repository. One +easy way to do this is to give all the team members ssh access to the +machine where the repository is hosted. If you don't want to give them a +full shell on the machine, there is a restricted shell which only allows +users to do git pushes and pulls; see gitlink:git-shell[1]. + +Put all the committers in the same group, and make the repository +writable by that group: + +------------------------------------------------ +$ cd /pub +$ chgrp -R $group repo.git +$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s +$ GIT_DIR=repo.git git repo-config core.sharedrepository true +------------------------------------------------ + +Make sure committers have a umask of at most 027, so that the directories +they create are writable and searchable by other group members. + +Importing a CVS archive +----------------------- + +First, install version 2.1 or higher of cvsps from +link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make +sure it is in your path. The magic command line is then + +------------------------------------------- +$ git cvsimport -v -d -C +------------------------------------------- + +This puts a git archive of the named CVS module in the directory +, which will be created if necessary. The -v option makes +the conversion script very chatty. + +The import checks out from CVS every revision of every file. Reportedly +cvsimport can average some twenty revisions per second, so for a +medium-sized project this should not take more than a couple of minutes. +Larger projects or remote repositories may take longer. + +The main trunk is stored in the git branch named `origin`, and additional +CVS branches are stored in git branches with the same names. The most +recent version of the main trunk is also left checked out on the `master` +branch, so you can start adding your own changes right away. + +The import is incremental, so if you call it again next month it will +fetch any CVS updates that have been made in the meantime. For this to +work, you must not modify the imported branches; instead, create new +branches for your own changes, and merge in the imported branches as +necessary. Advanced Shared Repository Management ------------------------------------- @@ -188,127 +144,30 @@ You can enforce finer grained permissions using update hooks. See link:howto/update-hook-example.txt[Controlling access to branches using update hooks]. -CVS annotate ------------- +Providing CVS Access to a git Repository +---------------------------------------- + +It is also possible to provide true CVS access to a git repository, so +that developers can still use CVS; see gitlink:git-cvsserver[1] for +details. + +Alternative Development Models +------------------------------ + +CVS users are accustomed to giving a group of developers commit access to +a common repository. As we've seen, this is also possible with git. +However, the distributed nature of git allows other development models, +and you may want to first consider whether one of them might be a better +fit for your project. + +For example, you can choose a single person to maintain the project's +primary public repository. Other developers then clone this repository +and each work in their own clone. When they have a series of changes that +they're happy with, they ask the maintainer to pull from the branch +containing the changes. The maintainer reviews their changes and pulls +them into the primary repository, which other developers pull from as +necessary to stay coordinated. The Linux kernel and other projects use +variants of this model. -So, something has gone wrong, and you don't know whom to blame, and -you're an ex-CVS user and used to do "cvs annotate" to see who caused -the breakage. You're looking for the "git annotate", and it's just -claiming not to find such a script. You're annoyed. - -Yes, that's right. Core git doesn't do "annotate", although it's -technically possible, and there are at least two specialized scripts out -there that can be used to get equivalent information (see the git -mailing list archives for details). - -git has a couple of alternatives, though, that you may find sufficient -or even superior depending on your use. One is called "git-whatchanged" -(for obvious reasons) and the other one is called "pickaxe" ("a tool for -the software archaeologist"). - -The "git-whatchanged" script is a truly trivial script that can give you -a good overview of what has changed in a file or a directory (or an -arbitrary list of files or directories). The "pickaxe" support is an -additional layer that can be used to further specify exactly what you're -looking for, if you already know the specific area that changed. - -Let's step back a bit and think about the reason why you would -want to do "cvs annotate a-file.c" to begin with. - -You would use "cvs annotate" on a file when you have trouble -with a function (or even a single "if" statement in a function) -that happens to be defined in the file, which does not do what -you want it to do. And you would want to find out why it was -written that way, because you are about to modify it to suit -your needs, and at the same time you do not want to break its -current callers. For that, you are trying to find out why the -original author did things that way in the original context. - -Many times, it may be enough to see the commit log messages of -commits that touch the file in question, possibly along with the -patches themselves, like this: - - $ git-whatchanged -p a-file.c - -This will show log messages and patches for each commit that -touches a-file. - -This, however, may not be very useful when this file has many -modifications that are not related to the piece of code you are -interested in. You would see many log messages and patches that -do not have anything to do with the piece of code you are -interested in. As an example, assuming that you have this piece -of code that you are interested in in the HEAD version: - - if (frotz) { - nitfol(); - } - -you would use git-rev-list and git-diff-tree like this: - - $ git-rev-list HEAD | - git-diff-tree --stdin -v -p -S'if (frotz) { - nitfol(); - }' - -We have already talked about the "\--stdin" form of git-diff-tree -command that reads the list of commits and compares each commit -with its parents (otherwise you should go back and read the tutorial). -The git-whatchanged command internally runs -the equivalent of the above command, and can be used like this: - - $ git-whatchanged -p -S'if (frotz) { - nitfol(); - }' - -When the -S option is used, git-diff-tree command outputs -differences between two commits only if one tree has the -specified string in a file and the corresponding file in the -other tree does not. The above example looks for a commit that -has the "if" statement in it in a file, but its parent commit -does not have it in the same shape in the corresponding file (or -the other way around, where the parent has it and the commit -does not), and the differences between them are shown, along -with the commit message (thanks to the -v flag). It does not -show anything for commits that do not touch this "if" statement. - -Also, in the original context, the same statement might have -appeared at first in a different file and later the file was -renamed to "a-file.c". CVS annotate would not help you to go -back across such a rename, but git would still help you in such -a situation. For that, you can give the -C flag to -git-diff-tree, like this: - - $ git-whatchanged -p -C -S'if (frotz) { - nitfol(); - }' - -When the -C flag is used, file renames and copies are followed. -So if the "if" statement in question happens to be in "a-file.c" -in the current HEAD commit, even if the file was originally -called "o-file.c" and then renamed in an earlier commit, or if -the file was created by copying an existing "o-file.c" in an -earlier commit, you will not lose track. If the "if" statement -did not change across such a rename or copy, then the commit that -does rename or copy would not show in the output, and if the -"if" statement was modified while the file was still called -"o-file.c", it would find the commit that changed the statement -when it was in "o-file.c". - -NOTE: The current version of "git-diff-tree -C" is not eager - enough to find copies, and it will miss the fact that a-file.c - was created by copying o-file.c unless o-file.c was somehow - changed in the same commit. - -You can use the --pickaxe-all flag in addition to the -S flag. -This causes the differences from all the files contained in -those two commits, not just the differences between the files -that contain this changed "if" statement: - - $ git-whatchanged -p -C -S'if (frotz) { - nitfol(); - }' --pickaxe-all - -NOTE: This option is called "--pickaxe-all" because -S - option is internally called "pickaxe", a tool for software - archaeologists. +With a small group, developers may just pull changes from each other's +repositories without the need for a central maintainer. -- cgit v0.10.2-6-g49f6 From 46732fae3d049254f4f12b8a716cf56159277eda Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 6 Dec 2006 23:01:00 -0500 Subject: change the unpack limit treshold to a saner value Currently the treshold is 5000. The likelihood of this value to ever be crossed for a single push is really small making it not really useful. The optimal treshold for a pure space saving on a filesystem with 4kb blocks is 3. However this is likely to create many small packs concentrating a large number of files in a single directory compared to the same objects which are spread over 256 directories when loose. This means we would need 512 objects per pack on average to approximagte the same directory cost (a pack has 2 files because of the index). But 512 is a really high value just like 5000 since most pushes are unlikely to have that many objects. So let's try with a value of 100 which should have a good balance between small pushes going to be exploded into loose objects and large pushes kept as whole packs. This is not a replacement for periodic repacks of course. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano diff --git a/receive-pack.c b/receive-pack.c index a20bc92..e76d9ae 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -11,7 +11,7 @@ static const char receive_pack_usage[] = "git-receive-pack "; static int deny_non_fast_forwards = 0; -static int unpack_limit = 5000; +static int unpack_limit = 100; static int report_status; static char capabilities[] = " report-status delete-refs "; -- cgit v0.10.2-6-g49f6 From 4f88d3e0cbf443cd309c2c881209f3366f14023d Mon Sep 17 00:00:00 2001 From: Martin Langhoff Date: Thu, 7 Dec 2006 16:38:50 +1300 Subject: cvsserver: Avoid miscounting bytes in Perl v5.8.x At some point between v5.6 and 5.8 Perl started to assume its input, output and filehandles are UTF-8. This breaks the counting of bytes for the CVS protocol, resulting in the client expecting less data than we actually send, and storing truncated files. Signed-off-by: Martin Langhoff Signed-off-by: Junio C Hamano diff --git a/git-cvsserver.perl b/git-cvsserver.perl index ca519b7..197014d 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -17,6 +17,7 @@ use strict; use warnings; +use bytes; use Fcntl; use File::Temp qw/tempdir tempfile/; -- cgit v0.10.2-6-g49f6 From db9819a40a56b4747931e637c1c22a104dcab902 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 8 Dec 2006 01:27:21 -0500 Subject: Documentation: update git-clone man page with new behavior Update git-clone man page to reflect recent changes (--use-separate-remote default and use of .git/config instead of remotes files), and rewrite introduction. Signed-off-by: J. Bruce Fields Signed-off-by: Junio C Hamano diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index d5efa00..985043f 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -16,22 +16,21 @@ SYNOPSIS DESCRIPTION ----------- -Clones a repository into a newly created directory. All remote -branch heads are copied under `$GIT_DIR/refs/heads/`, except -that the remote `master` is also copied to `origin` branch. -In addition, `$GIT_DIR/remotes/origin` file is set up to have -this line: +Clones a repository into a newly created directory, creates +remote-tracking branches for each branch in the cloned repository +(visible using `git branch -r`), and creates and checks out a master +branch equal to the cloned repository's master branch. - Pull: master:origin - -This is to help the typical workflow of working off of the -remote `master` branch. Every time `git pull` without argument -is run, the progress on the remote `master` branch is tracked by -copying it into the local `origin` branch, and merged into the -branch you are currently working on. Remote branches other than -`master` are also added there to be tracked. +After the clone, a plain `git fetch` without arguments will update +all the remote-tracking branches, and a `git pull` without +arguments will in addition merge the remote master branch into the +current branch. +This default configuration is achieved by creating references to +the remote branch heads under `$GIT_DIR/refs/remotes/origin` and +by initializing `remote.origin.url` and `remote.origin.fetch` +configuration variables. OPTIONS ------- -- cgit v0.10.2-6-g49f6 From 006ede5e860717ff1ec68125393bcd4e74507e5b Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 8 Dec 2006 01:55:19 -0800 Subject: git-svn: extra error check to ensure we open a file correctly This may be an issue with repositories imported with commit 27a1a8014b842c0d70fdc91c68dd361ca2dfb34c or later, but before commit dad73c0bb9f33323ec1aacf560a6263f1d85f81a. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano diff --git a/git-svn.perl b/git-svn.perl index 747daf0..ff61b92 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3438,6 +3438,9 @@ sub open_file { my ($self, $path, $pb, $rev) = @_; my ($mode, $blob) = (safe_qx('git-ls-tree',$self->{c},'--',$path) =~ /^(\d{6}) blob ([a-f\d]{40})\t/); + unless (defined $mode && defined $blob) { + die "$path was not found in commit $self->{c} (r$rev)\n"; + } { path => $path, mode_a => $mode, mode_b => $mode, blob => $blob, pool => SVN::Pool->new, action => 'M' }; } -- cgit v0.10.2-6-g49f6 From bbee1d971dc07c29f840b439aa2a2c890a12cf9f Mon Sep 17 00:00:00 2001 From: Uwe Zeisberger Date: Fri, 8 Dec 2006 12:44:31 +0100 Subject: Fix documentation copy&paste typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was introduced in 45a3b12cfd3eaa05bbb0954790d5be5b8240a7b5 Signed-off-by: Uwe Kleine-K,AC6(Bnig Signed-off-by: Junio C Hamano diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 61e2ab2..5ea3fda 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -120,7 +120,7 @@ our %feature = ( # To disable system wide have in $GITWEB_CONFIG # $feature{'snapshot'}{'default'} = [undef]; # To have project specific config enable override in $GITWEB_CONFIG - # $feature{'blame'}{'override'} = 1; + # $feature{'snapshot'}{'override'} = 1; # and in project config gitweb.snapshot = none|gzip|bzip2; 'snapshot' => { 'sub' => \&feature_snapshot, -- cgit v0.10.2-6-g49f6 From a552db3a64464f1b514b074fbc43aaf599106087 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 8 Dec 2006 02:20:17 -0800 Subject: git-svn: use do_switch for --follow-parent if the SVN library supports it do_switch works with the SVN Perl bindings after r22312 in the Subversion trunk. Since no released version of SVN currently supports it; we'll just autodetect it and enable its usage when a user has a recent-enough version of SVN. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano diff --git a/git-svn.perl b/git-svn.perl index ff61b92..1f8a3b0 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -72,7 +72,7 @@ my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit, $_username, $_config_dir, $_no_auth_cache, $_xfer_delta, $_pager, $_color); my (@_branch_from, %tree_map, %users, %rusers, %equiv); -my ($_svn_co_url_revs, $_svn_pg_peg_revs); +my ($_svn_co_url_revs, $_svn_pg_peg_revs, $_svn_can_do_switch); my @repo_path_split_cache; my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext, @@ -2877,6 +2877,24 @@ sub libsvn_connect { return $ra; } +sub libsvn_can_do_switch { + unless (defined $_svn_can_do_switch) { + my $pool = SVN::Pool->new; + my $rep = eval { + $SVN->do_switch(1, '', 0, $SVN->{url}, + SVN::Delta::Editor->new, $pool); + }; + if ($@) { + $_svn_can_do_switch = 0; + } else { + $rep->abort_report($pool); + $_svn_can_do_switch = 1; + } + $pool->clear; + } + $_svn_can_do_switch; +} + sub libsvn_dup_ra { my ($ra) = @_; SVN::Ra->new(map { $_ => $ra->{$_} } qw/config url @@ -3198,12 +3216,26 @@ sub libsvn_find_parent_branch { unlink $GIT_SVN_INDEX; print STDERR "Found branch parent: ($GIT_SVN) $parent\n"; sys(qw/git-read-tree/, $parent); - # I can't seem to get do_switch() to work correctly with - # the SWIG interface (TypeError when passing switch_url...), - # so we'll unconditionally bypass the delta interface here - # for now - return libsvn_fetch_full($parent, $paths, $rev, - $author, $date, $msg); + unless (libsvn_can_do_switch()) { + return libsvn_fetch_full($parent, $paths, $rev, + $author, $date, $msg); + } + # do_switch works with svn/trunk >= r22312, but that is not + # included with SVN 1.4.2 (the latest version at the moment), + # so we can't rely on it. + my $ra = libsvn_connect("$url/$branch_from"); + my $ed = SVN::Git::Fetcher->new({c => $parent, q => $_q}); + my $pool = SVN::Pool->new; + my $reporter = $ra->do_switch($rev, '', 1, $SVN->{url}, + $ed, $pool); + my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : (); + $reporter->set_path('', $r0, 0, @lock, $pool); + $reporter->finish_report($pool); + $pool->clear; + unless ($ed->{git_commit_ok}) { + die "SVN connection failed somewhere...\n"; + } + return libsvn_log_entry($rev, $author, $date, $msg, [$parent]); } print STDERR "Nope, branch point not imported or unknown\n"; return undef; -- cgit v0.10.2-6-g49f6 From 2cdf87ebd9976d98d544669d94b111fea731d2ba Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 8 Dec 2006 14:07:45 -0800 Subject: Fix perl/ build. An earlier commit f848718a broke the build in perl/ directory by allowing the Makefile.PL to overwrite the now-tracked Makefile. Fix this by forcing Makefile.PL to produce its output in perl.mak as the broken commit originally intended. Signed-off-by: Junio C Hamano diff --git a/perl/Makefile b/perl/Makefile index bd483b0..099beda 100644 --- a/perl/Makefile +++ b/perl/Makefile @@ -29,7 +29,7 @@ $(makfile): ../GIT-CFLAGS Makefile echo ' echo $(instdir_SQ)' >> $@ else $(makfile): Makefile.PL ../GIT-CFLAGS - '$(PERL_PATH_SQ)' $< FIRST_MAKEFILE='$@' PREFIX='$(prefix_SQ)' + '$(PERL_PATH_SQ)' $< PREFIX='$(prefix_SQ)' endif # this is just added comfort for calling make directly in perl dir diff --git a/perl/Makefile.PL b/perl/Makefile.PL index de73235..4168775 100644 --- a/perl/Makefile.PL +++ b/perl/Makefile.PL @@ -24,5 +24,6 @@ WriteMakefile( NAME => 'Git', VERSION_FROM => 'Git.pm', PM => \%pm, + MAKEFILE => 'perl.mak', %extra ); -- cgit v0.10.2-6-g49f6 From 62b339a544b1fa5199de7571c460d770cb286e65 Mon Sep 17 00:00:00 2001 From: Josef Weidendorfer Date: Sat, 9 Dec 2006 02:28:26 +0100 Subject: Add branch.*.merge warning and documentation update This patch clarifies the meaning of the branch.*.merge option. Previously, if branch.*.merge was specified but did not match any ref, the message "No changes." was not really helpful regarding the misconfiguration. This patch adds a warning for this. Signed-off-by: Josef Weidendorfer Signed-off-by: Junio C Hamano diff --git a/Documentation/config.txt b/Documentation/config.txt index 9090762..21ec557 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -125,10 +125,17 @@ apply.whitespace:: branch..remote:: When in branch , it tells `git fetch` which remote to fetch. + If this option is not given, `git fetch` defaults to remote "origin". branch..merge:: - When in branch , it tells `git fetch` the default remote branch - to be merged. + When in branch , it tells `git fetch` the default refspec to + be marked for merging in FETCH_HEAD. The value has exactly to match + a remote part of one of the refspecs which are fetched from the remote + given by "branch..remote". + The merge information is used by `git pull` (which at first calls + `git fetch`) to lookup the default branch for merging. Without + this option, `git pull` defaults to merge the first refspec fetched. + Specify multiple values to get an octopus merge. pager.color:: A boolean to enable/disable colored output when the pager is in diff --git a/git-parse-remote.sh b/git-parse-remote.sh index da064a5..6ae534b 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -134,6 +134,8 @@ canon_refs_list_for_fetch () { # or the first one otherwise; add prefix . to the rest # to prevent the secondary branches to be merged by default. merge_branches= + found_mergeref= + curr_branch= if test "$1" = "-d" then shift ; remote="$1" ; shift @@ -171,6 +173,10 @@ canon_refs_list_for_fetch () { dot_prefix= && break done fi + if test -z $dot_prefix + then + found_mergeref=true + fi case "$remote" in '') remote=HEAD ;; refs/heads/* | refs/tags/* | refs/remotes/*) ;; @@ -191,6 +197,11 @@ canon_refs_list_for_fetch () { fi echo "${dot_prefix}${force}${remote}:${local}" done + if test -z "$found_mergeref" -a "$curr_branch" + then + echo >&2 "Warning: No merge candidate found because value of config option + \"branch.${curr_branch}.merge\" does not match any remote branch fetched." + fi } # Returns list of src: (no store), or src:dst (store) -- cgit v0.10.2-6-g49f6 From 90ffefe564cd849f88b1d1b5817eb25e3d57521b Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 8 Dec 2006 23:04:21 -0500 Subject: shortlog: fix segfault on empty authorname The old code looked backwards from the email address to parse the name, allowing an arbitrary number of spaces between the two. However, in the case of no name, we looked back too far to the 'author' (or 'Author:') header. Instead, remove at most one space between name and address. The bug was triggered by commit febf7ea4bed from linux-2.6. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano diff --git a/builtin-shortlog.c b/builtin-shortlog.c index f1124e2..7a2ddfe 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -188,7 +188,7 @@ static void read_from_stdin(struct path_list *list) bob = buffer + strlen(buffer); else { offset = 8; - while (isspace(bob[-1])) + if (isspace(bob[-1])) bob--; } @@ -236,7 +236,7 @@ static void get_from_rev(struct rev_info *rev, struct path_list *list) author = scratch; authorlen = strlen(scratch); } else { - while (bracket[-1] == ' ') + if (bracket[-1] == ' ') bracket--; author = buffer + 7; -- cgit v0.10.2-6-g49f6 From 4cfeccc75d6ab1ccc433770bac6bf3b15ab486d6 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 8 Dec 2006 22:58:50 -0500 Subject: Documentation: simpler shared repository creation Take Johannes Schindelin's suggestions for a further simplification of the shared repository creation using git --bare init-db --shared, and for a simplified cvsimport using an existing CVS working directory. Also insert more man page references. Signed-off-by: J. Bruce Fields cvs-migration.txt | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) Signed-off-by: Junio C Hamano diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt index 47846bd..b657f45 100644 --- a/Documentation/cvs-migration.txt +++ b/Documentation/cvs-migration.txt @@ -43,8 +43,8 @@ Pull: refs/heads/master:refs/remotes/origin/master ------------ ================================ -You can update the shared repository with your changes by first commiting -your changes, and then using: +You can update the shared repository with your changes by first committing +your changes, and then using the gitlink:git-push[1] command: ------------------------------------------------ $ git push origin master @@ -76,11 +76,15 @@ possibly created from scratch or from a tarball (see the link:tutorial.html[tutorial]), or imported from an already existing CVS repository (see the next section). -If your project's working directory is /home/alice/myproject, you can -create a shared repository at /pub/repo.git with: +Assume your existing repo is at /home/alice/myproject. Create a new "bare" +repository (a repository without a working tree) and fetch your project into +it: ------------------------------------------------ -$ git clone -bare /home/alice/myproject /pub/repo.git +$ mkdir /pub/my-repo.git +$ cd /pub/my-repo.git +$ git --bare init-db --shared +$ git --bare fetch /home/alice/myproject master:master ------------------------------------------------ Next, give every team member read/write access to this repository. One @@ -93,10 +97,7 @@ Put all the committers in the same group, and make the repository writable by that group: ------------------------------------------------ -$ cd /pub -$ chgrp -R $group repo.git -$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s -$ GIT_DIR=repo.git git repo-config core.sharedrepository true +$ chgrp -R $group /pub/my-repo.git ------------------------------------------------ Make sure committers have a umask of at most 027, so that the directories @@ -107,15 +108,15 @@ Importing a CVS archive First, install version 2.1 or higher of cvsps from link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make -sure it is in your path. The magic command line is then +sure it is in your path. Then cd to a checked out CVS working directory +of the project you are interested in and run gitlink:git-cvsimport[1]: ------------------------------------------- -$ git cvsimport -v -d -C +$ git cvsimport -C ------------------------------------------- This puts a git archive of the named CVS module in the directory -, which will be created if necessary. The -v option makes -the conversion script very chatty. +, which will be created if necessary. The import checks out from CVS every revision of every file. Reportedly cvsimport can average some twenty revisions per second, so for a -- cgit v0.10.2-6-g49f6 From d44c92d6ab4ded7a1960bb0b4a1da0c2fc102b89 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Sun, 10 Dec 2006 23:39:32 -0800 Subject: no need to install manpages as executable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to install manpages as executable. Noticed by Ville Skytt,Ad(B. Signed-off-by: Chris Wright Signed-off-by: Junio C Hamano diff --git a/Documentation/Makefile b/Documentation/Makefile index c00f5f6..d68bc4a 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -56,8 +56,8 @@ man7: $(DOC_MAN7) install: man $(INSTALL) -d -m755 $(DESTDIR)$(man1dir) $(DESTDIR)$(man7dir) - $(INSTALL) $(DOC_MAN1) $(DESTDIR)$(man1dir) - $(INSTALL) $(DOC_MAN7) $(DESTDIR)$(man7dir) + $(INSTALL) -m644 $(DOC_MAN1) $(DESTDIR)$(man1dir) + $(INSTALL) -m644 $(DOC_MAN7) $(DESTDIR)$(man7dir) # -- cgit v0.10.2-6-g49f6 From 554a2636f7c5125a83bb07194632445467d46c83 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 11 Dec 2006 19:06:34 +0100 Subject: Don't use memcpy when source and dest. buffers may overlap git-index-pack can call memcpy with overlapping source and destination buffers. The patch below makes it use memmove instead. If you want to demonstrate a failure, add the following two lines + if (input_offset < input_len) + abort (); before the existing memcpy call (shown in the patch below), and then run this: (cd t; sh ./t5500-fetch-pack.sh) Signed-off-by: Jim Meyering Signed-off-by: Junio C Hamano diff --git a/index-pack.c b/index-pack.c index 8331d99..6d6c92b 100644 --- a/index-pack.c +++ b/index-pack.c @@ -96,7 +96,7 @@ static void flush(void) if (output_fd >= 0) write_or_die(output_fd, input_buffer, input_offset); SHA1_Update(&input_ctx, input_buffer, input_offset); - memcpy(input_buffer, input_buffer + input_offset, input_len); + memmove(input_buffer, input_buffer + input_offset, input_len); input_offset = 0; } } -- cgit v0.10.2-6-g49f6 From 9abd46a3471c2d58976e06a00e937b03672b98bc Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 7 Dec 2006 05:17:07 -0500 Subject: Make sure the empty tree exists when needed in merge-recursive. There are some baseless merge cases where git-merge-recursive will try to compare one of the branches against the empty tree. However most projects won't have the empty tree object in their object database as Git does not normally create empty tree objects. If the empty tree object is missing then the merge process will die, as it cannot load the object from the database. The error message may make the user think that their database is corrupt when its actually not. So instead we should just create the empty tree object whenever it is needed. If the object already exists as a loose object then no harm done. Otherwise that loose object will be pruned away later by either git-prune or git-prune-packed. Thanks goes to Junio for suggesting this fix. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano diff --git a/merge-recursive.c b/merge-recursive.c index cd2cc77..32e186c 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1238,7 +1238,7 @@ static int merge(struct commit *h1, tree->object.parsed = 1; tree->object.type = OBJ_TREE; - hash_sha1_file(NULL, 0, tree_type, tree->object.sha1); + write_sha1_file(NULL, 0, tree_type, tree->object.sha1); merged_common_ancestors = make_virtual_commit(tree, "ancestor"); } -- cgit v0.10.2-6-g49f6 From bca73251da5cc3e4bea71e28e0096a5cd662bbd9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 10 Dec 2006 15:55:07 -0800 Subject: shortlog: remove "[PATCH]" prefix from shortlog output Originally noticed by Nicolas Pitre; the real cause was the code was prepared to deal with [PATCH] (and [PATCH n/m whatever]) prefixes but forgot that the string can be indented while acting as a filter. Signed-off-by: Junio C Hamano diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 7a2ddfe..3322c3a 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -195,11 +195,17 @@ static void read_from_stdin(struct path_list *list) while (fgets(buffer2, sizeof(buffer2), stdin) && buffer2[0] != '\n') ; /* chomp input */ - if (fgets(buffer2, sizeof(buffer2), stdin)) + if (fgets(buffer2, sizeof(buffer2), stdin)) { + int l2 = strlen(buffer2); + int i; + for (i = 0; i < l2; i++) + if (!isspace(buffer2[i])) + break; insert_author_oneline(list, buffer + offset, bob - buffer - offset, - buffer2, strlen(buffer2)); + buffer2 + i, l2 - i); + } } } } -- cgit v0.10.2-6-g49f6 From 6f9872582246b9b8ee4bdc9f6a563b409aab1ecb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 10 Dec 2006 15:51:54 -0800 Subject: shortlog: fix segfault on empty authorname The old code looked backwards from the email address to parse the name, allowing an arbitrary number of spaces between the two. However, in the case of no name, we looked back too far to the 'author' (or 'Author:') header. The bug was triggered by commit febf7ea4bed from linux-2.6. Jeff King originally fixed it by looking back only one character; Johannes Schindelin pointed out that we could try harder while at it to cope with commits with broken headers. Signed-off-by: Junio C Hamano diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 3322c3a..3fc43dd 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -188,7 +188,8 @@ static void read_from_stdin(struct path_list *list) bob = buffer + strlen(buffer); else { offset = 8; - if (isspace(bob[-1])) + while (buffer + offset < bob && + isspace(bob[-1])) bob--; } -- cgit v0.10.2-6-g49f6 From 59f867400650b39568e4a7f96bd60f3a0072dbda Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Tue, 12 Dec 2006 12:01:47 -0500 Subject: Move Fink and Ports check to after config file Putting NO_FINK or NO_DARWIN_PORTS in config.mak is ignored because the checks are done before the config is included. Signed-off-by: Brian Gernhardt Signed-off-by: Junio C Hamano diff --git a/Makefile b/Makefile index 36ce8cd..c5a1804 100644 --- a/Makefile +++ b/Makefile @@ -334,18 +334,6 @@ ifeq ($(uname_S),Darwin) NEEDS_SSL_WITH_CRYPTO = YesPlease NEEDS_LIBICONV = YesPlease NO_STRLCPY = YesPlease - ifndef NO_FINK - ifeq ($(shell test -d /sw/lib && echo y),y) - BASIC_CFLAGS += -I/sw/include - BASIC_LDFLAGS += -L/sw/lib - endif - endif - ifndef NO_DARWIN_PORTS - ifeq ($(shell test -d /opt/local/lib && echo y),y) - BASIC_CFLAGS += -I/opt/local/include - BASIC_LDFLAGS += -L/opt/local/lib - endif - endif endif ifeq ($(uname_S),SunOS) NEEDS_SOCKET = YesPlease @@ -423,6 +411,21 @@ endif -include config.mak.autogen -include config.mak +ifeq ($(uname_S),Darwin) + ifndef NO_FINK + ifeq ($(shell test -d /sw/lib && echo y),y) + BASIC_CFLAGS += -I/sw/include + BASIC_LDFLAGS += -L/sw/lib + endif + endif + ifndef NO_DARWIN_PORTS + ifeq ($(shell test -d /opt/local/lib && echo y),y) + BASIC_CFLAGS += -I/opt/local/include + BASIC_LDFLAGS += -L/opt/local/lib + endif + endif +endif + ifdef WITH_OWN_SUBPROCESS_PY PYMODULES += compat/subprocess.py else -- cgit v0.10.2-6-g49f6 From 0d7a6e4ef9e2dc458a9a56ab73638d97f4e75d87 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Tue, 12 Dec 2006 18:34:02 +0100 Subject: Clarify fetch error for missing objects. Otherwise there're such things like: Cannot obtain needed none 9a6e87b60dbd2305c95cecce7d9d60f849a0658d while processing commit 0000000000000000000000000000000000000000. which while looks weird. What is the none needed for? Signed-off-by: Junio C Hamano diff --git a/fetch.c b/fetch.c index c426c04..663b4b2 100644 --- a/fetch.c +++ b/fetch.c @@ -22,14 +22,15 @@ void pull_say(const char *fmt, const char *hex) fprintf(stderr, fmt, hex); } -static void report_missing(const char *what, const unsigned char *missing) +static void report_missing(const struct object *obj) { char missing_hex[41]; - - strcpy(missing_hex, sha1_to_hex(missing));; - fprintf(stderr, - "Cannot obtain needed %s %s\nwhile processing commit %s.\n", - what, missing_hex, sha1_to_hex(current_commit_sha1)); + strcpy(missing_hex, sha1_to_hex(obj->sha1));; + fprintf(stderr, "Cannot obtain needed %s %s\n", + obj->type ? typename(obj->type): "object", missing_hex); + if (!is_null_sha1(current_commit_sha1)) + fprintf(stderr, "while processing commit %s.\n", + sha1_to_hex(current_commit_sha1)); } static int process(struct object *obj); @@ -177,7 +178,7 @@ static int loop(void) */ if (! (obj->flags & TO_SCAN)) { if (fetch(obj->sha1)) { - report_missing(typename(obj->type), obj->sha1); + report_missing(obj); return -1; } } -- cgit v0.10.2-6-g49f6 From d2a9a87b8a98e3b3797c6c1e5aa2269f36c2b47a Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 12 Dec 2006 14:47:00 -0800 Subject: git-svn: enable logging of information not supported by git The changes are now tracked in $GIT_DIR/svn/$GIT_SVN_ID/untracked.log Information in the untracked.log include: * the addition and removal of empty directories (changes of these will also warn the user) * file and directory property changes, including (but not limited to) svk:merge and svn:externals * revision properties (revprops) are also tracked * users will be warned of 'absent' file and directories (if users are forbidden access) Fields in entries are separated by spaces; "unsafe" characters are URI-encoded so that each entry takes exactly one line. There is currently no automated parser for dealing with the data in untracked.log, but it should be possible to write one to create empty directories on checkout and manage externals/subprojects. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano diff --git a/git-svn.perl b/git-svn.perl index 1f8a3b0..06e89ff 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -21,6 +21,16 @@ $ENV{TZ} = 'UTC'; $ENV{LC_ALL} = 'C'; $| = 1; # unbuffer STDOUT +# properties that we do not log: +my %SKIP = ( 'svn:wc:ra_dav:version-url' => 1, + 'svn:special' => 1, + 'svn:executable' => 1, + 'svn:entry:committed-rev' => 1, + 'svn:entry:last-author' => 1, + 'svn:entry:uuid' => 1, + 'svn:entry:committed-date' => 1, +); + sub fatal (@) { print STDERR $@; exit 1 } # If SVN:: library support is added, please make the dependencies # optional and preserve the capability to use the command-line client. @@ -2902,7 +2912,7 @@ sub libsvn_dup_ra { } sub libsvn_get_file { - my ($gui, $f, $rev, $chg) = @_; + my ($gui, $f, $rev, $chg, $untracked) = @_; $f =~ s#^/##; print "\t$chg\t$f\n" unless $_q; @@ -2940,11 +2950,25 @@ sub libsvn_get_file { waitpid $pid, 0; $hash =~ /^$sha1$/o or die "not a sha1: $hash\n"; } + %{$untracked->{file_prop}->{$f}} = %$props; print $gui $mode,' ',$hash,"\t",$f,"\0" or croak $!; } +sub uri_encode { + my ($f) = @_; + $f =~ s#([^a-zA-Z0-9\*!\:_\./\-])#uc sprintf("%%%02x",ord($1))#eg; + $f +} + +sub uri_decode { + my ($f) = @_; + $f =~ tr/+/ /; + $f =~ s/%([A-F0-9]{2})/chr hex($1)/ge; + $f +} + sub libsvn_log_entry { - my ($rev, $author, $date, $msg, $parents) = @_; + my ($rev, $author, $date, $msg, $parents, $untracked) = @_; my ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\d{4})\-(\d\d)\-(\d\d)T (\d\d)\:(\d\d)\:(\d\d).\d+Z$/x) or die "Unable to parse date: $date\n"; @@ -2952,8 +2976,65 @@ sub libsvn_log_entry { die "Author: $author not defined in $_authors file\n"; } $msg = '' if ($rev == 0 && !defined $msg); - return { revision => $rev, date => "+0000 $Y-$m-$d $H:$M:$S", - author => $author, msg => $msg."\n", parents => $parents || [] } + + open my $un, '>>', "$GIT_SVN_DIR/unhandled.log" or croak $!; + my $h; + print $un "r$rev\n" or croak $!; + $h = $untracked->{empty}; + foreach (sort keys %$h) { + my $act = $h->{$_} ? '+empty_dir' : '-empty_dir'; + print $un " $act: ", uri_encode($_), "\n" or croak $!; + warn "W: $act: $_\n"; + } + foreach my $t (qw/dir_prop file_prop/) { + $h = $untracked->{$t} or next; + foreach my $path (sort keys %$h) { + my $ppath = $path eq '' ? '.' : $path; + foreach my $prop (sort keys %{$h->{$path}}) { + next if $SKIP{$prop}; + my $v = $h->{$path}->{$prop}; + if (defined $v) { + print $un " +$t: ", + uri_encode($ppath), ' ', + uri_encode($prop), ' ', + uri_encode($v), "\n" + or croak $!; + } else { + print $un " -$t: ", + uri_encode($ppath), ' ', + uri_encode($prop), "\n" + or croak $!; + } + } + } + } + foreach my $t (qw/absent_file absent_directory/) { + $h = $untracked->{$t} or next; + foreach my $parent (sort keys %$h) { + foreach my $path (sort @{$h->{$parent}}) { + print $un " $t: ", + uri_encode("$parent/$path"), "\n" + or croak $!; + warn "W: $t: $parent/$path ", + "Insufficient permissions?\n"; + } + } + } + + # revprops (make this optional? it's an extra network trip...) + my $pool = SVN::Pool->new; + my $rp = $SVN->rev_proplist($rev, $pool); + foreach (sort keys %$rp) { + next if /^svn:(?:author|date|log)$/; + print $un " rev_prop: ", uri_encode($_), ' ', + uri_encode($rp->{$_}), "\n"; + } + $pool->clear; + close $un or croak $!; + + { revision => $rev, date => "+0000 $Y-$m-$d $H:$M:$S", + author => $author, msg => $msg."\n", parents => $parents || [], + revprops => $rp } } sub process_rm { @@ -2972,9 +3053,11 @@ sub process_rm { } print "\tD\t$f/\n" unless $q; close $ls or croak $?; + return $SVN::Node::dir; } else { print $gui '0 ',0 x 40,"\t",$f,"\0" or croak $!; print "\tD\t$f\n" unless $q; + return $SVN::Node::file; } } @@ -2995,13 +3078,14 @@ sub libsvn_fetch_delta { unless ($ed->{git_commit_ok}) { die "SVN connection failed somewhere...\n"; } - libsvn_log_entry($rev, $author, $date, $msg, [$last_commit]); + libsvn_log_entry($rev, $author, $date, $msg, [$last_commit], $ed); } sub libsvn_fetch_full { my ($last_commit, $paths, $rev, $author, $date, $msg) = @_; open my $gui, '| git-update-index -z --index-info' or croak $!; my %amr; + my $ut = { empty => {}, dir_prop => {}, file_prop => {} }; my $p = $SVN->{svn_path}; foreach my $f (keys %$paths) { my $m = $paths->{$f}->action(); @@ -3012,8 +3096,11 @@ sub libsvn_fetch_full { $f =~ s#^/##; } if ($m =~ /^[DR]$/) { - process_rm($gui, $last_commit, $f, $_q); - next if $m eq 'D'; + my $t = process_rm($gui, $last_commit, $f, $_q); + if ($m eq 'D') { + $ut->{empty}->{$f} = 0 if $t == $SVN::Node::dir; + next; + } # 'R' can be file replacements, too, right? } my $pool = SVN::Pool->new; @@ -3026,18 +3113,32 @@ sub libsvn_fetch_full { } } elsif ($t == $SVN::Node::dir && $m =~ /^[AR]$/) { my @traversed = (); - libsvn_traverse($gui, '', $f, $rev, \@traversed); - foreach (@traversed) { - $amr{$_} = $m; + libsvn_traverse($gui, '', $f, $rev, \@traversed, $ut); + if (@traversed) { + foreach (@traversed) { + $amr{$_} = $m; + } + } else { + my ($dir, $file) = ($f =~ m#^(.*?)/?([^/]+)$#); + delete $ut->{empty}->{$dir}; + $ut->{empty}->{$f} = 1; } } $pool->clear; } foreach (keys %amr) { - libsvn_get_file($gui, $_, $rev, $amr{$_}); + libsvn_get_file($gui, $_, $rev, $amr{$_}, $ut); + my ($d) = ($_ =~ m#^(.*?)/?(?:[^/]+)$#); + delete $ut->{empty}->{$d}; + } + unless (exists $ut->{dir_prop}->{''}) { + my $pool = SVN::Pool->new; + my (undef, undef, $props) = $SVN->get_dir('', $rev, $pool); + %{$ut->{dir_prop}->{''}} = %$props; + $pool->clear; } close $gui or croak $?; - return libsvn_log_entry($rev, $author, $date, $msg, [$last_commit]); + libsvn_log_entry($rev, $author, $date, $msg, [$last_commit], $ut); } sub svn_grab_base_rev { @@ -3098,25 +3199,38 @@ sub libsvn_parse_revision { } sub libsvn_traverse { - my ($gui, $pfx, $path, $rev, $files) = @_; + my ($gui, $pfx, $path, $rev, $files, $untracked) = @_; my $cwd = length $pfx ? "$pfx/$path" : $path; my $pool = SVN::Pool->new; $cwd =~ s#^\Q$SVN->{svn_path}\E##; + my $nr = 0; my ($dirent, $r, $props) = $SVN->get_dir($cwd, $rev, $pool); + %{$untracked->{dir_prop}->{$cwd}} = %$props; foreach my $d (keys %$dirent) { my $t = $dirent->{$d}->kind; if ($t == $SVN::Node::dir) { - libsvn_traverse($gui, $cwd, $d, $rev, $files); + my $i = libsvn_traverse($gui, $cwd, $d, $rev, + $files, $untracked); + if ($i) { + $nr += $i; + } else { + $untracked->{empty}->{"$cwd/$d"} = 1; + } } elsif ($t == $SVN::Node::file) { + $nr++; my $file = "$cwd/$d"; if (defined $files) { push @$files, $file; } else { - libsvn_get_file($gui, $file, $rev, 'A'); + libsvn_get_file($gui, $file, $rev, 'A', + $untracked); + my ($dir) = ($file =~ m#^(.*?)/?(?:[^/]+)$#); + delete $untracked->{empty}->{$dir}; } } } $pool->clear; + $nr; } sub libsvn_traverse_ignore { @@ -3255,6 +3369,7 @@ sub libsvn_new_tree { return $log_entry; } my ($paths, $rev, $author, $date, $msg) = @_; + my $ut; if ($_xfer_delta) { my $pool = SVN::Pool->new; my $ed = SVN::Git::Fetcher->new({q => $_q}); @@ -3266,12 +3381,14 @@ sub libsvn_new_tree { unless ($ed->{git_commit_ok}) { die "SVN connection failed somewhere...\n"; } + $ut = $ed; } else { + $ut = { empty => {}, dir_prop => {}, file_prop => {} }; open my $gui, '| git-update-index -z --index-info' or croak $!; - libsvn_traverse($gui, '', $SVN->{svn_path}, $rev); + libsvn_traverse($gui, '', $SVN->{svn_path}, $rev, undef, $ut); close $gui or croak $?; } - return libsvn_log_entry($rev, $author, $date, $msg); + libsvn_log_entry($rev, $author, $date, $msg, [], $ut); } sub find_graft_path_commit { @@ -3456,13 +3573,28 @@ sub new { $self->{gui} = $gui; $self->{c} = $git_svn->{c} if exists $git_svn->{c}; $self->{q} = $git_svn->{q}; + $self->{empty} = {}; + $self->{dir_prop} = {}; + $self->{file_prop} = {}; + $self->{absent_dir} = {}; + $self->{absent_file} = {}; require Digest::MD5; $self; } +sub open_root { + { path => '' }; +} + +sub open_directory { + my ($self, $path, $pb, $rev) = @_; + { path => $path }; +} + sub delete_entry { my ($self, $path, $rev, $pb) = @_; - process_rm($self->{gui}, $self->{c}, $path, $self->{q}); + my $t = process_rm($self->{gui}, $self->{c}, $path, $self->{q}); + $self->{empty}->{$path} = 0 if $t == $SVN::Node::dir; undef; } @@ -3479,10 +3611,41 @@ sub open_file { sub add_file { my ($self, $path, $pb, $cp_path, $cp_rev) = @_; + my ($dir, $file) = ($path =~ m#^(.*?)/?([^/]+)$#); + delete $self->{empty}->{$dir}; { path => $path, mode_a => 100644, mode_b => 100644, pool => SVN::Pool->new, action => 'A' }; } +sub add_directory { + my ($self, $path, $cp_path, $cp_rev) = @_; + my ($dir, $file) = ($path =~ m#^(.*?)/?([^/]+)$#); + delete $self->{empty}->{$dir}; + $self->{empty}->{$path} = 1; + { path => $path }; +} + +sub change_dir_prop { + my ($self, $db, $prop, $value) = @_; + $self->{dir_prop}->{$db->{path}} ||= {}; + $self->{dir_prop}->{$db->{path}}->{$prop} = $value; + undef; +} + +sub absent_directory { + my ($self, $path, $pb) = @_; + $self->{absent_dir}->{$pb->{path}} ||= []; + push @{$self->{absent_dir}->{$pb->{path}}}, $path; + undef; +} + +sub absent_file { + my ($self, $path, $pb) = @_; + $self->{absent_file}->{$pb->{path}} ||= []; + push @{$self->{absent_file}->{$pb->{path}}}, $path; + undef; +} + sub change_file_prop { my ($self, $fb, $prop, $value) = @_; if ($prop eq 'svn:executable') { @@ -3491,6 +3654,9 @@ sub change_file_prop { } } elsif ($prop eq 'svn:special') { $fb->{mode_b} = defined $value ? 120000 : 100644; + } else { + $self->{file_prop}->{$fb->{path}} ||= {}; + $self->{file_prop}->{$fb->{path}}->{$prop} = $value; } undef; } -- cgit v0.10.2-6-g49f6 From dd31da2fdc199132c9fd42023aea5b33672d73cc Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 12 Dec 2006 14:47:01 -0800 Subject: git-svn: allow dcommit to take an alternate head Previously dcommit would unconditionally commit all patches up-to and including the current HEAD. Now if an optional command-line argument is specified, it will only commit up to the specified revision. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index a45067e..c589a98 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -57,11 +57,13 @@ See '<>' if you are interested in manually joining branches on commit. 'dcommit':: - Commit all diffs from the current HEAD directly to the SVN + Commit all diffs from a specified head directly to the SVN repository, and then rebase or reset (depending on whether or - not there is a diff between SVN and HEAD). It is recommended + not there is a diff between SVN and head). It is recommended that you run git-svn fetch and rebase (not pull) your commits against the latest changes in the SVN repository. + An optional command-line argument may be specified as an + alternative to HEAD. This is advantageous over 'commit' (below) because it produces cleaner, more linear history. diff --git a/git-svn.perl b/git-svn.perl index 06e89ff..819584b 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -604,8 +604,9 @@ sub commit_lib { } sub dcommit { + my $head = shift || 'HEAD'; my $gs = "refs/remotes/$GIT_SVN"; - chomp(my @refs = safe_qx(qw/git-rev-list --no-merges/, "$gs..HEAD")); + chomp(my @refs = safe_qx(qw/git-rev-list --no-merges/, "$gs..$head")); my $last_rev; foreach my $d (reverse @refs) { if (quiet_run('git-rev-parse','--verify',"$d~1") != 0) { @@ -632,16 +633,16 @@ sub dcommit { } return if $_dry_run; fetch(); - my @diff = safe_qx(qw/git-diff-tree HEAD/, $gs); + my @diff = safe_qx('git-diff-tree', $head, $gs); my @finish; if (@diff) { @finish = qw/rebase/; push @finish, qw/--merge/ if $_merge; push @finish, "--strategy=$_strategy" if $_strategy; - print STDERR "W: HEAD and $gs differ, using @finish:\n", @diff; + print STDERR "W: $head and $gs differ, using @finish:\n", @diff; } else { - print "No changes between current HEAD and $gs\n", - "Hard resetting to the latest $gs\n"; + print "No changes between current $head and $gs\n", + "Resetting to the latest $gs\n"; @finish = qw/reset --mixed/; } sys('git', @finish, $gs); -- cgit v0.10.2-6-g49f6 From 6fda05aebe6e36bfe87113f85b6e70f2b9b73e42 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 12 Dec 2006 14:47:02 -0800 Subject: git-svn: correctly display fatal() error messages If I wanted to print $@, I'd pass $@ to fatal(). This looks like a stupid typo on my part. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano diff --git a/git-svn.perl b/git-svn.perl index 819584b..c746a3c 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -31,7 +31,7 @@ my %SKIP = ( 'svn:wc:ra_dav:version-url' => 1, 'svn:entry:committed-date' => 1, ); -sub fatal (@) { print STDERR $@; exit 1 } +sub fatal (@) { print STDERR @_; exit 1 } # If SVN:: library support is added, please make the dependencies # optional and preserve the capability to use the command-line client. # use eval { require SVN::... } to make it lazy load -- cgit v0.10.2-6-g49f6 From c93be3b539da06e2d89d613448dfadf83c48de53 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 12 Dec 2006 16:36:16 -0800 Subject: add test case for recursive merge This test case is based on the bug report by Shawn Pearce. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh new file mode 100755 index 0000000..9416c27 --- /dev/null +++ b/t/t6024-recursive-merge.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +test_description='Test merge without common ancestors' +. ./test-lib.sh + +# This scenario is based on a real-world repository of Shawn Pearce. + +# 1 - A - D - F +# \ X / +# B X +# X \ +# 2 - C - E - G + +export GIT_COMMITTER_DATE="2006-12-12 23:28:00 +0100" +echo 1 > a1 +git add a1 +GIT_AUTHOR_DATE="2006-12-12 23:00:00" git commit -m 1 a1 + +git checkout -b A master +echo A > a1 +GIT_AUTHOR_DATE="2006-12-12 23:00:01" git commit -m A a1 + +git checkout -b B master +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 +echo D > a1 +git update-index a1 +GIT_AUTHOR_DATE="2006-12-12 23:00:03" git commit -m D + +git symbolic-ref HEAD refs/heads/other +echo 2 > a1 +GIT_AUTHOR_DATE="2006-12-12 23:00:04" git commit -m 2 a1 + +git checkout -b C +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 +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 +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 +echo F > a1 +git update-index a1 +GIT_AUTHOR_DATE="2006-12-12 23:00:08" git commit -m F + +test_expect_failure "combined merge conflicts" "git merge -m final G" + +git ls-files --stage > out +cat > expect << EOF +100644 f70f10e4db19068f79bc43844b49f3eece45c4e8 1 a1 +100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1 +100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1 +EOF + +test_expect_success "virtual trees were processed" "diff -u expect out" + +test_done -- cgit v0.10.2-6-g49f6 From c53d696bcc2894b0df277e617740b15bac794df9 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 12 Dec 2006 16:45:00 -0800 Subject: git-svn: correctly handle packed-refs in refs/remotes/ We now use git-rev-parse universally to read refs, instead of our own file_to_s function (which I plan on removing). Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano diff --git a/git-svn.perl b/git-svn.perl index c746a3c..15254e4 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -2027,9 +2027,17 @@ sub git_commit { # just in case we clobber the existing ref, we still want that ref # as our parent: - if (my $cur = eval { file_to_s("$GIT_DIR/refs/remotes/$GIT_SVN") }) { + open my $null, '>', '/dev/null' or croak $!; + open my $stderr, '>&', \*STDERR or croak $!; + open STDERR, '>&', $null or croak $!; + if (my $cur = eval { safe_qx('git-rev-parse', + "refs/remotes/$GIT_SVN^0") }) { + chomp $cur; push @tmp_parents, $cur; } + open STDERR, '>&', $stderr or croak $!; + close $stderr or croak $!; + close $null or croak $!; if (exists $tree_map{$tree}) { foreach my $p (@{$tree_map{$tree}}) { -- cgit v0.10.2-6-g49f6