From fd35e42683113e367eee0bb8ac956dde3d95edde Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Thu, 7 Aug 2008 02:06:30 +0200 Subject: [PATCH 01/73] Fail properly when cloning from invalid HTTP URL Currently, when cloning from invalid HTTP URL, git clone will possibly return curl error, then a confusing message about remote HEAD and then return success and leave an empty repository behind, confusing either the end-user or the automated service calling it (think repo.or.cz). This patch changes the error() calls in get_refs_via_curl() to die()s, akin to the other get_refs_*() functions. Cc: Daniel Barkalow Signed-off-by: Petr Baudis Signed-off-by: Junio C Hamano --- transport.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/transport.c b/transport.c index 6f549b336b..b3e3e61f9d 100644 --- a/transport.c +++ b/transport.c @@ -463,17 +463,14 @@ static struct ref *get_refs_via_curl(struct transport *transport) run_active_slot(slot); if (results.curl_result != CURLE_OK) { strbuf_release(&buffer); - if (missing_target(&results)) { - return NULL; - } else { - error("%s", curl_errorstr); - return NULL; - } + if (missing_target(&results)) + die("%s not found: did you run git update-server-info on the server?", refs_url); + else + die("%s download error - %s", refs_url, curl_errorstr); } } else { strbuf_release(&buffer); - error("Unable to start request"); - return NULL; + die("Unable to start HTTP request"); } data = buffer.buf; From 468386a956c09ff59dd2b8fd681e162b2e167392 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 8 Aug 2008 04:29:35 +0200 Subject: [PATCH 02/73] clone --mirror: avoid storing repeated tags With --mirror, clone asks for refs/* already, so it does not need to ask for ref/tags/*, too. Noticed by Cesar Eduardo Barros. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-clone.c | 3 ++- t/t5601-clone.sh | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/builtin-clone.c b/builtin-clone.c index 8612d59dd2..c0e3086437 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -330,7 +330,8 @@ static struct ref *write_remote_refs(const struct ref *refs, struct ref *r; get_fetch_map(refs, refspec, &tail, 0); - get_fetch_map(refs, tag_refspec, &tail, 0); + if (!option_mirror) + get_fetch_map(refs, tag_refspec, &tail, 0); for (r = local_refs; r; r = r->next) add_extra_ref(r->peer_ref->name, r->old_sha1, 0); diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index a13b6f9d3d..59c65fef28 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -95,4 +95,16 @@ test_expect_success 'clone --bare names the local repository .git' ' ' +test_expect_success 'clone --mirror does not repeat tags' ' + + (cd src && + git tag some-tag HEAD) && + git clone --mirror src mirror2 && + (cd mirror2 && + git show-ref 2> clone.err > clone.out) && + test_must_fail grep Duplicate mirror2/clone.err && + grep some-tag mirror2/clone.out + +' + test_done From 0f4f4d1597219bad74c4fde624321d8a05d1b55e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 7 Aug 2008 16:05:25 -0700 Subject: [PATCH 03/73] asciidoc markup fixes I see quite a few pages on k.org site, e.g. http://www.kernel.org/pub/software/scm/git/docs/git-rerere.html (scroll down to find "After this test merge") are misformatted to lose teletype text '+' that is followed by a comma, and turns the following paragraph all typeset in teletype. This patch seems to fix the issue at the site (meaning, with the particular vintage of asciidoc and docbook toolchain), without breaking things with the version I have at my primary development machine, but wider testing is very much appreciated. After this patch, git grep '`+`,' -- Documentation should report noting. Signed-off-by: Junio C Hamano --- Documentation/git-push.txt | 2 +- Documentation/git-rerere.txt | 6 +++--- Documentation/pull-fetch-param.txt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 82dd4433f2..60d53391d2 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -31,7 +31,7 @@ OPTIONS :: The canonical format of a parameter is - `+?:`; that is, an optional plus `+`, followed + `+?:`; that is, an optional plus `{plus}`, followed by the source ref, followed by a colon `:`, followed by the destination ref. + diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index 37828e5c5a..8f12dc9759 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -90,15 +90,15 @@ One way to do it is to pull master into the topic branch: The commits marked with `*` touch the same area in the same file; you need to resolve the conflicts when creating the commit -marked with `+`. Then you can test the result to make sure your +marked with `{plus}`. Then you can test the result to make sure your work-in-progress still works with what is in the latest master. After this test merge, there are two ways to continue your work on the topic. The easiest is to build on top of the test merge -commit `+`, and when your work in the topic branch is finally +commit `{plus}`, and when your work in the topic branch is finally ready, pull the topic branch into master, and/or ask the upstream to pull from you. By that time, however, the master or -the upstream might have been advanced since the test merge `+`, +the upstream might have been advanced since the test merge `{plus}`, in which case the final commit graph would look like this: ------------ diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt index cbee369947..f157738279 100644 --- a/Documentation/pull-fetch-param.txt +++ b/Documentation/pull-fetch-param.txt @@ -6,7 +6,7 @@ :: The canonical format of a parameter is - `+?:`; that is, an optional plus `+`, followed + `+?:`; that is, an optional plus `{plus}`, followed by the source ref, followed by a colon `:`, followed by the destination ref. + From b3bc97cba45e3b97243d31927fbf2343c21b6766 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Fri, 8 Aug 2008 09:52:55 +0200 Subject: [PATCH 04/73] Documentation: commit-tree: remove 16 parents restriction ef98c5ca lifted the 16 parents restriction in builtin-commit-tree.c, but forgot to update the documentation. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/git-commit-tree.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index feec58400b..92ab3ab4a8 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -16,12 +16,12 @@ This is usually not what an end user wants to run directly. See linkgit:git-commit[1] instead. Creates a new commit object based on the provided tree object and -emits the new commit object id on stdout. If no parent is given then -it is considered to be an initial tree. +emits the new commit object id on stdout. -A commit object usually has 1 parent (a commit after a change) or up -to 16 parents. More than one parent represents a merge of branches -that led to them. +A commit object may have any number of parents. With exactly one +parent, it is an ordinary commit. Having more than one parent makes +the commit a merge between several lines of history. Initial (root) +commits have no parents. While a tree represents a particular directory state of a working directory, a commit represents that state in "time", and explains how From ba24e7457aa1f958370bbb67dfb97e3ec806fd4a Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 7 Aug 2008 02:06:16 -0700 Subject: [PATCH 05/73] git-svn: add ability to specify --commit-url for dcommit This allows one to use public svn:// URLs for fetch and svn+ssh:// URLs for committing (without using the complicated rewriteRoot option, reimporting or git-filter-branch). Using this can also help avoid unnecessary server authentication/encryption overhead on busy SVN servers. Along with the new --revision option, this can also be allowed to override the branch detection in dcommit, too. This is potentially dangerous and not recommended! (And also purposely undocumented, but the loaded gun is there in case somebody wants to make it safe). Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- Documentation/git-svn.txt | 9 +++++++++ git-svn.perl | 9 ++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 773ae9654b..1e644ca6dc 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -138,6 +138,15 @@ and have no uncommitted changes. + --no-rebase;; After committing, do not rebase or reset. +--commit-url ;; + Commit to this SVN URL (the full path). This is intended to + allow existing git-svn repositories created with one transport + method (e.g. `svn://` or `http://` for anonymous read) to be + reused if a user is later given access to an alternate transport + method (e.g. `svn+ssh://` or `https://`) for commit. + + Using this option for any other purpose (don't ask) + is very strongly discouraged. -- 'log':: diff --git a/git-svn.perl b/git-svn.perl index df0ed9027d..06a82c80ce 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -66,7 +66,7 @@ my ($_stdin, $_help, $_edit, $_version, $_fetch_all, $_no_rebase, $_merge, $_strategy, $_dry_run, $_local, $_prefix, $_no_checkout, $_url, $_verbose, - $_git_format); + $_git_format, $_commit_url); $Git::SVN::_follow_parent = 1; my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username, 'config-dir=s' => \$Git::SVN::Ra::config_dir, @@ -127,6 +127,8 @@ my %cmd = ( 'verbose|v' => \$_verbose, 'dry-run|n' => \$_dry_run, 'fetch-all|all' => \$_fetch_all, + 'commit-url=s' => \$_commit_url, + 'revision|r=i' => \$_revision, 'no-rebase' => \$_no_rebase, %cmt_opts, %fc_opts } ], 'set-tree' => [ \&cmd_set_tree, @@ -416,6 +418,8 @@ sub cmd_dcommit { $head ||= 'HEAD'; my @refs; my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs); + $url = $_commit_url if defined $_commit_url; + my $last_rev = $_revision if defined $_revision; if ($url) { print "Committing to $url ...\n"; } @@ -423,7 +427,6 @@ sub cmd_dcommit { die "Unable to determine upstream SVN information from ", "$head history.\nPerhaps the repository is empty."; } - my $last_rev; my ($linear_refs, $parents) = linearize_history($gs, \@refs); if ($_no_rebase && scalar(@$linear_refs) > 1) { warn "Attempting to commit more than one change while ", @@ -446,7 +449,7 @@ sub cmd_dcommit { my $cmt_rev; my %ed_opts = ( r => $last_rev, log => get_commit_entry($d)->{log}, - ra => Git::SVN::Ra->new($gs->full_url), + ra => Git::SVN::Ra->new($url), config => SVN::Core::config_get_config( $Git::SVN::Ra::config_dir ), From 7be73ae94e6dac3d1c41268a13b02ff7203c0631 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Wed, 6 Aug 2008 16:22:00 -0500 Subject: [PATCH 06/73] Documentation: user-manual: "git commit -a" doesn't motivate .gitignore "git commit -a" ignores untracked files and follows all tracked files, regardless of whether they are listed in .gitignore. So don't use it to motivate gitignore. Signed-off-by: Jonathan Nieder Acked-by: J. Bruce Fields Signed-off-by: Junio C Hamano --- Documentation/user-manual.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 43f4e392fd..f421689942 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1128,8 +1128,8 @@ This typically includes files generated by a build process or temporary backup files made by your editor. Of course, 'not' tracking files with git is just a matter of 'not' calling "`git-add`" on them. But it quickly becomes annoying to have these untracked files lying around; e.g. they make -"`git add .`" and "`git commit -a`" practically useless, and they keep -showing up in the output of "`git status`". +"`git add .`" practically useless, and they keep showing up in the output of +"`git status`". You can tell git to ignore certain files by creating a file called .gitignore in the top level of your working directory, with contents such as: From c94c8e5ff63728a60494cbbcb28d5045584a997b Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Thu, 7 Aug 2008 14:03:42 -0500 Subject: [PATCH 07/73] Makefile: set SHELL to value of SHELL_PATH Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 52c67c1a47..61fc86d964 100644 --- a/Makefile +++ b/Makefile @@ -1060,6 +1060,8 @@ export TAR INSTALL DESTDIR SHELL_PATH ### Build rules +SHELL = $(SHELL_PATH) + all:: $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS ifneq (,$X) $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$p';) From b13d44093bac2eb75f37be01f0e369290211472c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 8 Aug 2008 13:31:27 -0700 Subject: [PATCH 08/73] GIT-VERSION-GEN: mark the version 'dirty' only if there are modified files We used to mark the version string with '-dirty' if the cache was not up to date, but the only thing we want to know is if the binaries are built from modified source. Refresh the cache to avoid false dirtyness. Christian Jaeger noticed this issue while building under fakeroot environment (without -u) that lies about the file ownership data. Signed-off-by: Junio C Hamano --- GIT-VERSION-GEN | 1 + 1 file changed, 1 insertion(+) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index cb7cd4b538..e1290d8901 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -16,6 +16,7 @@ elif test -d .git -o -f .git && case "$VN" in *$LF*) (exit 1) ;; v[0-9]*) + git update-index -q --refresh test -z "$(git diff-index --name-only HEAD --)" || VN="$VN-dirty" ;; esac From 5a7ebd4faab1430a6d4daef0636345709139e3b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Wed, 6 Aug 2008 17:45:23 +0200 Subject: [PATCH 09/73] bash: remove redundant check for 'git stash apply' options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will never trigger anyway because of the first check, and even if it would, it would not offer the command line option. Signed-off-by: SZEDER Gábor Acked-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 3396e35d76..78189c1b7b 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1439,7 +1439,7 @@ _git_stash () apply,--*) __gitcomp "--index" ;; - show,--*|apply,--*|drop,--*|pop,--*|branch,--*) + show,--*|drop,--*|pop,--*|branch,--*) COMPREPLY=() ;; show,*|apply,*|drop,*|pop,*|branch,*) From 6dc4627ef4eb40aeb9b328270b189ca27c061f7a Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Thu, 7 Aug 2008 14:06:26 -0500 Subject: [PATCH 10/73] Makefile: add a target which will abort compilation with ancient shells This adds a make target which can be used to try to execute certain shell constructs which are required for compiling and running git. This patch provides a test for the $() notation for command substition which is used in the Makefile and extensively in the git scripts. The make target is named in such a way as to be a hint to the user that SHELL_PATH should be set to an appropriate shell. If the shell command fails, the user should receive a message similar to the following: make: *** [please_set_SHELL_PATH_to_a_more_modern_shell] Error 2 Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 61fc86d964..90c5a131be 100644 --- a/Makefile +++ b/Makefile @@ -1062,7 +1062,7 @@ export TAR INSTALL DESTDIR SHELL_PATH SHELL = $(SHELL_PATH) -all:: $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS +all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS ifneq (,$X) $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$p';) endif @@ -1075,6 +1075,11 @@ endif $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) +please_set_SHELL_PATH_to_a_more_modern_shell: + @$$(:) + +shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell + strip: $(PROGRAMS) git$X $(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X @@ -1457,6 +1462,7 @@ endif $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS .PHONY: all install clean strip +.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: .FORCE-GIT-VERSION-FILE TAGS tags cscope .FORCE-GIT-CFLAGS .PHONY: .FORCE-GIT-BUILD-OPTIONS From 8afa42101d14f8944c1eb7f2e54d4f5300d2bb73 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Thu, 7 Aug 2008 16:16:03 +0200 Subject: [PATCH 11/73] Documentation: filter-branch: document how to filter all refs Document the '--' option that can be used to pass rev-list options (not just arguments), and give an example usage of '-- --all'. Remove reference to "the new branch name"; filter-branch takes arbitrary arguments to rev-list since dfd05e3. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/git-filter-branch.txt | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index a518ba6072..b0e710d5f9 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -13,7 +13,7 @@ SYNOPSIS [--msg-filter ] [--commit-filter ] [--tag-name-filter ] [--subdirectory-filter ] [--original ] [-d ] [-f | --force] - [...] + [--] [...] DESCRIPTION ----------- @@ -168,10 +168,10 @@ to other tags will be rewritten to point to the underlying commit. 'refs/original/', unless forced. ...:: - When options are given after the new branch name, they will - be passed to 'git-rev-list'. Only commits in the resulting - output will be filtered, although the filtered commits can still - reference parents which are outside of that set. + Arguments for 'git-rev-list'. All positive refs included by + these options are rewritten. You may also specify options + such as '--all', but you must use '--' to separate them from + the 'git-filter-branch' options. Examples @@ -196,6 +196,17 @@ git filter-branch --index-filter 'git rm --cached filename' HEAD Now, you will get the rewritten history saved in HEAD. +To rewrite the repository to look as if `foodir/` had been its project +root, and discard all other history: + +------------------------------------------------------- +git filter-branch --subdirectory-filter foodir -- --all +------------------------------------------------------- + +Thus you can, e.g., turn a library subdirectory into a repository of +its own. Note the `\--` that separates 'filter-branch' options from +revision options, and the `\--all` to rewrite all branches and tags. + To set a commit (which typically is at the tip of another history) to be the parent of the current initial commit, in order to paste the other history behind the current history: From 261044e85ddac3de48dc74dd9c416c95147022ad Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Fri, 8 Aug 2008 01:50:31 +0200 Subject: [PATCH 12/73] filter-branch: be more helpful when an annotated tag changes Previously, git-filter-branch failed if it attempted to update an annotated tag. Now we ignore this condition if --tag-name-filter is given, so that we can later rewrite the tag. If no such option was provided, we warn the user that he might want to run with "--tag-name-filter cat" to achieve the intended effect. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 182822a24e..a324cf0596 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -361,9 +361,17 @@ do ;; $_x40) echo "Ref '$ref' was rewritten" - git update-ref -m "filter-branch: rewrite" \ - "$ref" $rewritten $sha1 || - die "Could not rewrite $ref" + if ! git update-ref -m "filter-branch: rewrite" \ + "$ref" $rewritten $sha1 2>/dev/null; then + if test $(git cat-file -t "$ref") = tag; then + if test -z "$filter_tag_name"; then + warn "WARNING: You said to rewrite tagged commits, but not the corresponding tag." + warn "WARNING: Perhaps use '--tag-name-filter cat' to rewrite the tag." + fi + else + die "Could not rewrite $ref" + fi + fi ;; *) # NEEDSWORK: possibly add -Werror, making this an error From b47ddefe02945f8746c642219450245cf83ed130 Mon Sep 17 00:00:00 2001 From: Marcus Griep Date: Fri, 8 Aug 2008 01:41:56 -0700 Subject: [PATCH 13/73] Fix multi-glob assertion in git-svn Fixes bad regex match check for multiple globs (would always return one glob regardless of actual number). [ew: fixed a bashism in the test and some minor line-wrapping] Signed-off-by: Marcus Griep Acked-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 5 +++-- t/t9108-git-svn-glob.sh | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index 06a82c80ce..503a7c900a 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -4915,14 +4915,15 @@ sub new { my ($class, $glob) = @_; my $re = $glob; $re =~ s!/+$!!g; # no need for trailing slashes - my $nr = ($re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g); - my ($left, $right) = ($1, $2); + my $nr = $re =~ tr/*/*/; if ($nr > 1) { die "Only one '*' wildcard expansion ", "is supported (got $nr): '$glob'\n"; } elsif ($nr == 0) { die "One '*' is needed for glob: '$glob'\n"; } + $re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g; + my ($left, $right) = ($1, $2); $re = quotemeta($left) . $re . quotemeta($right); if (length $left && !($left =~ s!/+$!!g)) { die "Missing trailing '/' on left side of: '$glob' ($left)\n"; diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh index f6f71d0545..69e96878fe 100755 --- a/t/t9108-git-svn-glob.sh +++ b/t/t9108-git-svn-glob.sh @@ -16,7 +16,8 @@ test_expect_success 'test refspec globbing' ' echo "goodbye world" > trunk/src/b/readme && svn import -m "initial" trunk "$svnrepo"/trunk && svn co "$svnrepo" tmp && - cd tmp && + ( + cd tmp && mkdir branches tags && svn add branches tags && svn cp trunk branches/start && @@ -37,7 +38,7 @@ test_expect_success 'test refspec globbing' ' echo "byebye" >> tags/end/src/b/readme && poke tags/end/src/b/readme && svn commit -m "nothing to see here" - cd .. && + ) && git config --add svn-remote.svn.url "$svnrepo" && git config --add svn-remote.svn.fetch \ "trunk/src/a:refs/remotes/trunk" && @@ -48,7 +49,7 @@ test_expect_success 'test refspec globbing' ' git-svn multi-fetch && git log --pretty=oneline refs/remotes/tags/end | \ sed -e "s/^.\{41\}//" > output.end && - cmp expect.end output.end && + test_cmp expect.end output.end && test "`git rev-parse refs/remotes/tags/end~1`" = \ "`git rev-parse refs/remotes/branches/start`" && test "`git rev-parse refs/remotes/branches/start~2`" = \ @@ -66,11 +67,12 @@ test_expect_success 'test left-hand-side only globbing' ' "branches/*:refs/remotes/two/branches/*" && git config --add svn-remote.two.tags \ "tags/*:refs/remotes/two/tags/*" && - cd tmp && + ( + cd tmp && echo "try try" >> tags/end/src/b/readme && poke tags/end/src/b/readme && svn commit -m "try to try" - cd .. && + ) && git-svn fetch two && test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 && test `git rev-list refs/remotes/two/branches/start | wc -l` -eq 3 && @@ -80,7 +82,29 @@ test_expect_success 'test left-hand-side only globbing' ' `git rev-parse refs/remotes/two/branches/start` && git log --pretty=oneline refs/remotes/two/tags/end | \ sed -e "s/^.\{41\}//" > output.two && - cmp expect.two output.two + test_cmp expect.two output.two + ' + +echo "Only one '*' wildcard expansion is supported (got 2): 'branches/*/*'" \ + > expect.three +echo "" >> expect.three + +test_expect_success 'test disallow multi-globs' ' + git config --add svn-remote.three.url "$svnrepo" && + git config --add svn-remote.three.fetch \ + trunk:refs/remotes/three/trunk && + git config --add svn-remote.three.branches \ + "branches/*/*:refs/remotes/three/branches/*" && + git config --add svn-remote.three.tags \ + "tags/*/*:refs/remotes/three/tags/*" && + ( + cd tmp && + echo "try try" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "try to try" + ) && + test_must_fail git-svn fetch three 2> stderr.three && + test_cmp expect.three stderr.three ' test_done From 570d35c26dfbc40757da6032cdc96afb58cc0037 Mon Sep 17 00:00:00 2001 From: Marcus Griep Date: Fri, 8 Aug 2008 01:41:57 -0700 Subject: [PATCH 14/73] git-svn: Allow deep branch names by supporting multi-globs Some repositories use a deep branching strategy, such as: branches/1.0/1.0.rc1 branches/1.0/1.0.rc2 branches/1.0/1.0.rtm branches/1.0/1.0.gold Only allowing a single glob stiffles this. This change allows for a single glob 'set' to accept this deep branching strategy. The ref glob depth must match the branch glob depth. When using the -b or -t options for init or clone, this is automatically done. For example, using the above branches: svn-remote.svn.branches = branches/*/*:refs/remote/*/* gives the following branch names: 1.0/1.0.rc1 1.0/1.0.rc2 1.0/1.0.rtm 1.0/1.0.gold [ew: * removed unrelated line-wrapping changes * fixed line-wrapping in a few more places * removed trailing whitespace * fixed bashism in test * removed unnecessary httpd startup in test * changed copyright on tests to 2008 Marcus Griep * added executable permissions to new tests ] Signed-off-by: Marcus Griep Acked-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 60 +++++--- t/t9108-git-svn-glob.sh | 9 +- t/t9108-git-svn-multi-glob.sh | 160 +++++++++++++++++++++ t/t9125-git-svn-multi-glob-branch-names.sh | 37 +++++ 4 files changed, 246 insertions(+), 20 deletions(-) create mode 100755 t/t9108-git-svn-multi-glob.sh create mode 100755 t/t9125-git-svn-multi-glob-branch-names.sh diff --git a/git-svn.perl b/git-svn.perl index 503a7c900a..ee00e417d2 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -987,8 +987,10 @@ sub complete_url_ls_init { if (length $pfx && $pfx !~ m#/$#) { die "--prefix='$pfx' must have a trailing slash '/'\n"; } - command_noisy('config', "svn-remote.$gs->{repo_id}.$n", - "$remote_path:refs/remotes/$pfx*"); + command_noisy('config', + "svn-remote.$gs->{repo_id}.$n", + "$remote_path:refs/remotes/$pfx*" . + ('/*' x (($remote_path =~ tr/*/*/) - 1)) ); } sub verify_ref { @@ -4124,16 +4126,38 @@ sub gs_fetch_loop_common { Git::SVN::gc(); } +sub get_dir_globbed { + my ($self, $left, $depth, $r) = @_; + + my @x = eval { $self->get_dir($left, $r) }; + return unless scalar @x == 3; + my $dirents = $x[0]; + my @finalents; + foreach my $de (keys %$dirents) { + next if $dirents->{$de}->{kind} != $SVN::Node::dir; + if ($depth > 1) { + my @args = ("$left/$de", $depth - 1, $r); + foreach my $dir ($self->get_dir_globbed(@args)) { + push @finalents, "$de/$dir"; + } + } else { + push @finalents, $de; + } + } + @finalents; +} + sub match_globs { my ($self, $exists, $paths, $globs, $r) = @_; sub get_dir_check { my ($self, $exists, $g, $r) = @_; - my @x = eval { $self->get_dir($g->{path}->{left}, $r) }; - return unless scalar @x == 3; - my $dirents = $x[0]; - foreach my $de (keys %$dirents) { - next if $dirents->{$de}->{kind} != $SVN::Node::dir; + + my @dirs = $self->get_dir_globbed($g->{path}->{left}, + $g->{path}->{depth}, + $r); + + foreach my $de (@dirs) { my $p = $g->{path}->full_path($de); next if $exists->{$p}; next if (length $g->{path}->{right} && @@ -4915,16 +4939,20 @@ sub new { my ($class, $glob) = @_; my $re = $glob; $re =~ s!/+$!!g; # no need for trailing slashes - my $nr = $re =~ tr/*/*/; - if ($nr > 1) { - die "Only one '*' wildcard expansion ", - "is supported (got $nr): '$glob'\n"; - } elsif ($nr == 0) { + $re =~ m!^([^*]*)(\*(?:/\*)*)([^*]*)$!; + my $temp = $re; + my ($left, $right) = ($1, $3); + $re = $2; + my $depth = $re =~ tr/*/*/; + if ($depth != $temp =~ tr/*/*/) { + die "Only one set of wildcard directories " . + "(e.g. '*' or '*/*/*') is supported: '$glob'\n"; + } + if ($depth == 0) { die "One '*' is needed for glob: '$glob'\n"; } - $re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g; - my ($left, $right) = ($1, $2); - $re = quotemeta($left) . $re . quotemeta($right); + $re =~ s!\*!\[^/\]*!g; + $re = quotemeta($left) . "($re)" . quotemeta($right); if (length $left && !($left =~ s!/+$!!g)) { die "Missing trailing '/' on left side of: '$glob' ($left)\n"; } @@ -4933,7 +4961,7 @@ sub new { } my $left_re = qr/^\/\Q$left\E(\/|$)/; bless { left => $left, right => $right, left_regex => $left_re, - regex => qr/$re/, glob => $glob }, $class; + regex => qr/$re/, glob => $glob, depth => $depth }, $class; } sub full_path { diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh index 69e96878fe..8b792a1370 100755 --- a/t/t9108-git-svn-glob.sh +++ b/t/t9108-git-svn-glob.sh @@ -53,7 +53,8 @@ test_expect_success 'test refspec globbing' ' test "`git rev-parse refs/remotes/tags/end~1`" = \ "`git rev-parse refs/remotes/branches/start`" && test "`git rev-parse refs/remotes/branches/start~2`" = \ - "`git rev-parse refs/remotes/trunk`" + "`git rev-parse refs/remotes/trunk`" && + test_must_fail git rev-parse refs/remotes/tags/end@3 ' echo try to try > expect.two @@ -85,8 +86,8 @@ test_expect_success 'test left-hand-side only globbing' ' test_cmp expect.two output.two ' -echo "Only one '*' wildcard expansion is supported (got 2): 'branches/*/*'" \ - > expect.three +echo "Only one set of wildcard directories" \ + "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three echo "" >> expect.three test_expect_success 'test disallow multi-globs' ' @@ -94,7 +95,7 @@ test_expect_success 'test disallow multi-globs' ' git config --add svn-remote.three.fetch \ trunk:refs/remotes/three/trunk && git config --add svn-remote.three.branches \ - "branches/*/*:refs/remotes/three/branches/*" && + "branches/*/t/*:refs/remotes/three/branches/*" && git config --add svn-remote.three.tags \ "tags/*/*:refs/remotes/three/tags/*" && ( diff --git a/t/t9108-git-svn-multi-glob.sh b/t/t9108-git-svn-multi-glob.sh new file mode 100755 index 0000000000..3583721652 --- /dev/null +++ b/t/t9108-git-svn-multi-glob.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# Copyright (c) 2007 Eric Wong +test_description='git-svn globbing refspecs' +. ./lib-git-svn.sh + +cat > expect.end < trunk/src/a/readme && + echo "goodbye world" > trunk/src/b/readme && + svn import -m "initial" trunk "$svnrepo"/trunk && + svn co "$svnrepo" tmp && + ( + cd tmp && + mkdir branches branches/v1 tags && + svn add branches tags && + svn cp trunk branches/v1/start && + svn commit -m "start a new branch" && + svn up && + echo "hi" >> branches/v1/start/src/b/readme && + poke branches/v1/start/src/b/readme && + echo "hey" >> branches/v1/start/src/a/readme && + poke branches/v1/start/src/a/readme && + svn commit -m "hi" && + svn up && + svn cp branches/v1/start tags/end && + echo "bye" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + echo "aye" >> tags/end/src/a/readme && + poke tags/end/src/a/readme && + svn commit -m "the end" && + echo "byebye" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "nothing to see here" + ) && + git config --add svn-remote.svn.url "$svnrepo" && + git config --add svn-remote.svn.fetch \ + "trunk/src/a:refs/remotes/trunk" && + git config --add svn-remote.svn.branches \ + "branches/*/*/src/a:refs/remotes/branches/*/*" && + git config --add svn-remote.svn.tags\ + "tags/*/src/a:refs/remotes/tags/*" && + git-svn multi-fetch && + git log --pretty=oneline refs/remotes/tags/end | \ + sed -e "s/^.\{41\}//" > output.end && + test_cmp expect.end output.end && + test "`git rev-parse refs/remotes/tags/end~1`" = \ + "`git rev-parse refs/remotes/branches/v1/start`" && + test "`git rev-parse refs/remotes/branches/v1/start~2`" = \ + "`git rev-parse refs/remotes/trunk`" && + test_must_fail git rev-parse refs/remotes/tags/end@3 + ' + +echo try to try > expect.two +echo nothing to see here >> expect.two +cat expect.end >> expect.two + +test_expect_success 'test left-hand-side only globbing' ' + git config --add svn-remote.two.url "$svnrepo" && + git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk && + git config --add svn-remote.two.branches \ + "branches/*/*:refs/remotes/two/branches/*/*" && + git config --add svn-remote.two.tags \ + "tags/*:refs/remotes/two/tags/*" && + ( + cd tmp && + echo "try try" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "try to try" + ) && + git-svn fetch two && + test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 && + test `git rev-list refs/remotes/two/branches/v1/start | wc -l` -eq 3 && + test `git rev-parse refs/remotes/two/branches/v1/start~2` = \ + `git rev-parse refs/remotes/two/trunk` && + test `git rev-parse refs/remotes/two/tags/end~3` = \ + `git rev-parse refs/remotes/two/branches/v1/start` && + git log --pretty=oneline refs/remotes/two/tags/end | \ + sed -e "s/^.\{41\}//" > output.two && + test_cmp expect.two output.two + ' +cat > expect.four <> branches/v2/start/src/b/readme && + poke branches/v2/start/src/b/readme && + echo "howdy" >> branches/v2/start/src/a/readme && + poke branches/v2/start/src/a/readme && + svn commit -m "Changed 2 in v2/start" && + svn up && + svn cp branches/v2/start tags/next && + echo "bye" >> tags/next/src/b/readme && + poke tags/next/src/b/readme && + echo "aye" >> tags/next/src/a/readme && + poke tags/next/src/a/readme && + svn commit -m "adding more" && + echo "byebye" >> tags/next/src/b/readme && + poke tags/next/src/b/readme && + svn commit -m "adios" + ) && + git config --add svn-remote.four.url "$svnrepo" && + git config --add svn-remote.four.fetch trunk:refs/remotes/four/trunk && + git config --add svn-remote.four.branches \ + "branches/*/*:refs/remotes/four/branches/*/*" && + git config --add svn-remote.four.tags \ + "tags/*:refs/remotes/four/tags/*" && + git-svn fetch four && + test `git rev-list refs/remotes/four/tags/next | wc -l` -eq 5 && + test `git rev-list refs/remotes/four/branches/v2/start | wc -l` -eq 3 && + test `git rev-parse refs/remotes/four/branches/v2/start~2` = \ + `git rev-parse refs/remotes/four/trunk` && + test `git rev-parse refs/remotes/four/tags/next~2` = \ + `git rev-parse refs/remotes/four/branches/v2/start` && + git log --pretty=oneline refs/remotes/four/tags/next | \ + sed -e "s/^.\{41\}//" > output.four && + test_cmp expect.four output.four + ' + +echo "Only one set of wildcard directories" \ + "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three +echo "" >> expect.three + +test_expect_success 'test disallow multiple globs' ' + git config --add svn-remote.three.url "$svnrepo" && + git config --add svn-remote.three.fetch \ + trunk:refs/remotes/three/trunk && + git config --add svn-remote.three.branches \ + "branches/*/t/*:refs/remotes/three/branches/*/*" && + git config --add svn-remote.three.tags \ + "tags/*:refs/remotes/three/tags/*" && + ( + cd tmp && + echo "try try" >> tags/end/src/b/readme && + poke tags/end/src/b/readme && + svn commit -m "try to try" + ) && + test_must_fail git-svn fetch three 2> stderr.three && + test_cmp expect.three stderr.three + ' + +test_done diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh new file mode 100755 index 0000000000..6b62b52f54 --- /dev/null +++ b/t/t9125-git-svn-multi-glob-branch-names.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Copyright (c) 2008 Marcus Griep + +test_description='git-svn multi-glob branch names' +. ./lib-git-svn.sh + +test_expect_success 'setup svnrepo' ' + mkdir project project/trunk project/branches \ + project/branches/v14.1 project/tags && + echo foo > project/trunk/foo && + svn import -m "$test_description" project "$svnrepo/project" && + rm -rf project && + svn cp -m "fun" "$svnrepo/project/trunk" \ + "$svnrepo/project/branches/v14.1/beta" && + svn cp -m "more fun!" "$svnrepo/project/branches/v14.1/beta" \ + "$svnrepo/project/branches/v14.1/gold" + ' + +test_expect_success 'test clone with multi-glob in branch names' ' + git svn clone -T trunk -b branches/*/* -t tags \ + "$svnrepo/project" project && + cd project && + git rev-parse "refs/remotes/v14.1/beta" && + git rev-parse "refs/remotes/v14.1/gold" && + cd .. + ' + +test_expect_success 'test dcommit to multi-globbed branch' " + cd project && + git reset --hard 'refs/remotes/v14.1/gold' && + echo hello >> foo && + git commit -m 'hello' -- foo && + git svn dcommit && + cd .. + " + +test_done From 222566e42cfc339b31db4757800cc387bcd8c20e Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 8 Aug 2008 01:41:58 -0700 Subject: [PATCH 15/73] git-svn: wrap long lines in a few places Oops, I let a few patches slip by with long lines in them. Extracted from an unrelated patch by: Marcus Griep Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index ee00e417d2..4dc33801a8 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -171,7 +171,8 @@ my %cmd = ( 'color' => \$Git::SVN::Log::color, 'pager=s' => \$Git::SVN::Log::pager } ], - 'find-rev' => [ \&cmd_find_rev, "Translate between SVN revision numbers and tree-ish", + 'find-rev' => [ \&cmd_find_rev, + "Translate between SVN revision numbers and tree-ish", {} ], 'rebase' => [ \&cmd_rebase, "Fetch and rebase your working directory", { 'merge|m|M' => \$_merge, @@ -231,7 +232,9 @@ unless ($cmd && $cmd =~ /(?:clone|init|multi-init)$/) { my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd); read_repo_config(\%opts); -Getopt::Long::Configure('pass_through') if ($cmd && ($cmd eq 'log' || $cmd eq 'blame')); +if ($cmd && ($cmd eq 'log' || $cmd eq 'blame')) { + Getopt::Long::Configure('pass_through'); +} my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version, 'minimize-connections' => \$Git::SVN::Migration::_minimize, 'id|i=s' => \$Git::SVN::default_ref_id, From 01144f20955bfbb6463c9649d90f411839ad1617 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sat, 9 Aug 2008 00:37:02 +0200 Subject: [PATCH 16/73] builtin-rm: Add a --force flag This adds a --force flag to git-rm, making it somewhat easier for subversion people to switch. Signed-off-by: Pieter de Bie Signed-off-by: Junio C Hamano --- Documentation/git-rm.txt | 3 ++- builtin-rm.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index 4d0c495bc3..5afb1e7428 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -7,7 +7,7 @@ git-rm - Remove files from the working tree and from the index SYNOPSIS -------- -'git rm' [-f] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] ... +'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] ... DESCRIPTION ----------- @@ -36,6 +36,7 @@ OPTIONS but this requires the `-r` option to be explicitly given. -f:: +--force:: Override the up-to-date check. -n:: diff --git a/builtin-rm.c b/builtin-rm.c index ee8247b08c..0ed26bb8f1 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -131,7 +131,7 @@ static struct option builtin_rm_options[] = { OPT__DRY_RUN(&show_only), OPT__QUIET(&quiet), OPT_BOOLEAN( 0 , "cached", &index_only, "only remove from the index"), - OPT_BOOLEAN('f', NULL, &force, "override the up-to-date check"), + OPT_BOOLEAN('f', "force", &force, "override the up-to-date check"), OPT_BOOLEAN('r', NULL, &recursive, "allow recursive removal"), OPT_BOOLEAN( 0 , "ignore-unmatch", &ignore_unmatch, "exit with a zero status even if nothing matched"), From a9fd1383a73878284d4157b20ac7c735e876102e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 9 Aug 2008 01:17:24 -0700 Subject: [PATCH 17/73] mailinfo: fix MIME multi-part message boundary handling After finding a MIME multi-part message boundary line, the handle_body() function is supposed to first flush any accumulated contents from the previous part to the output stream. However, the code mistakenly output the boundary line it found. The old code that used one global, fixed-length buffer line[] used an alternate static buffer newline[] for keeping track of this accumulated contents and flushed newline[] upon seeing the boundary; when 3b6121f (git-mailinfo: use strbuf's instead of fixed buffers, 2008-07-13) converted a fixed-length buffer in this program to use strbuf,these two buffers were converted to "line" and "prev" (the latter of which now has a much more sensible name) strbufs, but the code mistakenly flushed "line" (which contains the boundary we have just found), instead of "prev". This resulted in the first boundary to be output in front of the first line of the message. The rewritten implementation of handle_boundary() lost the terminating newline; this would then result in the second line of the message to be stuck with the first line. The is_multipart_boundary() was designed to catch both the internal boundary and the terminating one (the one with trailing "--"); this also was broken with the rewrite, and the code in the handle_boundary() to handle the terminating boundary was never triggered. Signed-off-by: Junio C Hamano --- builtin-mailinfo.c | 17 +++++++++++------ t/t5100-mailinfo.sh | 2 +- t/t5100/info0011 | 5 +++++ t/t5100/msg0011 | 2 ++ t/t5100/patch0011 | 22 ++++++++++++++++++++++ t/t5100/sample.mbox | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 t/t5100/info0011 create mode 100644 t/t5100/msg0011 create mode 100644 t/t5100/patch0011 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c index f974b9df96..3577382d70 100644 --- a/builtin-mailinfo.c +++ b/builtin-mailinfo.c @@ -203,7 +203,8 @@ static void handle_content_transfer_encoding(const struct strbuf *line) static int is_multipart_boundary(const struct strbuf *line) { - return !strbuf_cmp(line, *content_top); + return (((*content_top)->len <= line->len) && + !memcmp(line->buf, (*content_top)->buf, (*content_top)->len)); } static void cleanup_subject(struct strbuf *subject) @@ -649,8 +650,11 @@ again: check_header(&line, p_hdr_data, 0); strbuf_release(&newline); - /* eat the blank line after section info */ - return (strbuf_getline(&line, fin, '\n') == 0); + /* replenish line */ + if (strbuf_getline(&line, fin, '\n')) + return 0; + strbuf_addch(&line, '\n'); + return 1; } static inline int patchbreak(const struct strbuf *line) @@ -757,9 +761,10 @@ static void handle_body(void) /* process any boundary lines */ if (*content_top && is_multipart_boundary(&line)) { /* flush any leftover */ - if (line.len) - handle_filter(&line); - + if (prev.len) { + handle_filter(&prev); + strbuf_reset(&prev); + } if (!handle_boundary()) goto handle_body_out; } diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh index e9f3e72c7e..8dfaddda91 100755 --- a/t/t5100-mailinfo.sh +++ b/t/t5100-mailinfo.sh @@ -11,7 +11,7 @@ test_expect_success 'split sample box' \ 'git mailsplit -o. ../t5100/sample.mbox >last && last=`cat last` && echo total is $last && - test `cat last` = 10' + test `cat last` = 11' for mail in `echo 00*` do diff --git a/t/t5100/info0011 b/t/t5100/info0011 new file mode 100644 index 0000000000..da5a605a12 --- /dev/null +++ b/t/t5100/info0011 @@ -0,0 +1,5 @@ +Author: A U Thor +Email: a.u.thor@example.com +Subject: Xyzzy +Date: Fri, 8 Aug 2008 13:08:37 +0200 (CEST) + diff --git a/t/t5100/msg0011 b/t/t5100/msg0011 new file mode 100644 index 0000000000..4667f21007 --- /dev/null +++ b/t/t5100/msg0011 @@ -0,0 +1,2 @@ +Here comes a commit log message, and +its second line is here. diff --git a/t/t5100/patch0011 b/t/t5100/patch0011 new file mode 100644 index 0000000000..8841d3c139 --- /dev/null +++ b/t/t5100/patch0011 @@ -0,0 +1,22 @@ +--- + builtin-mailinfo.c | 4 ++-- + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index 3e5fe51..aabfe5c 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -758,8 +758,8 @@ static void handle_body(void) + /* process any boundary lines */ + if (*content_top && is_multipart_boundary(&line)) { + /* flush any leftover */ +- if (line.len) +- handle_filter(&line); ++ if (prev.len) ++ handle_filter(&prev); + + if (!handle_boundary()) + goto handle_body_out; +-- +1.6.0.rc2 + + diff --git a/t/t5100/sample.mbox b/t/t5100/sample.mbox index aba57f922b..d7ca79b1fc 100644 --- a/t/t5100/sample.mbox +++ b/t/t5100/sample.mbox @@ -465,3 +465,38 @@ index 962aa34..2d1520f 100644 -- 1.5.6.2.455.g1efb2 +From nobody Fri Aug 8 22:24:03 2008 +Date: Fri, 8 Aug 2008 13:08:37 +0200 (CEST) +From: A U Thor +Subject: [PATCH 3/3 v2] Xyzzy +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="=-=-=" + +--=-=-= +Content-Type: text/plain; charset=iso-8859-15 +Content-Transfer-Encoding: quoted-printable + +Here comes a commit log message, and +its second line is here. +--- + builtin-mailinfo.c | 4 ++-- + +diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c +index 3e5fe51..aabfe5c 100644 +--- a/builtin-mailinfo.c ++++ b/builtin-mailinfo.c +@@ -758,8 +758,8 @@ static void handle_body(void) + /* process any boundary lines */ + if (*content_top && is_multipart_boundary(&line)) { + /* flush any leftover */ +- if (line.len) +- handle_filter(&line); ++ if (prev.len) ++ handle_filter(&prev); +=20 + if (!handle_boundary()) + goto handle_body_out; +--=20 +1.6.0.rc2 + +--=-=-=-- From 71b9979bc74b66c1cf961d5c74de5c0b3cbf00a4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 9 Aug 2008 15:11:48 -0700 Subject: [PATCH 18/73] Update draft RelNotes for 1.6.0 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.0.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/RelNotes-1.6.0.txt b/Documentation/RelNotes-1.6.0.txt index e524d80fbf..8afb5b2531 100644 --- a/Documentation/RelNotes-1.6.0.txt +++ b/Documentation/RelNotes-1.6.0.txt @@ -5,7 +5,7 @@ User visible changes -------------------- With the default Makefile settings, most of the programs are now -installed outside your $PATH, except for "git", "gitk", "git-gui" and +installed outside your $PATH, except for "git", "gitk" and some server side programs that need to be accessible for technical reasons. Invoking a git subcommand as "git-xyzzy" from the command line has been deprecated since early 2006 (and officially announced in @@ -186,7 +186,7 @@ Updates since v1.5.6 * fast-import and fast-export learned to export and import gitlinks. -* "gitk" left background process behind after begin asked to dig very deep +* "gitk" left background process behind after being asked to dig very deep history and the user killed the UI; the process is killed when the UI goes away now. @@ -248,6 +248,6 @@ this release, unless otherwise noted. --- exec >/var/tmp/1 -O=v1.6.0-rc1-113-gf44bc33 +O=v1.6.0-rc2-21-g0bb3a0b echo O=$(git describe refs/heads/master) git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint From 1c1fe1005c9dacc05a34eb892ae20ebb1904a33b Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 10 Aug 2008 00:02:08 -0700 Subject: [PATCH 19/73] git-gui 0.11 Signed-off-by: Shawn O. Pearce --- GIT-VERSION-GEN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 0ab478ef90..4e709ebe77 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=0.10.GITGUI +DEF_VER=0.11.GITGUI LF=' ' From df75e86d7307c2fd16d8df1bcbe8d7ccfb7305ff Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 9 Aug 2008 14:41:50 +0400 Subject: [PATCH 20/73] gitk: Allow safely calling nukefile from a run queue handler Originally dorunq assumed that the queue entry remained first in the queue after the script eval, and blindly removed it. However, if the handler calls nukefile, it may not be the case anymore, and a random queue entry gets dropped instead. This makes dorunq remove the entry before calling the script, and adds a global variable to allow other functions to determine if they are called from within a dorunq handler. Signed-off-by: Alexander Gavrilov Signed-off-by: Paul Mackerras --- gitk | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gitk b/gitk index d093a39506..087c4ac733 100755 --- a/gitk +++ b/gitk @@ -22,11 +22,11 @@ proc gitdir {} { # run before X event handlers, so reading from a fast source can # make the GUI completely unresponsive. proc run args { - global isonrunq runq + global isonrunq runq currunq set script $args if {[info exists isonrunq($script)]} return - if {$runq eq {}} { + if {$runq eq {} && ![info exists currunq]} { after idle dorunq } lappend runq [list {} $script] @@ -38,10 +38,10 @@ proc filerun {fd script} { } proc filereadable {fd script} { - global runq + global runq currunq fileevent $fd readable {} - if {$runq eq {}} { + if {$runq eq {} && ![info exists currunq]} { after idle dorunq } lappend runq [list $fd $script] @@ -60,17 +60,19 @@ proc nukefile {fd} { } proc dorunq {} { - global isonrunq runq + global isonrunq runq currunq set tstart [clock clicks -milliseconds] set t0 $tstart while {[llength $runq] > 0} { set fd [lindex $runq 0 0] set script [lindex $runq 0 1] + set currunq [lindex $runq 0] + set runq [lrange $runq 1 end] set repeat [eval $script] + unset currunq set t1 [clock clicks -milliseconds] set t [expr {$t1 - $t0}] - set runq [lrange $runq 1 end] if {$repeat ne {} && $repeat} { if {$fd eq {} || $repeat == 2} { # script returns 1 if it wants to be readded From 18a2197e6d1be4b2a4a4b10cac34215fac5be5f9 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Sun, 10 Aug 2008 15:04:34 +0200 Subject: [PATCH 21/73] Documentation: rev-list-options: Fix -g paragraph formatting - Add an escape to @{now}. Without the escape, the brace does something magic and eats half the sentence up to the closing brace at 'timestamp}'. - Join the last paragraph with a '+'. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index f69260f4c0..56e2eca258 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -260,10 +260,10 @@ With '\--pretty' format other than oneline (for obvious reasons), this causes the output to have two extra lines of information taken from the reflog. By default, 'commit@\{Nth}' notation is used in the output. When the starting commit is specified as -'commit@{now}', output also uses 'commit@\{timestamp}' notation +'commit@\{now}', output also uses 'commit@\{timestamp}' notation instead. Under '\--pretty=oneline', the commit message is prefixed with this information on the same line. - ++ Cannot be combined with '\--reverse'. See also linkgit:git-reflog[1]. From 38881a9066fcb3ce6e0438e6d7b20cce22ece411 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 10 Aug 2008 01:33:29 +0200 Subject: [PATCH 22/73] reflog test: add more tests for 'reflog delete' This adds more tests for 'reflog delete' and marks it as broken, as currently a call to 'git reflog delete HEAD@{1}' deletes entries in the currently checked out branch's log, not the HEAD log. Noticed by John Wiegley Signed-off-by: Pieter de Bie Signed-off-by: Junio C Hamano --- t/t1410-reflog.sh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 73f830db23..3b9860ea2e 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -175,7 +175,7 @@ test_expect_success 'recover and check' ' ' -test_expect_success 'delete' ' +test_expect_failure 'delete' ' echo 1 > C && test_tick && git commit -m rat C && @@ -188,16 +188,30 @@ test_expect_success 'delete' ' test_tick && git commit -m tiger C && - test 5 = $(git reflog | wc -l) && + HEAD_entry_count=$(git reflog | wc -l) + master_entry_count=$(git reflog show master | wc -l) + + test $HEAD_entry_count = 5 && + test $master_entry_count = 5 && + git reflog delete master@{1} && git reflog show master > output && - test 4 = $(wc -l < output) && + test $(($master_entry_count - 1)) = $(wc -l < output) && + test $HEAD_entry_count = $(git reflog | wc -l) && ! grep ox < output && + master_entry_count=$(wc -l < output) + + git reflog delete HEAD@{1} && + test $(($HEAD_entry_count -1)) = $(git reflog | wc -l) && + test $master_entry_count = $(git reflog show master | wc -l) && + + HEAD_entry_count=$(git reflog | wc -l) + git reflog delete master@{07.04.2005.15:15:00.-0700} && git reflog show master > output && - test 3 = $(wc -l < output) && + test $(($master_entry_count - 1)) = $(wc -l < output) && ! grep dragon < output ' From 55beff4f536011e5d7f17ae63911f1bb56308feb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 10 Aug 2008 23:21:25 -0700 Subject: [PATCH 23/73] Fix deleting reflog entries from HEAD reflog dwim_ref() used to resolve HEAD symbolic ref to its target (i.e. current branch). This incorrectly removed the reflog entry from the current branch when 'git reflog delete HEAD@{1}' was asked for. Signed-off-by: Junio C Hamano --- builtin-reflog.c | 4 ++-- t/t1410-reflog.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builtin-reflog.c b/builtin-reflog.c index 125d455b97..7d7047d792 100644 --- a/builtin-reflog.c +++ b/builtin-reflog.c @@ -604,8 +604,8 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) continue; } - if (!dwim_ref(argv[i], spec - argv[i], sha1, &ref)) { - status |= error("%s points nowhere!", argv[i]); + if (!dwim_log(argv[i], spec - argv[i], sha1, &ref)) { + status |= error("no reflog for '%s'", argv[i]); continue; } diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 3b9860ea2e..5b24f05573 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -175,7 +175,7 @@ test_expect_success 'recover and check' ' ' -test_expect_failure 'delete' ' +test_expect_success 'delete' ' echo 1 > C && test_tick && git commit -m rat C && From 4f80b27d48fee1c588810f3341ffe5d14558cea2 Mon Sep 17 00:00:00 2001 From: Ivan Stankovic Date: Sun, 10 Aug 2008 18:22:14 +0200 Subject: [PATCH 24/73] Documentation: fix invalid reference to 'mybranch' in user manual Signed-off-by: Ivan Stankovic Signed-off-by: Junio C Hamano --- Documentation/user-manual.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 64a820bf60..49a4a898d7 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -2812,7 +2812,7 @@ $ git config remote.example.fetch +master:ref/remotes/example/master ------------------------------------------------- Don't do this unless you're sure you won't mind "git fetch" possibly -throwing away commits on mybranch. +throwing away commits on 'example/master'. Also note that all of the above configuration can be performed by directly editing the file .git/config instead of using From e534735a4cd778ac8172f543869a20894c1022a6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 11 Aug 2008 14:24:51 -0700 Subject: [PATCH 25/73] Re-fix rev-list-options documentation 18a2197 (Documentation: rev-list-options: Fix -g paragraph formatting, 2008-08-10) introduced the third paragraph that is continued, but it seems to confuse docbook toolchain on FC9 machines. Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 56e2eca258..c953d1cac5 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -263,8 +263,7 @@ used in the output. When the starting commit is specified as 'commit@\{now}', output also uses 'commit@\{timestamp}' notation instead. Under '\--pretty=oneline', the commit message is prefixed with this information on the same line. -+ -Cannot be combined with '\--reverse'. +This option cannot be combined with '\--reverse'. See also linkgit:git-reflog[1]. --merge:: From 2860b57a87ba7e544d472701c83019d7624e6a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Sun, 10 Aug 2008 22:26:23 +0700 Subject: [PATCH 26/73] Fix typo in comments of longest_ancestor_length() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- path.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/path.c b/path.c index 9df447bd6d..76e8872622 100644 --- a/path.c +++ b/path.c @@ -365,7 +365,7 @@ int normalize_absolute_path(char *buf, const char *path) * path = Canonical absolute path * prefix_list = Colon-separated list of absolute paths * - * Determines, for each path in parent_list, whether the "prefix" really + * Determines, for each path in prefix_list, whether the "prefix" really * is an ancestor directory of path. Returns the length of the longest * ancestor directory, excluding any trailing slashes, or -1 if no prefix * is an ancestor. (Note that this means 0 is returned if prefix_list is From e5d3afd78be54fc6e958c7ebad178593fd030441 Mon Sep 17 00:00:00 2001 From: Francis Moreau Date: Mon, 11 Aug 2008 19:37:46 +0200 Subject: [PATCH 27/73] git-bisect: fix wrong usage of read(1) Signed-off-by: Francis Moreau Signed-off-by: Junio C Hamano --- git-bisect.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git-bisect.sh b/git-bisect.sh index 991b2ef37e..6c6c3de54a 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -220,7 +220,8 @@ bisect_next_check() { if test -t 0 then printf >&2 'Are you sure [Y/n]? ' - case "$(read yesno)" in [Nn]*) exit 1 ;; esac + read yesno + case "$yesno" in [Nn]*) exit 1 ;; esac fi : bisect without good... ;; From 7dce9918c72148139c3eb7a2a5c66b0df9ed415d Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Tue, 12 Aug 2008 00:34:46 +0200 Subject: [PATCH 28/73] Adjust for the new way of enabling the default post-update hook The post-update hook, which is required to be enabled in order for the repository to be accessible over HTTP, is not enabled by chmod a+x anymore, but instead by dropping the .sample suffix. This patch emphasizes this change in the release notes (since I believe this is rather noticeable backwards-incompatible change). It also adjusts the documentation which still described the old way and fixes t/t5540-http-push.sh, which was broken for 1.5 month but apparently noone ever runs this test. Signed-off-by: Petr Baudis Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.0.txt | 16 +++++++++++----- Documentation/gitcore-tutorial.txt | 15 ++++++++------- Documentation/user-manual.txt | 2 +- t/t5540-http-push.sh | 2 +- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Documentation/RelNotes-1.6.0.txt b/Documentation/RelNotes-1.6.0.txt index 8afb5b2531..e3c0c1d88d 100644 --- a/Documentation/RelNotes-1.6.0.txt +++ b/Documentation/RelNotes-1.6.0.txt @@ -28,6 +28,16 @@ introduced in v1.5.2 and v1.4.4.5. If you want to keep your repositories backwards compatible past these versions, set repack.useDeltaBaseOffset to false or pack.indexVersion to 1, respectively. +We used to prevent sample hook scripts shipped in templates/ from +triggering by default by relying on the fact that we install them as +unexecutable, but on some filesystems, this approach does not work. +They are now shipped with ".sample" suffix. If you want to activate +any of these samples as-is, rename them to drop the ".sample" suffix, +instead of running "chmod +x" on them. For example, you can rename +hooks/post-update.sample to hooks/post-update to enable the sample +hook that runs update-server-info, in order to make repositories +friendly to dumb protocols (i.e. HTTP). + GIT_CONFIG, which was only documented as affecting "git config", but actually affected all git commands, now only affects "git config". GIT_LOCAL_CONFIG, also only documented as affecting "git config" and @@ -56,11 +66,7 @@ Updates since v1.5.6 gangs. * Sample hook scripts shipped in templates/ are now suffixed with - *.sample. We used to prevent them from triggering by default by - relying on the fact that we install them as unexecutable, but on - some filesystems this approach does not work. Instead of running - "chmod +x" on them, the users who want to activate these samples - as-is can now rename them dropping *.sample suffix. + *.sample. * perl's in-place edit (-i) does not work well without backup files on Windows; some tests are rewritten to cope with this. diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index 49179b0a00..a417e592ac 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -1366,8 +1366,9 @@ your login shell is 'bash', only `.bashrc` is read and not [NOTE] If you plan to publish this repository to be accessed over http, -you should do `chmod +x my-git.git/hooks/post-update` at this -point. This makes sure that every time you push into this +you should do `mv my-git.git/hooks/post-update.sample +my-git.git/hooks/post-update` at this point. +This makes sure that every time you push into this repository, `git update-server-info` is run. Your "public repository" is now ready to accept your changes. @@ -1486,11 +1487,11 @@ A recommended workflow for a "project lead" goes like this: If other people are pulling from your repository over dumb transport protocols (HTTP), you need to keep this repository 'dumb transport friendly'. After `git init`, -`$GIT_DIR/hooks/post-update` copied from the standard templates -would contain a call to 'git-update-server-info' but the -`post-update` hook itself is disabled by default -- enable it -with `chmod +x post-update`. This makes sure 'git-update-server-info' -keeps the necessary files up-to-date. +`$GIT_DIR/hooks/post-update.sample` copied from the standard templates +would contain a call to 'git-update-server-info' +but you need to manually enable the hook with +`mv post-update.sample post-update`. This makes sure +'git-update-server-info' keeps the necessary files up-to-date. 3. Push into the public repository from your primary repository. diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index e99921108e..08d1310bf5 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1890,7 +1890,7 @@ adjustments to give web clients some extra information they need: $ mv proj.git /home/you/public_html/proj.git $ cd proj.git $ git --bare update-server-info -$ chmod a+x hooks/post-update +$ mv hooks/post-update.sample hooks/post-update ------------------------------------------------- (For an explanation of the last two lines, see diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh index f8c17cd96c..b0d242e3ed 100755 --- a/t/t5540-http-push.sh +++ b/t/t5540-http-push.sh @@ -41,7 +41,7 @@ test_expect_success 'setup remote repository' ' git clone --bare test_repo test_repo.git && cd test_repo.git && git --bare update-server-info && - chmod +x hooks/post-update && + mv hooks/post-update.sample hooks/post-update && cd - && mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH" ' From d777af86d84f73be50e922b84144d959475ed770 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Tue, 12 Aug 2008 01:55:35 +0200 Subject: [PATCH 29/73] Documentation: rev-list-options: Fix a typo Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index be84721781..1d857559ef 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -71,7 +71,7 @@ For example, if you have this topology: o---x---a---a branch A ----------------------------------------------------------------------- + -you would get an output line this: +you would get an output like this: + ----------------------------------------------------------------------- $ git rev-list --left-right --boundary --pretty=oneline A...B From 2318121babea786390f51796bfce17088c3420ee Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:24 +0100 Subject: [PATCH 30/73] Create a specific version of the read_pipe_lines command for p4 invocations This will make it easier to isolate changes to how 'p4' is invoked (whether with parameters or not, etc.). Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 6ae0429c2d..fc2a60dfee 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -57,6 +57,13 @@ def read_pipe_lines(c): return val +def p4_read_pipe_lines(c): + """Specifically invoke p4 on the command supplied. """ + real_cmd = "%s %s" % ("p4", c) + if verbose: + print real_cmd + return read_pipe_lines(real_cmd) + def system(cmd): if verbose: sys.stderr.write("executing %s\n" % cmd) From b340fa43017437988e233ed4fd8dc00042614071 Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:25 +0100 Subject: [PATCH 31/73] Utilise the new 'p4_read_pipe_lines' command Now that we have the new command, we can utilise it and then eventually, isolate any changes required to the one place. Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index fc2a60dfee..3deaa42559 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -371,7 +371,7 @@ def originP4BranchesExist(): def p4ChangesForPaths(depotPaths, changeRange): assert depotPaths - output = read_pipe_lines("p4 changes " + ' '.join (["%s...%s" % (p, changeRange) + output = p4_read_pipe_lines("changes " + ' '.join (["%s...%s" % (p, changeRange) for p in depotPaths])) changes = [] @@ -519,7 +519,7 @@ class P4Submit(Command): # remove lines in the Files section that show changes to files outside the depot path we're committing into template = "" inFilesSection = False - for line in read_pipe_lines("p4 change -o"): + for line in p4_read_pipe_lines("change -o"): if line.endswith("\r\n"): line = line[:-2] + "\n" if inFilesSection: From bf9320f1512d7ad4a17a64cfe5a593bba5037b3e Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:26 +0100 Subject: [PATCH 32/73] Have a command that specifically invokes 'p4' (via system) Similiar to our 'p4_read_pipe_lines' command, we can isolate specific changes to the invocation method in the one location with this change. Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 3deaa42559..08acd517ba 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -70,6 +70,13 @@ def system(cmd): if os.system(cmd) != 0: die("command failed: %s" % cmd) +def p4_system(cmd): + """Specifically invoke p4 as the system command. """ + real_cmd = "%s %s" % ("p4", cmd) + if verbose: + print real_cmd + return system(real_cmd) + def isP4Exec(kind): """Determine if a Perforce 'kind' should have execute permission From 87b611d5fd518e4754e599bc2f348f83db410c56 Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:27 +0100 Subject: [PATCH 33/73] Utilise the new 'p4_system' function. Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 08acd517ba..2ed36ecd6b 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -98,7 +98,7 @@ def setP4ExecBit(file, mode): if p4Type[-1] == "+": p4Type = p4Type[0:-1] - system("p4 reopen -t %s %s" % (p4Type, file)) + p4_system("reopen -t %s %s" % (p4Type, file)) def getP4OpenedType(file): # Returns the perforce file type for the given file. @@ -561,7 +561,7 @@ class P4Submit(Command): modifier = diff['status'] path = diff['src'] if modifier == "M": - system("p4 edit \"%s\"" % path) + p4_system("edit \"%s\"" % path) if isModeExecChanged(diff['src_mode'], diff['dst_mode']): filesToChangeExecBit[path] = diff['dst_mode'] editedFiles.add(path) @@ -576,8 +576,8 @@ class P4Submit(Command): filesToAdd.remove(path) elif modifier == "R": src, dest = diff['src'], diff['dst'] - system("p4 integrate -Dt \"%s\" \"%s\"" % (src, dest)) - system("p4 edit \"%s\"" % (dest)) + p4_system("integrate -Dt \"%s\" \"%s\"" % (src, dest)) + p4_system("edit \"%s\"" % (dest)) if isModeExecChanged(diff['src_mode'], diff['dst_mode']): filesToChangeExecBit[dest] = diff['dst_mode'] os.unlink(dest) @@ -601,7 +601,7 @@ class P4Submit(Command): if response == "s": print "Skipping! Good luck with the next patches..." for f in editedFiles: - system("p4 revert \"%s\"" % f); + p4_system("revert \"%s\"" % f); for f in filesToAdd: system("rm %s" %f) return @@ -624,10 +624,10 @@ class P4Submit(Command): system(applyPatchCmd) for f in filesToAdd: - system("p4 add \"%s\"" % f) + p4_system("add \"%s\"" % f) for f in filesToDelete: - system("p4 revert \"%s\"" % f) - system("p4 delete \"%s\"" % f) + p4_system("revert \"%s\"" % f) + p4_system("delete \"%s\"" % f) # Set/clear executable bits for f in filesToChangeExecBit.keys(): @@ -728,7 +728,7 @@ class P4Submit(Command): os.chdir(self.clientPath) print "Syncronizing p4 checkout..." - system("p4 sync ...") + p4_system("sync ...") self.check() From 21a50753852cb51b120ec9933416daa6cea6d184 Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:28 +0100 Subject: [PATCH 34/73] Add a single command that will be used to construct the 'p4' command Rather than having three locations where the 'p4' command is built up, refactor this into the one place. This will, eventually, allow us to have one place where we modify the evironment or pass extra command-line options to the 'p4' binary. Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 2ed36ecd6b..b4acf7689d 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -16,6 +16,17 @@ from sets import Set; verbose = False + +def p4_build_cmd(cmd): + """Build a suitable p4 command line. + + This consolidates building and returning a p4 command line into one + location. It means that hooking into the environment, or other configuration + can be done more easily. + """ + real_cmd = "%s %s" % ("p4", cmd) + return real_cmd + def die(msg): if verbose: raise Exception(msg) From ee06427aa6d975c35b63c3cd103ace43fbde062b Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:29 +0100 Subject: [PATCH 35/73] If we are in verbose mode, output what we are about to run (or return) Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index b4acf7689d..d36b0c6bec 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -25,6 +25,8 @@ def p4_build_cmd(cmd): can be done more easily. """ real_cmd = "%s %s" % ("p4", cmd) + if verbose: + print real_cmd return real_cmd def die(msg): From 155af83491b26d958b147c93620816846343b019 Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:30 +0100 Subject: [PATCH 36/73] Switch to using 'p4_build_cmd' Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index d36b0c6bec..2b6ea74d1c 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -72,9 +72,7 @@ def read_pipe_lines(c): def p4_read_pipe_lines(c): """Specifically invoke p4 on the command supplied. """ - real_cmd = "%s %s" % ("p4", c) - if verbose: - print real_cmd + real_cmd = p4_build_cmd(c) return read_pipe_lines(real_cmd) def system(cmd): @@ -85,9 +83,7 @@ def system(cmd): def p4_system(cmd): """Specifically invoke p4 as the system command. """ - real_cmd = "%s %s" % ("p4", cmd) - if verbose: - print real_cmd + real_cmd = p4_build_cmd(cmd) return system(real_cmd) def isP4Exec(kind): @@ -172,7 +168,7 @@ def isModeExecChanged(src_mode, dst_mode): return isModeExec(src_mode) != isModeExec(dst_mode) def p4CmdList(cmd, stdin=None, stdin_mode='w+b'): - cmd = "p4 -G %s" % cmd + cmd = p4_build_cmd("-G %s" % (cmd)) if verbose: sys.stderr.write("Opening pipe: %s\n" % cmd) From abcaf07360357cf2e9ce4b34e44adc09bb5587f0 Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:31 +0100 Subject: [PATCH 37/73] If the user has configured various parameters, use them. Some repositories require authentication and access to certain hosts. Allow git-p4 to pull this information from the configuration Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 2b6ea74d1c..a927e50b25 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -24,7 +24,29 @@ def p4_build_cmd(cmd): location. It means that hooking into the environment, or other configuration can be done more easily. """ - real_cmd = "%s %s" % ("p4", cmd) + real_cmd = "%s " % "p4" + + user = gitConfig("git-p4.user") + if len(user) > 0: + real_cmd += "-u %s " % user + + password = gitConfig("git-p4.password") + if len(password) > 0: + real_cmd += "-P %s " % password + + port = gitConfig("git-p4.port") + if len(port) > 0: + real_cmd += "-p %s " % port + + host = gitConfig("git-p4.host") + if len(host) > 0: + real_cmd += "-h %s " % host + + client = gitConfig("git-p4.client") + if len(client) > 0: + real_cmd += "-c %s " % client + + real_cmd += "%s" % (cmd) if verbose: print real_cmd return real_cmd From 3cafb7d8ce63effe6bf477182d431ecb4470eded Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:32 +0100 Subject: [PATCH 38/73] Consistently use 'git-p4' for the configuration entries Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index a927e50b25..6c64224b77 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -1444,7 +1444,7 @@ class P4Sync(Command): if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes and gitBranchExists(self.branch): system("git symbolic-ref %sHEAD %s" % (self.refPrefix, self.branch)) - if self.useClientSpec or gitConfig("p4.useclientspec") == "true": + if self.useClientSpec or gitConfig("git-p4.useclientspec") == "true": self.getClientSpec() # TODO: should always look at previous commits, From bc02acfc769a1ae19772feaa7f03acfaea18a36f Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:33 +0100 Subject: [PATCH 39/73] Move git-p4.syncFromOrigin into a configuration parameters section Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4.txt | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/contrib/fast-import/git-p4.txt b/contrib/fast-import/git-p4.txt index b16a8384bc..0896abb933 100644 --- a/contrib/fast-import/git-p4.txt +++ b/contrib/fast-import/git-p4.txt @@ -63,18 +63,6 @@ It is recommended to run 'git repack -a -d -f' from time to time when using incremental imports to optimally combine the individual git packs that each incremental import creates through the use of git-fast-import. - -A useful setup may be that you have a periodically updated git repository -somewhere that contains a complete import of a Perforce project. That git -repository can be used to clone the working repository from and one would -import from Perforce directly after cloning using git-p4. If the connection to -the Perforce server is slow and the working repository hasn't been synced for a -while it may be desirable to fetch changes from the origin git repository using -the efficient git protocol. git-p4 supports this setup by calling "git fetch origin" -by default if there is an origin branch. You can disable this using - - git config git-p4.syncFromOrigin false - Updating ======== @@ -140,6 +128,22 @@ Example git-p4 rebase +Configuration parameters +======================== + +git-p4.syncFromOrigin + +A useful setup may be that you have a periodically updated git repository +somewhere that contains a complete import of a Perforce project. That git +repository can be used to clone the working repository from and one would +import from Perforce directly after cloning using git-p4. If the connection to +the Perforce server is slow and the working repository hasn't been synced for a +while it may be desirable to fetch changes from the origin git repository using +the efficient git protocol. git-p4 supports this setup by calling "git fetch origin" +by default if there is an origin branch. You can disable this using: + + git config [--global] git-p4.syncFromOrigin false + Implementation Details... ========================= From b87a659635f40b5301c6b18fa5e22c72ca79b830 Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:34 +0100 Subject: [PATCH 40/73] Put some documentation in about the parameters that have been added Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4.txt | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/contrib/fast-import/git-p4.txt b/contrib/fast-import/git-p4.txt index 0896abb933..79a22e9c10 100644 --- a/contrib/fast-import/git-p4.txt +++ b/contrib/fast-import/git-p4.txt @@ -131,6 +131,38 @@ Example Configuration parameters ======================== +git-p4.user ($P4USER) + +Allows you to specify the username to use to connect to the Perforce repository. + + git config [--global] git-p4.user public + +git-p4.password ($P4PASS) + +Allows you to specify the password to use to connect to the Perforce repository. +Warning this password will be visible on the command-line invocation of the p4 binary. + + git config [--global] git-p4.password public1234 + +git-p4.port ($P4PORT) + +Specify the port to be used to contact the Perforce server. As this will be passed +directly to the p4 binary, it may be in the format host:port as well. + + git config [--global] git-p4.port codes.zimbra.com:2666 + +git-p4.host ($P4HOST) + +Specify the host to contact for a Perforce repository. + + git config [--global] git-p4.host perforce.example.com + +git-p4.client ($P4CLIENT) + +Specify the client name to use + + git config [--global] git-p4.client public-view + git-p4.syncFromOrigin A useful setup may be that you have a periodically updated git repository From 5b5aa22f00c315021ff58450f18134b20dfd5abd Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Sun, 10 Aug 2008 19:26:35 +0100 Subject: [PATCH 41/73] Put in the two other configuration elements found in the source I am not entirely clear what these parameters do but felt it useful to call them out in the documentation. Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contrib/fast-import/git-p4.txt b/contrib/fast-import/git-p4.txt index 79a22e9c10..ac551d45f1 100644 --- a/contrib/fast-import/git-p4.txt +++ b/contrib/fast-import/git-p4.txt @@ -163,6 +163,10 @@ Specify the client name to use git config [--global] git-p4.client public-view +git-p4.allowSubmit + + git config [--global] git-p4.allowSubmit false + git-p4.syncFromOrigin A useful setup may be that you have a periodically updated git repository @@ -176,6 +180,10 @@ by default if there is an origin branch. You can disable this using: git config [--global] git-p4.syncFromOrigin false +git-p4.useclientspec + + git config [--global] git-p4.useclientspec false + Implementation Details... ========================= From 04c6e9e9ca34226db095bbaa1218030f99f0b7c6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 11 Aug 2008 22:15:28 -0700 Subject: [PATCH 42/73] diff --check: do not unconditionally complain about trailing empty lines Recently "git diff --check" learned to detect new trailing blank lines just like "git apply --whitespace" does. However this check should not trigger unconditionally. This patch makes it honor the whitespace settings from core.whitespace and gitattributes. Signed-off-by: Junio C Hamano --- diff.c | 3 ++- t/t4019-diff-wserror.sh | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/diff.c b/diff.c index 8746c60b9c..6954f992c2 100644 --- a/diff.c +++ b/diff.c @@ -1631,7 +1631,8 @@ static void builtin_checkdiff(const char *name_a, const char *name_b, ecb.priv = &data; xdi_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); - if (data.trailing_blanks_start) { + if ((data.ws_rule & WS_TRAILING_SPACE) && + data.trailing_blanks_start) { fprintf(o->file, "%s:%d: ends with blank lines.\n", data.filename, data.trailing_blanks_start); data.status = 1; /* report errors */ diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh index 0d9cbb6261..7eae1f4500 100755 --- a/t/t4019-diff-wserror.sh +++ b/t/t4019-diff-wserror.sh @@ -13,7 +13,8 @@ test_expect_success setup ' echo " HT and SP indent" >>F && echo "With trailing SP " >>F && echo "Carriage ReturnQ" | tr Q "\015" >>F && - echo "No problem" >>F + echo "No problem" >>F && + echo >>F ' @@ -160,4 +161,21 @@ test_expect_success 'with cr-at-eol (attribute)' ' ' +test_expect_success 'trailing empty lines (1)' ' + + rm -f .gitattributes && + test_must_fail git diff --check >output && + grep "ends with blank lines." output && + grep "trailing whitespace" output + +' + +test_expect_success 'trailing empty lines (2)' ' + + echo "F -whitespace" >.gitattributes && + git diff --check >output && + ! test -s output + +' + test_done From bd7b371e9c2aeb0aaf228dc1655e8d04fca6f797 Mon Sep 17 00:00:00 2001 From: "Stephen R. van den Berg" Date: Tue, 12 Aug 2008 21:36:13 +0200 Subject: [PATCH 43/73] git-daemon: SysV needs the signal handler reinstated. Fixes the bug on (amongst others) Solaris that only the first child ever is reaped. Signed-off-by: Stephen R. van den Berg Signed-off-by: Junio C Hamano --- daemon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/daemon.c b/daemon.c index 4540e8df5a..8dcde73200 100644 --- a/daemon.c +++ b/daemon.c @@ -794,6 +794,7 @@ static void child_handler(int signo) } break; } + signal(SIGCHLD, child_handler); } static int set_reuse_addr(int sockfd) From d08ed6d692a79eb2a62410d7e76380fbf25ca793 Mon Sep 17 00:00:00 2001 From: Gustaf Hendeby Date: Tue, 12 Aug 2008 16:24:25 +0200 Subject: [PATCH 44/73] gitattributes: Document built in hunk header patterns Since the hunk header pattern text was written patterns for Ruby and Pascal/Delphi have been added. For users to be able to find them they should be documented not only in code. Signed-off-by: Gustaf Hendeby Signed-off-by: Junio C Hamano --- Documentation/gitattributes.txt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index d7b41142d2..c61a58d8f2 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -307,9 +307,16 @@ backslash, and zero or more occurrences of `sub` followed by There are a few built-in patterns to make this easier, and `tex` is one of them, so you do not have to write the above in your configuration file (you still need to enable this with the -attribute mechanism, via `.gitattributes`). Another built-in -pattern is defined for `java` that defines a pattern suitable -for program text in Java language. +attribute mechanism, via `.gitattributes`). The following built in +patterns are available: + +- `java` suitable for source code in the Java lanugage. + +- `pascal` suitable for source code in the Pascal/Delphi language. + +- `ruby` suitable for source code in the Ruby language. + +- `tex` suitable for source code for LaTeX documents. Performing a three-way merge From 23b5beb28fdadbb1d80ebf686a35385609f7a180 Mon Sep 17 00:00:00 2001 From: Gustaf Hendeby Date: Tue, 12 Aug 2008 16:24:26 +0200 Subject: [PATCH 45/73] Teach git diff about BibTeX head hunk patterns All BibTeX entries starts with an @ followed by an entry type. Since there are many entry types and own can be defined, the pattern matches legal entry type names instead of just the default types (which would be a long list). The pattern also matches strings and comments since they will also be useful to position oneself in a bib-file. Signed-off-by: Gustaf Hendeby Signed-off-by: Junio C Hamano --- Documentation/gitattributes.txt | 2 ++ diff.c | 1 + 2 files changed, 3 insertions(+) diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index c61a58d8f2..db16b0ca5b 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -310,6 +310,8 @@ configuration file (you still need to enable this with the attribute mechanism, via `.gitattributes`). The following built in patterns are available: +- `bibtex` suitable for files with BibTeX coded references. + - `java` suitable for source code in the Java lanugage. - `pascal` suitable for source code in the Pascal/Delphi language. diff --git a/diff.c b/diff.c index 6954f992c2..bf5d5f15a3 100644 --- a/diff.c +++ b/diff.c @@ -1387,6 +1387,7 @@ static struct builtin_funcname_pattern { "\\|" "^\\(.*=[ \t]*\\(class\\|record\\).*\\)$" }, + { "bibtex", "\\(@[a-zA-Z]\\{1,\\}[ \t]*{\\{0,1\\}[ \t]*[^ \t\"@',\\#}{~%]*\\).*$" }, { "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" }, { "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" }, }; From 70d9895ebcb8d401b569d28f049ad37fcb7b5ade Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Tue, 12 Aug 2008 01:55:36 +0200 Subject: [PATCH 46/73] Documentation: rev-list-options: Rewrite simplification descriptions for clarity This completely rewrites the documentation of --full-history with lots of examples. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 153 +++++++++++++++++++++++++---- 1 file changed, 136 insertions(+), 17 deletions(-) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 1d857559ef..0ce3f7fbd9 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -43,11 +43,13 @@ endif::git-rev-list[] --parents:: - Print the parents of the commit. + Print the parents of the commit. Also enables parent + rewriting, see 'History Simplification' below. --children:: - Print the children of the commit. + Print the children of the commit. Also enables parent + rewriting, see 'History Simplification' below. ifdef::git-rev-list[] --timestamp:: @@ -191,14 +193,6 @@ endif::git-rev-list[] Stop when a given path disappears from the tree. ---full-history:: - - Show also parts of history irrelevant to current state of a given - path. This turns off history simplification, which removed merges - which didn't change anything at all at some child. It will still actually - simplify away merges that didn't change anything at all into either - child. - --no-merges:: Do not print commits with more than one parent. @@ -280,18 +274,144 @@ See also linkgit:git-reflog[1]. Output uninteresting commits at the boundary, which are usually not shown. +-- + +History Simplification +~~~~~~~~~~~~~~~~~~~~~~ + +When optional paths are given, 'git-rev-list' simplifies commits with +various strategies, according to the options you have selected. + +Suppose you specified `foo` as the . We shall call commits +that modify `foo` !TREESAME, and the rest TREESAME. (In a diff +filtered for `foo`, they look different and equal, respectively.) + +In the following, we will always refer to the same example history to +illustrate the differences between simplification settings. We assume +that you are filtering for a file `foo` in this commit graph: +----------------------------------------------------------------------- + .-A---M---N---O---P + / / / / / + I B C D E + \ / / / / + `-------------' +----------------------------------------------------------------------- +The horizontal line of history A--P is taken to be the first parent of +each merge. The commits are: + +* `I` is the initial commit, in which `foo` exists with contents + "asdf", and a file `quux` exists with contents "quux". Initial + commits are compared to an empty tree, so `I` is !TREESAME. + +* In `A`, `foo` contains just "foo". + +* `B` contains the same change as `A`. Its merge `M` is trivial and + hence TREESAME to all parents. + +* `C` does not change `foo`, but its merge `N` changes it to "foobar", + so it is not TREESAME to any parent. + +* `D` sets `foo` to "baz". Its merge `O` combines the strings from + `N` and `D` to "foobarbaz"; i.e., it is not TREESAME to any parent. + +* `E` changes `quux` to "xyzzy", and its merge `P` combines the + strings to "quux xyzzy". Despite appearing interesting, `P` is + TREESAME to all parents. + +'rev-list' walks backwards through history, including or excluding +commits based on whether '\--full-history' and/or parent rewriting +(via '\--parents' or '\--children') are used. The following settings +are available. + +Default mode:: + + Commits are included if they are not TREESAME to any parent + (though this can be changed, see '\--sparse' below). If the + commit was a merge, and it was TREESAME to one parent, follow + only that parent. (Even if there are several TREESAME + parents, follow only one of them.) Otherwise, follow all + parents. ++ +This results in: ++ +----------------------------------------------------------------------- + .-A---N---O + / / + I---------D +----------------------------------------------------------------------- ++ +Note how the rule to only follow the TREESAME parent, if one is +available, removed `B` from consideration entirely. `C` was +considered via `N`, but is TREESAME. Root commits are compared to an +empty tree, so `I` is !TREESAME. ++ +Parent/child relations are only visible with --parents, but that does +not affect the commits selected in default mode, so we have shown the +parent lines. + +--full-history without parent rewriting:: + + This mode differs from the default in one point: always follow + all parents of a merge, even if it is TREESAME to one of them. + Even if more than one side of the merge has commits that are + included, this does not imply that the merge itself is! In + the example, we get ++ +----------------------------------------------------------------------- + I A B N D O +----------------------------------------------------------------------- ++ +`P` and `M` were excluded because they are TREESAME to a parent. `E`, +`C` and `B` were all walked, but only `B` was !TREESAME, so the others +do not appear. ++ +Note that without parent rewriting, it is not really possible to talk +about the parent/child relationships between the commits, so we show +them disconnected. + +--full-history with parent rewriting:: + + Ordinary commits are only included if they are !TREESAME + (though this can be changed, see '\--sparse' below). ++ +Merges are always included. However, their parent list is rewritten: +Along each parent, prune away commits that are not included +themselves. This results in ++ +----------------------------------------------------------------------- + .-A---M---N---O---P + / / / / / + I B / D / + \ / / / / + `-------------' +----------------------------------------------------------------------- ++ +Compare to '\--full-history' without rewriting above. Note that `E` +was pruned away because it is TREESAME, but the parent list of P was +rewritten to contain `E`'s parent `I`. The same happened for `C` and +`N`. Note also that `P` was included despite being TREESAME. + +In addition to the above settings, you can change whether TREESAME +affects inclusion: + --dense:: + + Commits that are walked are included if they are not TREESAME + to any parent. + --sparse:: -When optional paths are given, the default behaviour ('--dense') is to -only output commits that changes at least one of them, and also ignore -merges that do not touch the given paths. + All commits that are walked are included. ++ +Note that without '\--full-history', this still simplifies merges: if +one of the parents is TREESAME, we follow only that one, so the other +sides of the merge are never walked. -Use the '--sparse' flag to makes the command output all eligible commits -(still subject to count and age limitation), but apply merge -simplification nevertheless. ifdef::git-rev-list[] +Bisection Helpers +~~~~~~~~~~~~~~~~~ + --bisect:: Limit output to the one commit object which is roughly halfway between @@ -341,7 +461,6 @@ after all the sorted commit objects, there will be the same text as if `--bisect-vars` had been used alone. endif::git-rev-list[] --- Commit Ordering ~~~~~~~~~~~~~~~ From e41352b24e29eba43d00a3fd117befaef1d594bc Mon Sep 17 00:00:00 2001 From: Marcus Griep Date: Tue, 12 Aug 2008 12:00:18 -0400 Subject: [PATCH 47/73] Git.pm: Add faculties to allow temp files to be cached This patch offers a generic interface to allow temp files to be cached while using an instance of the 'Git' package. If many temp files are created and destroyed during the execution of a program, this caching mechanism can help reduce the amount of files created and destroyed by the filesystem. The temp_acquire method provides a weak guarantee that a temp file will not be stolen by subsequent requests. If a file is locked when another acquire request is made, a simple error is thrown. Signed-off-by: Marcus Griep Acked-by: Eric Wong --- perl/Git.pm | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 2 deletions(-) diff --git a/perl/Git.pm b/perl/Git.pm index e1ca5b4a22..405f68fc39 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -57,7 +57,8 @@ require Exporter; command_output_pipe command_input_pipe command_close_pipe command_bidi_pipe command_close_bidi_pipe version exec_path hash_object git_cmd_try - remote_refs); + remote_refs + temp_acquire temp_release temp_reset); =head1 DESCRIPTION @@ -99,7 +100,9 @@ use Carp qw(carp croak); # but croak is bad - throw instead use Error qw(:try); use Cwd qw(abs_path); use IPC::Open2 qw(open2); - +use File::Temp (); +require File::Spec; +use Fcntl qw(SEEK_SET SEEK_CUR); } @@ -933,6 +936,124 @@ sub _close_cat_blob { delete @$self{@vars}; } + +{ # %TEMP_* Lexical Context + +my (%TEMP_LOCKS, %TEMP_FILES); + +=item temp_acquire ( NAME ) + +Attempts to retreive the temporary file mapped to the string C. If an +associated temp file has not been created this session or was closed, it is +created, cached, and set for autoflush and binmode. + +Internally locks the file mapped to C. This lock must be released with +C when the temp file is no longer needed. Subsequent attempts +to retrieve temporary files mapped to the same C while still locked will +cause an error. This locking mechanism provides a weak guarantee and is not +threadsafe. It does provide some error checking to help prevent temp file refs +writing over one another. + +In general, the L returned should not be closed by consumers as +it defeats the purpose of this caching mechanism. If you need to close the temp +file handle, then you should use L or another temp file faculty +directly. If a handle is closed and then requested again, then a warning will +issue. + +=cut + +sub temp_acquire { + my ($self, $name) = _maybe_self(@_); + + my $temp_fd = _temp_cache($name); + + $TEMP_LOCKS{$temp_fd} = 1; + $temp_fd; +} + +=item temp_release ( NAME ) + +=item temp_release ( FILEHANDLE ) + +Releases a lock acquired through C. Can be called either with +the C mapping used when acquiring the temp file or with the C +referencing a locked temp file. + +Warns if an attempt is made to release a file that is not locked. + +The temp file will be truncated before being released. This can help to reduce +disk I/O where the system is smart enough to detect the truncation while data +is in the output buffers. Beware that after the temp file is released and +truncated, any operations on that file may fail miserably until it is +re-acquired. All contents are lost between each release and acquire mapped to +the same string. + +=cut + +sub temp_release { + my ($self, $temp_fd, $trunc) = _maybe_self(@_); + + if (ref($temp_fd) ne 'File::Temp') { + $temp_fd = $TEMP_FILES{$temp_fd}; + } + unless ($TEMP_LOCKS{$temp_fd}) { + carp "Attempt to release temp file '", + $temp_fd, "' that has not been locked"; + } + temp_reset($temp_fd) if $trunc and $temp_fd->opened; + + $TEMP_LOCKS{$temp_fd} = 0; + undef; +} + +sub _temp_cache { + my ($name) = @_; + + my $temp_fd = \$TEMP_FILES{$name}; + if (defined $$temp_fd and $$temp_fd->opened) { + if ($TEMP_LOCKS{$$temp_fd}) { + throw Error::Simple("Temp file with moniker '", + $name, "' already in use"); + } + } else { + if (defined $$temp_fd) { + # then we're here because of a closed handle. + carp "Temp file '", $name, + "' was closed. Opening replacement."; + } + $$temp_fd = File::Temp->new( + TEMPLATE => 'Git_XXXXXX', + DIR => File::Spec->tmpdir + ) or throw Error::Simple("couldn't open new temp file"); + $$temp_fd->autoflush; + binmode $$temp_fd; + } + $$temp_fd; +} + +=item temp_reset ( FILEHANDLE ) + +Truncates and resets the position of the C. + +=cut + +sub temp_reset { + my ($self, $temp_fd) = _maybe_self(@_); + + truncate $temp_fd, 0 + or throw Error::Simple("couldn't truncate file"); + sysseek($temp_fd, 0, SEEK_SET) and seek($temp_fd, 0, SEEK_SET) + or throw Error::Simple("couldn't seek to beginning of file"); + sysseek($temp_fd, 0, SEEK_CUR) == 0 and tell($temp_fd) == 0 + or throw Error::Simple("expected file position to be reset"); +} + +sub END { + unlink values %TEMP_FILES if %TEMP_FILES; +} + +} # %TEMP_* Lexical Context + =back =head1 ERROR HANDLING From 0b19138ba3e4c129770565d364df65ec25ca0a8e Mon Sep 17 00:00:00 2001 From: Marcus Griep Date: Tue, 12 Aug 2008 12:00:53 -0400 Subject: [PATCH 48/73] git-svn: Make it incrementally faster by minimizing temp files Currently, git-svn would create a temp file on four occasions: 1. Reading a blob out of the object db 2. Creating a delta from svn 3. Hashing and writing a blob into the object db 4. Reading a blob out of the object db (in another place in code) Any time git-svn did the above, it would dutifully create and then delete said temp file. Unfortunately, this means that between 2-4 temporary files are created/deleted per file 'add/modify'-ed in svn (O(n)). This causes significant overhead and helps the inode counter to spin beautifully. By its nature, git-svn is a serial beast. Thus, reusing a temp file does not pose significant problems. "truncate and seek" takes much less time than "unlink and create". This patch centralizes the tempfile creation and holds onto the tempfile until they are deleted on exit. This significantly reduces file overhead, now requiring at most three (3) temp files per run (O(1)). Signed-off-by: Marcus Griep Acked-by: Eric Wong --- git-svn.perl | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index 4dc33801a8..9eae5e8d89 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1265,7 +1265,7 @@ sub md5sum { my $arg = shift; my $ref = ref $arg; my $md5 = Digest::MD5->new(); - if ($ref eq 'GLOB' || $ref eq 'IO::File') { + if ($ref eq 'GLOB' || $ref eq 'IO::File' || $ref eq 'File::Temp') { $md5->addfile($arg) or croak $!; } elsif ($ref eq 'SCALAR') { $md5->add($$arg) or croak $!; @@ -1328,6 +1328,7 @@ BEGIN { } } + my (%LOCKFILES, %INDEX_FILES); END { unlink keys %LOCKFILES if %LOCKFILES; @@ -3230,13 +3231,11 @@ sub change_file_prop { sub apply_textdelta { my ($self, $fb, $exp) = @_; - my $fh = IO::File->new_tmpfile; - $fh->autoflush(1); + my $fh = Git::temp_acquire('svn_delta'); # $fh gets auto-closed() by SVN::TxDelta::apply(), # (but $base does not,) so dup() it for reading in close_file open my $dup, '<&', $fh or croak $!; - my $base = IO::File->new_tmpfile; - $base->autoflush(1); + my $base = Git::temp_acquire('git_blob'); if ($fb->{blob}) { print $base 'link ' if ($fb->{mode_a} == 120000); my $size = $::_repository->cat_blob($fb->{blob}, $base); @@ -3251,9 +3250,9 @@ sub apply_textdelta { } } seek $base, 0, 0 or croak $!; - $fb->{fh} = $dup; + $fb->{fh} = $fh; $fb->{base} = $base; - [ SVN::TxDelta::apply($base, $fh, undef, $fb->{path}, $fb->{pool}) ]; + [ SVN::TxDelta::apply($base, $dup, undef, $fb->{path}, $fb->{pool}) ]; } sub close_file { @@ -3282,22 +3281,25 @@ sub close_file { } } - my ($tmp_fh, $tmp_filename) = File::Temp::tempfile(UNLINK => 1); + my $tmp_fh = Git::temp_acquire('svn_hash'); my $result; while ($result = sysread($fh, my $string, 1024)) { my $wrote = syswrite($tmp_fh, $string, $result); defined($wrote) && $wrote == $result - or croak("write $tmp_filename: $!\n"); + or croak("write ", + $tmp_fh->filename, ": $!\n"); } defined $result or croak $!; - close $tmp_fh or croak $!; - close $fh or croak $!; - $hash = $::_repository->hash_and_insert_object($tmp_filename); - unlink($tmp_filename); + Git::temp_release($fh, 1); + + $hash = $::_repository->hash_and_insert_object( + $tmp_fh->filename); $hash =~ /^[a-f\d]{40}$/ or die "not a sha1: $hash\n"; - close $fb->{base} or croak $!; + + Git::temp_release($fb->{base}, 1); + Git::temp_release($tmp_fh, 1); } else { $hash = $fb->{blob} or die "no blob information\n"; } @@ -3667,7 +3669,7 @@ sub chg_file { } elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) { $self->change_file_prop($fbat,'svn:executable',undef); } - my $fh = IO::File->new_tmpfile or croak $!; + my $fh = Git::temp_acquire('git_blob'); if ($m->{mode_b} =~ /^120/) { print $fh 'link ' or croak $!; $self->change_file_prop($fbat,'svn:special','*'); @@ -3686,9 +3688,8 @@ sub chg_file { my $atd = $self->apply_textdelta($fbat, undef, $pool); my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool); die "Checksum mismatch\nexpected: $exp\ngot: $got\n" if ($got ne $exp); + Git::temp_release($fh, 1); $pool->clear; - - close $fh or croak $!; } sub D { From 510b0945d041752db2f53dda00f1188308e2df4e Mon Sep 17 00:00:00 2001 From: Marcus Griep Date: Tue, 12 Aug 2008 12:45:39 -0400 Subject: [PATCH 49/73] git-svn: Reduce temp file usage when dealing with non-links Currently, in sub 'close_file', git-svn creates a temporary file and copies the contents of the blob to be written into it. This is useful for symlinks because svn stores symlinks in the form: link $FILE_PATH Git creates a blob only out of '$FILE_PATH' and uses file mode to indicate that the blob should be interpreted as a symlink. As git-hash-object is invoked with --stdin-paths, a duplicate of the link from svn must be created that leaves off the first five bytes, i.e. 'link '. However, this is wholly unnecessary for normal blobs, though, as we already have a temp file with their contents. Copying the entire file gains nothing, and effectively requires a file to be written twice before making it into the object db. This patch corrects that issue, holding onto the substr-like duplication for symlinks, but skipping it altogether for normal blobs by reusing the existing temp file. Signed-off-by: Marcus Griep Acked-by: Eric Wong --- git-svn.perl | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index 9eae5e8d89..099fd02b3f 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3268,38 +3268,36 @@ sub close_file { "expected: $exp\n got: $got\n"; } } - sysseek($fh, 0, 0) or croak $!; if ($fb->{mode_b} == 120000) { - eval { - sysread($fh, my $buf, 5) == 5 or croak $!; - $buf eq 'link ' or die "$path has mode 120000", - " but is not a link"; - }; - if ($@) { - warn "$@\n"; - sysseek($fh, 0, 0) or croak $!; + sysseek($fh, 0, 0) or croak $!; + sysread($fh, my $buf, 5) == 5 or croak $!; + + unless ($buf eq 'link ') { + warn "$path has mode 120000", + " but is not a link\n"; + } else { + my $tmp_fh = Git::temp_acquire('svn_hash'); + my $res; + while ($res = sysread($fh, my $str, 1024)) { + my $out = syswrite($tmp_fh, $str, $res); + defined($out) && $out == $res + or croak("write ", + $tmp_fh->filename, + ": $!\n"); + } + defined $res or croak $!; + + ($fh, $tmp_fh) = ($tmp_fh, $fh); + Git::temp_release($tmp_fh, 1); } } - my $tmp_fh = Git::temp_acquire('svn_hash'); - my $result; - while ($result = sysread($fh, my $string, 1024)) { - my $wrote = syswrite($tmp_fh, $string, $result); - defined($wrote) && $wrote == $result - or croak("write ", - $tmp_fh->filename, ": $!\n"); - } - defined $result or croak $!; - - - Git::temp_release($fh, 1); - $hash = $::_repository->hash_and_insert_object( - $tmp_fh->filename); + $fh->filename); $hash =~ /^[a-f\d]{40}$/ or die "not a sha1: $hash\n"; Git::temp_release($fb->{base}, 1); - Git::temp_release($tmp_fh, 1); + Git::temp_release($fh, 1); } else { $hash = $fb->{blob} or die "no blob information\n"; } From 9612e74342cfd38c0b83230a2c847cd070599a5a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 11 Aug 2008 11:46:56 -0700 Subject: [PATCH 50/73] Do not talk about "diff" in rev-list documentation. Since 8c02eee (git-rev-list(1): group options; reformat; document more options, 2006-09-01), git-rev-list documentation talks as if it supports any kind of diff output. It doesn't. Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index c953d1cac5..abf34204db 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -90,6 +90,7 @@ you would get an output line this: This implies the '--topo-order' option by default, but the '--date-order' option may also be specified. +ifndef::git-rev-list[] Diff Formatting ~~~~~~~~~~~~~~~ @@ -119,6 +120,7 @@ options may be given. See linkgit:git-diff-files[1] for more options. -t:: Show the tree objects in the diff output. This implies '-r'. +endif::git-rev-list[] Commit Limiting ~~~~~~~~~~~~~~~ From 65f59e2998c7dd87f61b25fa41bba72fd4247901 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 12 Aug 2008 21:42:22 -0700 Subject: [PATCH 51/73] GIT 1.6.0-rc3 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.0.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/RelNotes-1.6.0.txt b/Documentation/RelNotes-1.6.0.txt index e3c0c1d88d..9e2e417ef7 100644 --- a/Documentation/RelNotes-1.6.0.txt +++ b/Documentation/RelNotes-1.6.0.txt @@ -178,7 +178,7 @@ Updates since v1.5.6 * git-diff --check now checks leftover merge conflict markers. * "git-diff -p" learned to grab a better hunk header lines in - Pascal/Delphi and Ruby source files, and also pays attention to + BibTex, Pascal/Delphi, and Ruby files and also pays attention to chapter and part boundary in TeX documents. * When remote side used to have branch 'foo' and git-fetch finds that now @@ -254,6 +254,6 @@ this release, unless otherwise noted. --- exec >/var/tmp/1 -O=v1.6.0-rc2-21-g0bb3a0b +O=v1.6.0-rc3 echo O=$(git describe refs/heads/master) git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint From 71d9451e061841ed5acb576652e09df32c700b86 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Wed, 13 Aug 2008 23:41:23 +0200 Subject: [PATCH 52/73] rebase -i -p: handle index and workdir correctly 'git rebase -i -p' forgot to update the index and working directory during fast forwards. Fix this. Makes 'GIT_EDITOR=true rebase -i -p ' a no-op again. Also, it attempted to do a fast forward even if it was instructed not to commit (via -n). Fall back to the cherry-pick code path and let that handle the issue for us. Signed-off-by: Thomas Rast --- git-rebase--interactive.sh | 14 ++++++++++++-- t/t3404-rebase-interactive.sh | 6 ++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 4e334ba41d..58126bd80c 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -145,7 +145,16 @@ pick_one () { } pick_one_preserving_merges () { - case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac + fast_forward=t + case "$1" in + -n) + fast_forward=f + sha1=$2 + ;; + *) + sha1=$1 + ;; + esac sha1=$(git rev-parse $sha1) if test -f "$DOTEST"/current-commit @@ -157,7 +166,6 @@ pick_one_preserving_merges () { fi # rewrite parents; if none were rewritten, we can fast-forward. - fast_forward=t preserve=t new_parents= for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-) @@ -182,6 +190,8 @@ pick_one_preserving_merges () { t) output warn "Fast forward to $sha1" test $preserve = f || echo $sha1 > "$REWRITTEN"/$sha1 + output git reset --hard $sha1 || + die "Cannot fast forward to $sha1" ;; f) test "a$1" = a-n && die "Refusing to squash a merge: $sha1" diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index ffe3dd97b7..4d62b9af83 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -202,6 +202,9 @@ test_expect_success 'retain authorship when squashing' ' test_expect_success '-p handles "no changes" gracefully' ' HEAD=$(git rev-parse HEAD) && git rebase -i -p HEAD^ && + git update-index --refresh && + git diff-files --quiet && + git diff-index --quiet --cached HEAD -- && test $HEAD = $(git rev-parse HEAD) ' @@ -235,6 +238,9 @@ test_expect_success 'preserve merges with -p' ' git checkout -b to-be-rebased && test_tick && git rebase -i -p --onto branch1 master && + git update-index --refresh && + git diff-files --quiet && + git diff-index --quiet --cached HEAD -- && test $(git rev-parse HEAD~6) = $(git rev-parse branch1) && test $(git rev-parse HEAD~4^2) = $(git rev-parse to-be-preserved) && test $(git rev-parse HEAD^^2^) = $(git rev-parse HEAD^^^) && From a96dc01e21603849cb454a311f18780c2e839f29 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Wed, 13 Aug 2008 23:41:24 +0200 Subject: [PATCH 53/73] rebase -i -p: fix parent rewriting The existing parent rewriting did not handle the case where a previous commit was amended (via edit or squash). Fix by always putting the new sha1 of the last commit into the $REWRITTEN map. Signed-off-by: Thomas Rast --- git-rebase--interactive.sh | 6 ++---- t/t3404-rebase-interactive.sh | 12 ++++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 58126bd80c..929d681c47 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -165,14 +165,14 @@ pick_one_preserving_merges () { die "Cannot write current commit's replacement sha1" fi + echo $sha1 > "$DOTEST"/current-commit + # rewrite parents; if none were rewritten, we can fast-forward. - preserve=t new_parents= for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-) do if test -f "$REWRITTEN"/$p then - preserve=f new_p=$(cat "$REWRITTEN"/$p) test $p != $new_p && fast_forward=f case "$new_parents" in @@ -189,7 +189,6 @@ pick_one_preserving_merges () { case $fast_forward in t) output warn "Fast forward to $sha1" - test $preserve = f || echo $sha1 > "$REWRITTEN"/$sha1 output git reset --hard $sha1 || die "Cannot fast forward to $sha1" ;; @@ -201,7 +200,6 @@ pick_one_preserving_merges () { output git checkout $first_parent 2> /dev/null || die "Cannot move HEAD to $first_parent" - echo $sha1 > "$DOTEST"/current-commit case "$new_parents" in ' '*' '*) # redo merge diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 4d62b9af83..5aa487ac02 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -250,6 +250,18 @@ test_expect_success 'preserve merges with -p' ' test $(git show HEAD:unrelated-file) = 1 ' +test_expect_success 'edit ancestor with -p' ' + FAKE_LINES="1 edit 2 3 4" git rebase -i -p HEAD~3 && + echo 2 > unrelated-file && + test_tick && + git commit -m L2-modified --amend unrelated-file && + git rebase --continue && + git update-index --refresh && + git diff-files --quiet && + git diff-index --quiet --cached HEAD -- && + test $(git show HEAD:unrelated-file) = 2 +' + test_expect_success '--continue tries to commit' ' test_tick && test_must_fail git rebase -i --onto new-branch1 HEAD^ && From ea335b56d44a92b9b8be40b1465d7df65a4f736b Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 13 Aug 2008 15:34:34 -0700 Subject: [PATCH 54/73] Fix escaping of glob special characters in pathspecs match_one implements an optimized pathspec match where it only uses fnmatch if it detects glob special characters in the pattern. Unfortunately it didn't treat \ as a special character, so attempts to escape a glob special character would fail even though fnmatch() supports it. Signed-off-by: Kevin Ballard Signed-off-by: Junio C Hamano --- dir.c | 2 +- t/t3700-add.sh | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dir.c b/dir.c index 29d1d5ba31..109e05b013 100644 --- a/dir.c +++ b/dir.c @@ -54,7 +54,7 @@ int common_prefix(const char **pathspec) static inline int special_char(unsigned char c1) { - return !c1 || c1 == '*' || c1 == '[' || c1 == '?'; + return !c1 || c1 == '*' || c1 == '[' || c1 == '?' || c1 == '\\'; } /* diff --git a/t/t3700-add.sh b/t/t3700-add.sh index e83fa1f689..fcbc203e71 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -222,4 +222,12 @@ test_expect_success 'git add (add.ignore-errors = false)' ' ! ( git ls-files foo1 | grep foo1 ) ' +test_expect_success 'git add '\''fo\?bar'\'' ignores foobar' ' + git reset --hard && + touch fo\?bar foobar && + git add '\''fo\?bar'\'' && + git ls-files fo\?bar | grep -F fo\?bar && + ! ( git ls-files foobar | grep foobar ) +' + test_done From 8caa3acf3a5f660b6b4c01fe23c05094140795d6 Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Wed, 13 Aug 2008 19:48:57 -0500 Subject: [PATCH 55/73] test-parse-options: use appropriate cast in length_callback OPT_CALLBACK() is passed &integer which is now an "int" rather than "unsigned long". Update the length_callback function. Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- test-parse-options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-parse-options.c b/test-parse-options.c index 6e18083a7d..61d2c39814 100644 --- a/test-parse-options.c +++ b/test-parse-options.c @@ -15,7 +15,7 @@ int length_callback(const struct option *opt, const char *arg, int unset) if (unset) return 1; /* do not support unset */ - *(unsigned long *)opt->value = strlen(arg); + *(int *)opt->value = strlen(arg); return 0; } From 21926fe885aa6579f7aa0e89fcb6a9064f8aa516 Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Wed, 13 Aug 2008 19:49:30 -0500 Subject: [PATCH 56/73] t5304-prune: adjust file mtime based on system time rather than file mtime test-chmtime can adjust the mtime of a file based on the file's mtime, or based on the system time. For files accessed over NFS, the file's mtime is set by the NFS server, and as such may vary a great deal from the NFS client's system time if the clocks of the client and server are out of sync. Since these tests are testing the expire feature of git-prune, an incorrect mtime could cause a file to be expired or not expired incorrectly and produce a test failure. Avoid this NFS pitfall by modifying the calls to test-chmtime so that the mtime is adjusted based on the system time, rather than the file's mtime. Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- t/t5304-prune.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index 9fd9d07000..771c0a06a4 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -21,7 +21,7 @@ test_expect_success 'prune stale packs' ' orig_pack=$(echo .git/objects/pack/*.pack) && : > .git/objects/tmp_1.pack && : > .git/objects/tmp_2.pack && - test-chmtime -86501 .git/objects/tmp_1.pack && + test-chmtime =-86501 .git/objects/tmp_1.pack && git prune --expire 1.day && test -f $orig_pack && test -f .git/objects/tmp_2.pack && @@ -39,7 +39,7 @@ test_expect_success 'prune --expire' ' git prune --expire=1.hour.ago && test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && test -f $BLOB_FILE && - test-chmtime -86500 $BLOB_FILE && + test-chmtime =-86500 $BLOB_FILE && git prune --expire 1.day && test $before = $(git count-objects | sed "s/ .*//") && ! test -f $BLOB_FILE @@ -53,11 +53,11 @@ test_expect_success 'gc: implicit prune --expire' ' BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") && test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && test -f $BLOB_FILE && - test-chmtime -$((86400*14-30)) $BLOB_FILE && + test-chmtime =-$((86400*14-30)) $BLOB_FILE && git gc && test $((1 + $before)) = $(git count-objects | sed "s/ .*//") && test -f $BLOB_FILE && - test-chmtime -$((86400*14+1)) $BLOB_FILE && + test-chmtime =-$((86400*14+1)) $BLOB_FILE && git gc && test $before = $(git count-objects | sed "s/ .*//") && ! test -f $BLOB_FILE From 7950659dc9ef7f2b50b18010622299c508bfdfc3 Mon Sep 17 00:00:00 2001 From: Eric Raible Date: Thu, 14 Aug 2008 10:12:54 -0700 Subject: [PATCH 57/73] bash completion: 'git apply' should use 'fix' not 'strip' Bring completion up to date with the man page. Signed-off-by: Eric Raible Acked-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 78189c1b7b..d1afe96e1c 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -501,7 +501,7 @@ __git_has_doubledash () return 1 } -__git_whitespacelist="nowarn warn error error-all strip" +__git_whitespacelist="nowarn warn error error-all fix" _git_am () { From f491239170cb1463c7c3cd970862d6de636ba787 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Thu, 14 Aug 2008 13:37:41 -0400 Subject: [PATCH 58/73] git format-patch documentation: clarify what --cover-letter does Signed-off-by: Matt McCutchen Signed-off-by: Junio C Hamano --- Documentation/git-format-patch.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 010d9e4322..adb4ea7b1b 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -147,9 +147,9 @@ include::diff-options.txt[] to any configured headers, and may be used multiple times. --cover-letter:: - Generate a cover letter template. You still have to fill in - a description, but the shortlog and the diffstat will be - generated for you. + In addition to the patches, generate a cover letter file + containing the shortlog and the overall diffstat. You can + fill in a description in the file before sending it out. --suffix=.:: Instead of using `.patch` as the suffix for generated From b4c72162f6612ce335af79ef19c5ae16f5585e67 Mon Sep 17 00:00:00 2001 From: Lee Marlow Date: Thu, 14 Aug 2008 16:41:10 -0600 Subject: [PATCH 59/73] bash completion: Add completion for 'git mergetool' The --tool= long option to "git mergetool" can be completed with: kdiff3 tkdiff meld xxdiff emerge vimdiff gvimdiff ecmerge opendiff Signed-off-by: Lee Marlow Acked-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index d1afe96e1c..2f8036d1d9 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1001,6 +1001,25 @@ _git_merge () __gitcomp "$(__git_refs)" } +_git_mergetool () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + --tool=*) + __gitcomp " + kdiff3 tkdiff meld xxdiff emerge + vimdiff gvimdiff ecmerge opendiff + " "" "${cur##--tool=}" + return + ;; + --*) + __gitcomp "--tool=" + return + ;; + esac + COMPREPLY=() +} + _git_merge_base () { __gitcomp "$(__git_refs)" @@ -1650,6 +1669,7 @@ _git () ls-remote) _git_ls_remote ;; ls-tree) _git_ls_tree ;; merge) _git_merge;; + mergetool) _git_mergetool;; merge-base) _git_merge_base ;; mv) _git_mv ;; name-rev) _git_name_rev ;; From 5a13c8f6f7ef7463ddaa3dd7144bf66af4fcd9be Mon Sep 17 00:00:00 2001 From: Lee Marlow Date: Thu, 14 Aug 2008 16:41:11 -0600 Subject: [PATCH 60/73] bash completion: Add '--merge' long option for 'git log' Signed-off-by: Lee Marlow Acked-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 2f8036d1d9..c0bf7aade6 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -972,6 +972,7 @@ _git_log () --decorate --diff-filter= --color-words --walk-reflogs --parents --children --full-history + --merge " return ;; From d9429194f6e30e1f6f46a286217cd88972e1c83b Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Thu, 14 Aug 2008 23:40:38 +0100 Subject: [PATCH 61/73] Add p4 read_pipe and write_pipe wrappers Two additional wrappers to cover 3 places where we utilise p4 in piped form. Found by Tor Arvid Lund. Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 6c64224b77..3e9df70f29 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -69,6 +69,10 @@ def write_pipe(c, str): return val +def p4_write_pipe(c, str): + real_cmd = p4_build_cmd(c) + return write_pipe(c, str) + def read_pipe(c, ignore_error=False): if verbose: sys.stderr.write('Reading pipe: %s\n' % c) @@ -80,6 +84,9 @@ def read_pipe(c, ignore_error=False): return val +def p4_read_pipe(c, ignore_error=False): + real_cmd = p4_build_cmd(c) + return read_pipe(real_cmd, ignore_error) def read_pipe_lines(c): if verbose: From a7d3ef9d099ab00a19595bc3ca8abdc1fc6ff35d Mon Sep 17 00:00:00 2001 From: Anand Kumria Date: Thu, 14 Aug 2008 23:40:39 +0100 Subject: [PATCH 62/73] Utilise our new p4_read_pipe and p4_write_pipe wrappers Signed-off-by: Anand Kumria Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 3e9df70f29..12fa9d3fd8 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -141,7 +141,7 @@ def setP4ExecBit(file, mode): def getP4OpenedType(file): # Returns the perforce file type for the given file. - result = read_pipe("p4 opened %s" % file) + result = p4_read_pipe("opened %s" % file) match = re.match(".*\((.+)\)\r?$", result) if match: return match.group(1) @@ -681,7 +681,7 @@ class P4Submit(Command): submitTemplate = self.prepareLogMessage(template, logMessage) if os.environ.has_key("P4DIFF"): del(os.environ["P4DIFF"]) - diff = read_pipe("p4 diff -du ...") + diff = p4_read_pipe("diff -du ...") newdiff = "" for newFile in filesToAdd: @@ -719,7 +719,7 @@ class P4Submit(Command): if self.isWindows: submitTemplate = submitTemplate.replace("\r\n", "\n") - write_pipe("p4 submit -i", submitTemplate) + p4_write_pipe("submit -i", submitTemplate) else: fileName = "submit.txt" file = open(fileName, "w+") From 8134a003e06b5f216cdc1f14acc70d8cab284cf9 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Fri, 15 Aug 2008 09:32:30 +0200 Subject: [PATCH 63/73] Fix t3700 on filesystems which do not support question marks in names Use square brackets instead. And the prominent example of the deficiency are, as usual, the filesystems of Microsoft house. Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- t/t3700-add.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 77a782c9ad..2ac93a346d 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -222,11 +222,11 @@ test_expect_success 'git add (add.ignore-errors = false)' ' ! ( git ls-files foo1 | grep foo1 ) ' -test_expect_success 'git add '\''fo\?bar'\'' ignores foobar' ' +test_expect_success 'git add '\''fo\[ou\]bar'\'' ignores foobar' ' git reset --hard && - touch fo\?bar foobar && - git add '\''fo\?bar'\'' && - git ls-files fo\?bar | grep -F fo\?bar && + touch fo\[ou\]bar foobar && + git add '\''fo\[ou\]bar'\'' && + git ls-files fo\[ou\]bar | grep -F fo\[ou\]bar && ! ( git ls-files foobar | grep foobar ) ' From 2946cccfdf2fba591b6af61ad6e658bb927832af Mon Sep 17 00:00:00 2001 From: Marcus Griep Date: Fri, 15 Aug 2008 13:59:28 -0400 Subject: [PATCH 64/73] bash-completion: Add non-command git help files to bash-completion Git allows access to the gitattributes man page via `git help attributes`, but this is not discoverable via the bash-completion mechanism. This patch adds all current non-command man pages to the completion candidate list. Signed-off-by: Marcus Griep Acked-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index c0bf7aade6..158b912841 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -885,7 +885,11 @@ _git_help () return ;; esac - __gitcomp "$(__git_all_commands)" + __gitcomp "$(__git_all_commands) + attributes cli core-tutorial cvs-migration + diffcore gitk glossary hooks ignore modules + repository-layout tutorial tutorial-2 + " } _git_init () From cb3a160d604866331fdb0f5078face4ab2a4b49a Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Sat, 9 Aug 2008 01:28:54 +0200 Subject: [PATCH 65/73] git-am: ignore --binary option The git-apply documentation says that --binary is a historical option. This patch lets git-am ignore --binary and removes advertisements of this option. Signed-off-by: Stephan Beyer Signed-off-by: Junio C Hamano --- Documentation/git-am.txt | 7 +------ git-am.sh | 19 +++++++------------ t/t0023-crlf-am.sh | 2 +- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index c45c53ec24..b9c6fac748 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git am' [--signoff] [--keep] [--utf8 | --no-utf8] - [--3way] [--interactive] [--binary] + [--3way] [--interactive] [--whitespace=