* [PATCH 1/6] remote.c: simplify a bit of code using git_config_string()
From: Ramkumar Ramachandra @ 2013-03-20 12:44 UTC (permalink / raw)
To: Git List; +Cc: Junio C Hamano, Jeff King, Eric Sunshine, Jonathan Nieder
In-Reply-To: <1363783501-27981-1-git-send-email-artagnon@gmail.com>
A small segment where handle_config() parses the branch.remote
configuration variable can be simplified using git_config_string().
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
remote.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/remote.c b/remote.c
index e53a6eb..45b69d6 100644
--- a/remote.c
+++ b/remote.c
@@ -356,9 +356,7 @@ static int handle_config(const char *key, const char *value, void *cb)
return 0;
branch = make_branch(name, subkey - name);
if (!strcmp(subkey, ".remote")) {
- if (!value)
- return config_error_nonbool(key);
- branch->remote_name = xstrdup(value);
+ git_config_string(&branch->remote_name, key, value);
if (branch == current_branch) {
default_remote_name = branch->remote_name;
explicit_default_remote_name = 1;
--
1.8.2
^ permalink raw reply related
* [PATCH 2/6] t5516 (fetch-push): update test description
From: Ramkumar Ramachandra @ 2013-03-20 12:44 UTC (permalink / raw)
To: Git List; +Cc: Junio C Hamano, Jeff King, Eric Sunshine, Jonathan Nieder
In-Reply-To: <1363783501-27981-1-git-send-email-artagnon@gmail.com>
The file was originally created in bcdb34f (Test wildcard push/fetch,
2007-06-08), and only contained tests that exercised wildcard
functionality at the time. In subsequent commits, many other tests
unrelated to wildcards were added but the test description was never
updated. Fix this.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
t/t5516-fetch-push.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index c31e5c1..bfeec60 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='fetching and pushing, with or without wildcard'
+test_description='fetching and pushing'
. ./test-lib.sh
--
1.8.2
^ permalink raw reply related
* [PATCH v2 0/6] Support triangular workflows
From: Ramkumar Ramachandra @ 2013-03-20 12:44 UTC (permalink / raw)
To: Git List; +Cc: Junio C Hamano, Jeff King, Eric Sunshine, Jonathan Nieder
This follows-up [1], with three important differences:
1. pushremote_get() and remote_get() share code better. Thanks Jeff.
2. All spelling mistakes have been corrected. Thanks Eric.
3. One new test for each of the new configuration variables. The
extra two parts [2/6] and [3/6] preprare the file for introducing
tests. However, I've not gone overboard in this preparation; I don't
replicate the work done by Jonathan in [2].
Thanks for reading.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/218410
[2]: http://thread.gmane.org/gmane.comp.version-control.git/218451/focus=218465
Ramkumar Ramachandra (6):
remote.c: simplify a bit of code using git_config_string()
t5516 (fetch-push): update test description
t5516 (fetch-push): introduce mk_test_with_name()
remote.c: introduce a way to have different remotes for fetch/push
remote.c: introduce remote.pushdefault
remote.c: introduce branch.<name>.pushremote
Documentation/config.txt | 23 +++++++++++++++---
builtin/push.c | 2 +-
remote.c | 36 +++++++++++++++++++++------
remote.h | 1 +
t/t5516-fetch-push.sh | 63 ++++++++++++++++++++++++++++++++++++++++--------
5 files changed, 104 insertions(+), 21 deletions(-)
--
1.8.2
^ permalink raw reply
* Re: [PATCH v3 0/5] nd/branch-show-rebase-bisect-state updates
From: Duy Nguyen @ 2013-03-20 12:40 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Matthieu Moy, Jonathan Niedier
In-Reply-To: <7vhak7i6ch.fsf@alter.siamese.dyndns.org>
On Wed, Mar 20, 2013 at 1:37 AM, Junio C Hamano <gitster@pobox.com> wrote:
> I was running "git bisect start pu jch" (jch is a branch I do not
> push out everywhere that is somewhere in the middle of
> "master..pu"), and then after bisection finished, saw this:
>
> $ git branch --with 66887099e096f0258a5ef3b1e7458748597bdffe
> * (no branch, bisecting jch)
> nd/magic-pathspecs
> pu
>
> which is obviously bogus. I only said "I know the tip of pu is bad
> and the tip of jch is good". If anything, I was bisecting the
> breakage in 'pu', not in 'jch'.
>
> I think the message should better say "before you started to bisect
> you were on 'jch'" or something instead.
How about
* (no branch, bisect started on jch)
then? I don't want to make it too long because it'll waste space in
column layout.
--
Duy
^ permalink raw reply
* Re: [PATCH] push: Alias pushurl from push rewrites
From: Rob Hoelz @ 2013-03-20 12:33 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jonathan Nieder, git, josh
In-Reply-To: <7vwqt3i7p9.fsf@alter.siamese.dyndns.org>
On 3/19/13 7:08 PM, Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>
>> Junio C Hamano wrote:
>>> Jonathan Nieder <jrnieder@gmail.com> writes:
>>>> Test nits:
>>>> ...
>>>> Hope that helps,
>>>>
>>>> Jonathan Nieder (3):
>>>> push test: use test_config where appropriate
>>>> push test: simplify check of push result
>>>> push test: rely on &&-chaining instead of 'if bad; then echo Oops; fi'
>>> Are these supposed to be follow-up patches? Preparatory steps that
>>> Rob can reroll on top? Something else?
>> Preparatory steps.
> OK, thanks. I'll queue these first then.
>
Should I apply these to my patch to move things along? What's the next
step for me?
Thanks,
Rob
^ permalink raw reply
* [PATCH] t3200 (branch): modernize style
From: Ramkumar Ramachandra @ 2013-03-20 12:30 UTC (permalink / raw)
To: Git List
Style is inconsistent throughout the file. Make the following
changes:
1. Indent everything with tabs.
2. Put the opening quote (') for the test in the same line as
test_expect_succcess, and the closing quote on a line by itself.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
Another random patch. Found it while grep'ping around. I thought I
could automate my work, which would have been the case if it was
consistently inconsistent. Unfortunately, it wasn't, and I ended up
doing a lot of manual janitorial work :|
t/t3200-branch.sh | 475 ++++++++++++++++++++++++++++--------------------------
1 file changed, 243 insertions(+), 232 deletions(-)
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index f3e0e4a..3203b15 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -7,20 +7,18 @@ test_description='git branch assorted tests'
. ./test-lib.sh
-test_expect_success \
- 'prepare a trivial repository' \
- 'echo Hello > A &&
- git update-index --add A &&
- git commit -m "Initial commit." &&
- echo World >> A &&
- git update-index --add A &&
- git commit -m "Second commit." &&
- HEAD=$(git rev-parse --verify HEAD)'
-
-test_expect_success \
- 'git branch --help should not have created a bogus branch' '
- test_might_fail git branch --help </dev/null >/dev/null 2>/dev/null &&
- test_path_is_missing .git/refs/heads/--help
+test_expect_success 'prepare a trivial repository' '
+ echo Hello > A &&
+ git update-index --add A &&
+ git commit -m "Initial commit." &&
+ echo World >> A &&
+ git update-index --add A &&
+ git commit -m "Second commit." &&
+ HEAD=$(git rev-parse --verify HEAD)'
+
+test_expect_success 'git branch --help should not have created a bogus branch' '
+ test_might_fail git branch --help </dev/null >/dev/null 2>/dev/null &&
+ test_path_is_missing .git/refs/heads/--help
'
test_expect_success 'branch -h in broken repository' '
@@ -34,63 +32,63 @@ test_expect_success 'branch -h in broken repository' '
test_i18ngrep "[Uu]sage" broken/usage
'
-test_expect_success \
- 'git branch abc should create a branch' \
- 'git branch abc && test_path_is_file .git/refs/heads/abc'
+test_expect_success 'git branch abc should create a branch' '
+ git branch abc && test_path_is_file .git/refs/heads/abc
+'
-test_expect_success \
- 'git branch a/b/c should create a branch' \
- 'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c'
+test_expect_success 'git branch a/b/c should create a branch' '
+ git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c
+'
cat >expect <<EOF
$_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
EOF
-test_expect_success \
- 'git branch -l d/e/f should create a branch and a log' \
- 'GIT_COMMITTER_DATE="2005-05-26 23:30" \
- git branch -l d/e/f &&
- test_path_is_file .git/refs/heads/d/e/f &&
- test_path_is_file .git/logs/refs/heads/d/e/f &&
- test_cmp expect .git/logs/refs/heads/d/e/f'
-
-test_expect_success \
- 'git branch -d d/e/f should delete a branch and a log' \
- 'git branch -d d/e/f &&
- test_path_is_missing .git/refs/heads/d/e/f &&
- test_path_is_missing .git/logs/refs/heads/d/e/f'
-
-test_expect_success \
- 'git branch j/k should work after branch j has been deleted' \
- 'git branch j &&
- git branch -d j &&
- git branch j/k'
-
-test_expect_success \
- 'git branch l should work after branch l/m has been deleted' \
- 'git branch l/m &&
- git branch -d l/m &&
- git branch l'
-
-test_expect_success \
- 'git branch -m dumps usage' \
- 'test_expect_code 128 git branch -m 2>err &&
- test_i18ngrep "too many branches for a rename operation" err'
-
-test_expect_success \
- 'git branch -m m m/m should work' \
- 'git branch -l m &&
- git branch -m m m/m &&
- test_path_is_file .git/logs/refs/heads/m/m'
-
-test_expect_success \
- 'git branch -m n/n n should work' \
- 'git branch -l n/n &&
+test_expect_success 'git branch -l d/e/f should create a branch and a log' '
+ GIT_COMMITTER_DATE="2005-05-26 23:30" \
+ git branch -l d/e/f &&
+ test_path_is_file .git/refs/heads/d/e/f &&
+ test_path_is_file .git/logs/refs/heads/d/e/f &&
+ test_cmp expect .git/logs/refs/heads/d/e/f
+'
+
+test_expect_success 'git branch -d d/e/f should delete a branch and a log' '
+ git branch -d d/e/f &&
+ test_path_is_missing .git/refs/heads/d/e/f &&
+ test_path_is_missing .git/logs/refs/heads/d/e/f
+'
+
+test_expect_success 'git branch j/k should work after branch j has been deleted' '
+ git branch j &&
+ git branch -d j &&
+ git branch j/k
+'
+
+test_expect_success 'git branch l should work after branch l/m has been deleted' '
+ git branch l/m &&
+ git branch -d l/m &&
+ git branch l
+'
+
+test_expect_success 'git branch -m dumps usage' '
+ test_expect_code 128 git branch -m 2>err &&
+ test_i18ngrep "too many branches for a rename operation" err
+'
+
+test_expect_success 'git branch -m m m/m should work' '
+ git branch -l m &&
+ git branch -m m m/m &&
+ test_path_is_file .git/logs/refs/heads/m/m
+'
+
+test_expect_success 'git branch -m n/n n should work' '
+ git branch -l n/n &&
git branch -m n/n n &&
- test_path_is_file .git/logs/refs/heads/n'
+ test_path_is_file .git/logs/refs/heads/n
+'
test_expect_success 'git branch -m o/o o should fail when o/p exists' '
git branch o/o &&
- git branch o/p &&
+ git branch o/p &&
test_must_fail git branch -m o/o o
'
@@ -248,19 +246,20 @@ mv .git/config-saved .git/config
git config branch.s/s.dummy Hello
-test_expect_success \
- 'git branch -m s/s s should work when s/t is deleted' \
- 'git branch -l s/s &&
+test_expect_success 'git branch -m s/s s should work when s/t is deleted' '
+ git branch -l s/s &&
test_path_is_file .git/logs/refs/heads/s/s &&
- git branch -l s/t &&
+ git branch -l s/t &&
test_path_is_file .git/logs/refs/heads/s/t &&
- git branch -d s/t &&
- git branch -m s/s s &&
- test_path_is_file .git/logs/refs/heads/s'
+ git branch -d s/t &&
+ git branch -m s/s s &&
+ test_path_is_file .git/logs/refs/heads/s
+'
-test_expect_success 'config information was renamed, too' \
- "test $(git config branch.s.dummy) = Hello &&
- test_must_fail git config branch.s/s/dummy"
+test_expect_success 'config information was renamed, too' '
+ test $(git config branch.s.dummy) = Hello &&
+ test_must_fail git config branch.s/s/dummy
+'
test_expect_success 'deleting a symref' '
git branch target &&
@@ -281,8 +280,7 @@ test_expect_success 'deleting a dangling symref' '
test_i18ncmp expect actual
'
-test_expect_success 'renaming a symref is not allowed' \
-'
+test_expect_success 'renaming a symref is not allowed' '
git symbolic-ref refs/heads/master2 refs/heads/master &&
test_must_fail git branch -m master2 master3 &&
git symbolic-ref refs/heads/master2 &&
@@ -290,146 +288,159 @@ test_expect_success 'renaming a symref is not allowed' \
test_path_is_missing .git/refs/heads/master3
'
-test_expect_success SYMLINKS \
- 'git branch -m u v should fail when the reflog for u is a symlink' '
- git branch -l u &&
- mv .git/logs/refs/heads/u real-u &&
- ln -s real-u .git/logs/refs/heads/u &&
- test_must_fail git branch -m u v
-'
-
-test_expect_success 'test tracking setup via --track' \
- 'git config remote.local.url . &&
- git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch --track my1 local/master &&
- test $(git config branch.my1.remote) = local &&
- test $(git config branch.my1.merge) = refs/heads/master'
-
-test_expect_success 'test tracking setup (non-wildcard, matching)' \
- 'git config remote.local.url . &&
- git config remote.local.fetch refs/heads/master:refs/remotes/local/master &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch --track my4 local/master &&
- test $(git config branch.my4.remote) = local &&
- test $(git config branch.my4.merge) = refs/heads/master'
-
-test_expect_success 'test tracking setup (non-wildcard, not matching)' \
- 'git config remote.local.url . &&
- git config remote.local.fetch refs/heads/s:refs/remotes/local/s &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch --track my5 local/master &&
- ! test "$(git config branch.my5.remote)" = local &&
- ! test "$(git config branch.my5.merge)" = refs/heads/master'
-
-test_expect_success 'test tracking setup via config' \
- 'git config branch.autosetupmerge true &&
- git config remote.local.url . &&
- git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch my3 local/master &&
- test $(git config branch.my3.remote) = local &&
- test $(git config branch.my3.merge) = refs/heads/master'
-
-test_expect_success 'test overriding tracking setup via --no-track' \
- 'git config branch.autosetupmerge true &&
- git config remote.local.url . &&
- git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch --no-track my2 local/master &&
- git config branch.autosetupmerge false &&
- ! test "$(git config branch.my2.remote)" = local &&
- ! test "$(git config branch.my2.merge)" = refs/heads/master'
-
-test_expect_success 'no tracking without .fetch entries' \
- 'git config branch.autosetupmerge true &&
- git branch my6 s &&
- git config branch.automsetupmerge false &&
- test -z "$(git config branch.my6.remote)" &&
- test -z "$(git config branch.my6.merge)"'
-
-test_expect_success 'test tracking setup via --track but deeper' \
- 'git config remote.local.url . &&
- git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
- (git show-ref -q refs/remotes/local/o/o || git fetch local) &&
- git branch --track my7 local/o/o &&
- test "$(git config branch.my7.remote)" = local &&
- test "$(git config branch.my7.merge)" = refs/heads/o/o'
-
-test_expect_success 'test deleting branch deletes branch config' \
- 'git branch -d my7 &&
- test -z "$(git config branch.my7.remote)" &&
- test -z "$(git config branch.my7.merge)"'
-
-test_expect_success 'test deleting branch without config' \
- 'git branch my7 s &&
- sha1=$(git rev-parse my7 | cut -c 1-7) &&
- echo "Deleted branch my7 (was $sha1)." >expect &&
- git branch -d my7 >actual 2>&1 &&
- test_i18ncmp expect actual'
-
-test_expect_success 'test --track without .fetch entries' \
- 'git branch --track my8 &&
- test "$(git config branch.my8.remote)" &&
- test "$(git config branch.my8.merge)"'
-
-test_expect_success \
- 'branch from non-branch HEAD w/autosetupmerge=always' \
- 'git config branch.autosetupmerge always &&
- git branch my9 HEAD^ &&
- git config branch.autosetupmerge false'
-
-test_expect_success \
- 'branch from non-branch HEAD w/--track causes failure' \
- 'test_must_fail git branch --track my10 HEAD^'
-
-test_expect_success \
- 'branch from tag w/--track causes failure' \
- 'git tag foobar &&
- test_must_fail git branch --track my11 foobar'
-
-test_expect_success 'use --set-upstream-to modify HEAD' \
- 'test_config branch.master.remote foo &&
- test_config branch.master.merge foo &&
- git branch my12
- git branch --set-upstream-to my12 &&
- test "$(git config branch.master.remote)" = "." &&
- test "$(git config branch.master.merge)" = "refs/heads/my12"'
-
-test_expect_success 'use --set-upstream-to modify a particular branch' \
- 'git branch my13
- git branch --set-upstream-to master my13 &&
- test "$(git config branch.my13.remote)" = "." &&
- test "$(git config branch.my13.merge)" = "refs/heads/master"'
-
-test_expect_success '--unset-upstream should fail if given a non-existent branch' \
- 'test_must_fail git branch --unset-upstream i-dont-exist'
-
-test_expect_success 'test --unset-upstream on HEAD' \
- 'git branch my14
- test_config branch.master.remote foo &&
- test_config branch.master.merge foo &&
- git branch --set-upstream-to my14 &&
- git branch --unset-upstream &&
- test_must_fail git config branch.master.remote &&
- test_must_fail git config branch.master.merge &&
- # fail for a branch without upstream set
- test_must_fail git branch --unset-upstream
-'
-
-test_expect_success 'test --unset-upstream on a particular branch' \
- 'git branch my15
- git branch --set-upstream-to master my14 &&
- git branch --unset-upstream my14 &&
- test_must_fail git config branch.my14.remote &&
- test_must_fail git config branch.my14.merge'
-
-test_expect_success '--set-upstream shows message when creating a new branch that exists as remote-tracking' \
- 'git update-ref refs/remotes/origin/master HEAD &&
- git branch --set-upstream origin/master 2>actual &&
- test_when_finished git update-ref -d refs/remotes/origin/master &&
- test_when_finished git branch -d origin/master &&
- cat >expected <<EOF &&
+test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for u is a symlink' '
+ git branch -l u &&
+ mv .git/logs/refs/heads/u real-u &&
+ ln -s real-u .git/logs/refs/heads/u &&
+ test_must_fail git branch -m u v
+'
+
+test_expect_success 'test tracking setup via --track' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --track my1 local/master &&
+ test $(git config branch.my1.remote) = local &&
+ test $(git config branch.my1.merge) = refs/heads/master
+'
+
+test_expect_success 'test tracking setup (non-wildcard, matching)' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/master:refs/remotes/local/master &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --track my4 local/master &&
+ test $(git config branch.my4.remote) = local &&
+ test $(git config branch.my4.merge) = refs/heads/master
+'
+
+test_expect_success 'test tracking setup (non-wildcard, not matching)' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/s:refs/remotes/local/s &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --track my5 local/master &&
+ ! test "$(git config branch.my5.remote)" = local &&
+ ! test "$(git config branch.my5.merge)" = refs/heads/master
+'
+
+test_expect_success 'test tracking setup via config' '
+ git config branch.autosetupmerge true &&
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch my3 local/master &&
+ test $(git config branch.my3.remote) = local &&
+ test $(git config branch.my3.merge) = refs/heads/master
+'
+
+test_expect_success 'test overriding tracking setup via --no-track' '
+ git config branch.autosetupmerge true &&
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --no-track my2 local/master &&
+ git config branch.autosetupmerge false &&
+ ! test "$(git config branch.my2.remote)" = local &&
+ ! test "$(git config branch.my2.merge)" = refs/heads/master
+'
+
+test_expect_success 'no tracking without .fetch entries' '
+ git config branch.autosetupmerge true &&
+ git branch my6 s &&
+ git config branch.automsetupmerge false &&
+ test -z "$(git config branch.my6.remote)" &&
+ test -z "$(git config branch.my6.merge)"
+'
+
+test_expect_success 'test tracking setup via --track but deeper' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/o/o || git fetch local) &&
+ git branch --track my7 local/o/o &&
+ test "$(git config branch.my7.remote)" = local &&
+ test "$(git config branch.my7.merge)" = refs/heads/o/o
+'
+
+test_expect_success 'test deleting branch deletes branch config' '
+ git branch -d my7 &&
+ test -z "$(git config branch.my7.remote)" &&
+ test -z "$(git config branch.my7.merge)"
+'
+
+test_expect_success 'test deleting branch without config' '
+ git branch my7 s &&
+ sha1=$(git rev-parse my7 | cut -c 1-7) &&
+ echo "Deleted branch my7 (was $sha1)." >expect &&
+ git branch -d my7 >actual 2>&1 &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'test --track without .fetch entries' '
+ git branch --track my8 &&
+ test "$(git config branch.my8.remote)" &&
+ test "$(git config branch.my8.merge)"
+'
+
+test_expect_success 'branch from non-branch HEAD w/autosetupmerge=always' '
+ git config branch.autosetupmerge always &&
+ git branch my9 HEAD^ &&
+ git config branch.autosetupmerge false
+'
+
+test_expect_success 'branch from non-branch HEAD w/--track causes failure' '
+ test_must_fail git branch --track my10 HEAD^
+'
+
+test_expect_success 'branch from tag w/--track causes failure' '
+ git tag foobar &&
+ test_must_fail git branch --track my11 foobar
+'
+
+test_expect_success 'use --set-upstream-to modify HEAD' '
+ test_config branch.master.remote foo &&
+ test_config branch.master.merge foo &&
+ git branch my12
+ git branch --set-upstream-to my12 &&
+ test "$(git config branch.master.remote)" = "." &&
+ test "$(git config branch.master.merge)" = "refs/heads/my12"
+'
+
+test_expect_success 'use --set-upstream-to modify a particular branch' '
+ git branch my13
+ git branch --set-upstream-to master my13 &&
+ test "$(git config branch.my13.remote)" = "." &&
+ test "$(git config branch.my13.merge)" = "refs/heads/master"
+'
+
+test_expect_success '--unset-upstream should fail if given a non-existent branch' '
+ test_must_fail git branch --unset-upstream i-dont-exist
+'
+
+test_expect_success 'test --unset-upstream on HEAD' '
+ git branch my14
+ test_config branch.master.remote foo &&
+ test_config branch.master.merge foo &&
+ git branch --set-upstream-to my14 &&
+ git branch --unset-upstream &&
+ test_must_fail git config branch.master.remote &&
+ test_must_fail git config branch.master.merge &&
+ # fail for a branch without upstream set
+ test_must_fail git branch --unset-upstream
+'
+
+test_expect_success 'test --unset-upstream on a particular branch' '
+ git branch my15
+ git branch --set-upstream-to master my14 &&
+ git branch --unset-upstream my14 &&
+ test_must_fail git config branch.my14.remote &&
+ test_must_fail git config branch.my14.merge
+'
+
+test_expect_success '--set-upstream shows message when creating a new branch that exists as remote-tracking' '
+ git update-ref refs/remotes/origin/master HEAD &&
+ git branch --set-upstream origin/master 2>actual &&
+ test_when_finished git update-ref -d refs/remotes/origin/master &&
+ test_when_finished git branch -d origin/master &&
+ cat >expected <<EOF &&
The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
If you wanted to make '"'master'"' track '"'origin/master'"', do this:
@@ -437,38 +448,38 @@ If you wanted to make '"'master'"' track '"'origin/master'"', do this:
git branch -d origin/master
git branch --set-upstream-to origin/master
EOF
- test_cmp expected actual
+ test_cmp expected actual
'
-test_expect_success '--set-upstream with two args only shows the deprecation message' \
- 'git branch --set-upstream master my13 2>actual &&
- test_when_finished git branch --unset-upstream master &&
- cat >expected <<EOF &&
+test_expect_success '--set-upstream with two args only shows the deprecation message' '
+ git branch --set-upstream master my13 2>actual &&
+ test_when_finished git branch --unset-upstream master &&
+ cat >expected <<EOF &&
The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
EOF
- test_cmp expected actual
+ test_cmp expected actual
'
-test_expect_success '--set-upstream with one arg only shows the deprecation message if the branch existed' \
- 'git branch --set-upstream my13 2>actual &&
- test_when_finished git branch --unset-upstream my13 &&
- cat >expected <<EOF &&
+test_expect_success '--set-upstream with one arg only shows the deprecation message if the branch existed' '
+ git branch --set-upstream my13 2>actual &&
+ test_when_finished git branch --unset-upstream my13 &&
+ cat >expected <<EOF &&
The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
EOF
- test_cmp expected actual
+ test_cmp expected actual
'
# Keep this test last, as it changes the current branch
cat >expect <<EOF
$_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
EOF
-test_expect_success \
- 'git checkout -b g/h/i -l should create a branch and a log' \
- 'GIT_COMMITTER_DATE="2005-05-26 23:30" \
- git checkout -b g/h/i -l master &&
- test_path_is_file .git/refs/heads/g/h/i &&
- test_path_is_file .git/logs/refs/heads/g/h/i &&
- test_cmp expect .git/logs/refs/heads/g/h/i'
+test_expect_success 'git checkout -b g/h/i -l should create a branch and a log' '
+ GIT_COMMITTER_DATE="2005-05-26 23:30" \
+ git checkout -b g/h/i -l master &&
+ test_path_is_file .git/refs/heads/g/h/i &&
+ test_path_is_file .git/logs/refs/heads/g/h/i &&
+ test_cmp expect .git/logs/refs/heads/g/h/i
+'
test_expect_success 'checkout -b makes reflog by default' '
git checkout master &&
--
1.8.2
^ permalink raw reply related
* [PATCH v2 39/45] parse_pathspec: make sure the prefix part is wildcard-free
From: Nguyễn Thái Ngọc Duy @ 2013-03-20 12:16 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363781779-14947-1-git-send-email-pclouds@gmail.com>
Prepending prefix to pathspec is a trick to workaround the fact that
commands can be executed in a subdirectory, but all git commands run
at worktree's root. The prefix part should always be treated as
literal string. Make it so.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
cache.h | 2 ++
path.c | 15 ++++++++++++++-
pathspec.c | 17 +++++++++++++----
pathspec.h | 2 +-
setup.c | 9 +++++----
5 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/cache.h b/cache.h
index 6297783..17e0b26 100644
--- a/cache.h
+++ b/cache.h
@@ -401,6 +401,7 @@ extern void setup_work_tree(void);
extern const char *setup_git_directory_gently(int *);
extern const char *setup_git_directory(void);
extern char *prefix_path(const char *prefix, int len, const char *path);
+extern char *prefix_path_gently(const char *prefix, int *p_len, const char *path);
extern const char *prefix_filename(const char *prefix, int len, const char *path);
extern int check_filename(const char *prefix, const char *name);
extern void verify_filename(const char *prefix,
@@ -712,6 +713,7 @@ const char *real_path(const char *path);
const char *real_path_if_valid(const char *path);
const char *absolute_path(const char *path);
const char *relative_path(const char *abs, const char *base);
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
int normalize_path_copy(char *dst, const char *src);
int longest_ancestor_length(const char *path, struct string_list *prefixes);
char *strip_path_suffix(const char *path, const char *suffix);
diff --git a/path.c b/path.c
index d3d3f8b..7baf334 100644
--- a/path.c
+++ b/path.c
@@ -487,8 +487,14 @@ const char *relative_path(const char *abs, const char *base)
*
* Note that this function is purely textual. It does not follow symlinks,
* verify the existence of the path, or make any system calls.
+ *
+ * prefix_len != NULL is for a specific case of prefix_pathspec():
+ * assume that src == dst and src[0..prefix_len-1] is already
+ * normalized, any time "../" eats up to the prefix_len part,
+ * prefix_len is reduced. In the end prefix_len is the remaining
+ * prefix that has not been overridden by user pathspec.
*/
-int normalize_path_copy(char *dst, const char *src)
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
{
char *dst0;
@@ -563,11 +569,18 @@ int normalize_path_copy(char *dst, const char *src)
/* Windows: dst[-1] cannot be backslash anymore */
while (dst0 < dst && dst[-1] != '/')
dst--;
+ if (prefix_len && *prefix_len > dst - dst0)
+ *prefix_len = dst - dst0;
}
*dst = '\0';
return 0;
}
+int normalize_path_copy(char *dst, const char *src)
+{
+ return normalize_path_copy_len(dst, src, NULL);
+}
+
/*
* path = Canonical absolute path
* prefixes = string_list containing normalized, absolute paths without
diff --git a/pathspec.c b/pathspec.c
index 9cd3f2c..01f8844 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -149,10 +149,14 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
magic |= short_magic;
*p_short_magic = short_magic;
- if (magic & PATHSPEC_FROMTOP)
+ if (magic & PATHSPEC_FROMTOP) {
match = xstrdup(copyfrom);
- else
- match = prefix_path(prefix, prefixlen, copyfrom);
+ prefixlen = 0;
+ } else {
+ match = prefix_path_gently(prefix, &prefixlen, copyfrom);
+ if (!match)
+ die("%s: '%s' is outside repository", elt, copyfrom);
+ }
*raw = item->match = match;
/*
* Prefix the pathspec (keep all magic) and put to
@@ -166,6 +170,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
} else
item->original = elt;
item->len = strlen(item->match);
+ item->prefix = prefixlen;
if ((flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) &&
(item->len >= 1 && item->match[item->len - 1] == '/') &&
@@ -197,8 +202,11 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
if (limit_pathspec_to_literal())
item->nowildcard_len = item->len;
- else
+ else {
item->nowildcard_len = simple_length(item->match);
+ if (item->nowildcard_len < prefixlen)
+ item->nowildcard_len = prefixlen;
+ }
item->flags = 0;
if (item->nowildcard_len < item->len &&
item->match[item->nowildcard_len] == '*' &&
@@ -283,6 +291,7 @@ void parse_pathspec(struct pathspec *pathspec,
item->match = prefix;
item->original = prefix;
item->nowildcard_len = item->len = strlen(prefix);
+ item->prefix = item->len;
raw[0] = prefix;
raw[1] = NULL;
pathspec->nr = 1;
diff --git a/pathspec.h b/pathspec.h
index 16bbb7b..bbcfa74 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -21,7 +21,7 @@ struct pathspec {
const char *match;
const char *original;
unsigned magic;
- int len;
+ int len, prefix;
int nowildcard_len;
int flags;
} *items;
diff --git a/setup.c b/setup.c
index acdc634..e661a71 100644
--- a/setup.c
+++ b/setup.c
@@ -5,10 +5,11 @@
static int inside_git_dir = -1;
static int inside_work_tree = -1;
-static char *prefix_path_gently(const char *prefix, int len, const char *path)
+char *prefix_path_gently(const char *prefix, int *p_len, const char *path)
{
const char *orig = path;
char *sanitized;
+ int len = *p_len;
if (is_absolute_path(orig)) {
const char *temp = real_path(path);
sanitized = xmalloc(len + strlen(temp) + 1);
@@ -19,7 +20,7 @@ static char *prefix_path_gently(const char *prefix, int len, const char *path)
memcpy(sanitized, prefix, len);
strcpy(sanitized + len, path);
}
- if (normalize_path_copy(sanitized, sanitized))
+ if (normalize_path_copy_len(sanitized, sanitized, p_len))
goto error_out;
if (is_absolute_path(orig)) {
size_t root_len, len, total;
@@ -44,7 +45,7 @@ static char *prefix_path_gently(const char *prefix, int len, const char *path)
char *prefix_path(const char *prefix, int len, const char *path)
{
- char *r = prefix_path_gently(prefix, len, path);
+ char *r = prefix_path_gently(prefix, &len, path);
if (!r)
die("'%s' is outside repository", path);
return r;
@@ -53,7 +54,7 @@ char *prefix_path(const char *prefix, int len, const char *path)
int path_inside_repo(const char *prefix, const char *path)
{
int len = prefix ? strlen(prefix) : 0;
- char *r = prefix_path_gently(prefix, len, path);
+ char *r = prefix_path_gently(prefix, &len, path);
if (r) {
free(r);
return 1;
--
1.8.0.rc0.19.g7bbb31d
^ permalink raw reply related
* [PATCH v2 27/45] Convert run_add_interactive to use struct pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-03-20 12:16 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363781779-14947-1-git-send-email-pclouds@gmail.com>
This passes the pathspec, more or less unmodified, to
git-add--interactive. The command itself does not process pathspec. It
simply passes the pathspec to other builtin commands. So if all those
commands support pathspec, we're good.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/add.c | 26 ++++++++++----------------
builtin/checkout.c | 9 ++++-----
builtin/reset.c | 8 ++++----
commit.h | 2 +-
4 files changed, 19 insertions(+), 26 deletions(-)
diff --git a/builtin/add.c b/builtin/add.c
index ec6fbe3..2b20d7d 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -139,16 +139,12 @@ static void refresh(int verbose, const char **pathspec)
}
int run_add_interactive(const char *revision, const char *patch_mode,
- const char **pathspec)
+ const struct pathspec *pathspec)
{
- int status, ac, pc = 0;
+ int status, ac, i;
const char **args;
- if (pathspec)
- while (pathspec[pc])
- pc++;
-
- args = xcalloc(sizeof(const char *), (pc + 5));
+ args = xcalloc(sizeof(const char *), (pathspec->nr + 6));
ac = 0;
args[ac++] = "add--interactive";
if (patch_mode)
@@ -156,11 +152,9 @@ int run_add_interactive(const char *revision, const char *patch_mode,
if (revision)
args[ac++] = revision;
args[ac++] = "--";
- if (pc) {
- memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
- ac += pc;
- }
- args[ac] = NULL;
+ for (i = 0; i < pathspec->nr; i++)
+ /* pass original pathspec, to be re-parsed */
+ args[ac++] = pathspec->items[i].original;
status = run_command_v_opt(args, RUN_GIT_CMD);
free(args);
@@ -175,17 +169,17 @@ int interactive_add(int argc, const char **argv, const char *prefix, int patch)
* git-add--interactive itself does not parse pathspec. It
* simply passes the pathspec to other builtin commands. Let's
* hope all of them support all magic, or we'll need to limit
- * the magic here. There is still a problem with prefix. But
- * that'll be worked on later on.
+ * the magic here.
*/
parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP,
PATHSPEC_PREFER_FULL |
- PATHSPEC_SYMLINK_LEADING_PATH,
+ PATHSPEC_SYMLINK_LEADING_PATH |
+ PATHSPEC_PREFIX_ORIGIN,
prefix, argv);
return run_add_interactive(NULL,
patch ? "--patch" : NULL,
- pathspec.raw);
+ &pathspec);
}
static int edit_patch(int argc, const char **argv, const char *prefix)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 3c19cb4..2ddff95 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -256,7 +256,7 @@ static int checkout_paths(const struct checkout_opts *opts,
if (opts->patch_mode)
return run_add_interactive(revision, "--patch=checkout",
- opts->pathspec.raw);
+ &opts->pathspec);
lock_file = xcalloc(1, sizeof(struct lock_file));
@@ -1115,10 +1115,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
* cannot handle. Magic mask is pretty safe to be
* lifted for new magic when opts.patch_mode == 0.
*/
- parse_pathspec(&opts.pathspec,
- opts.patch_mode == 0 ? 0 :
- (PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP),
- 0, prefix, argv);
+ parse_pathspec(&opts.pathspec, 0,
+ opts.patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0,
+ prefix, argv);
if (!opts.pathspec.nr)
die(_("invalid path specification"));
diff --git a/builtin/reset.c b/builtin/reset.c
index da7282e..1c8e4a5 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -216,9 +216,9 @@ static void parse_args(struct pathspec *pathspec,
}
}
*rev_ret = rev;
- parse_pathspec(pathspec,
- patch_mode ? PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP : 0,
- PATHSPEC_PREFER_FULL,
+ parse_pathspec(pathspec, 0,
+ PATHSPEC_PREFER_FULL |
+ (patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0),
prefix, argv);
}
@@ -296,7 +296,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
if (patch_mode) {
if (reset_type != NONE)
die(_("--patch is incompatible with --{hard,mixed,soft}"));
- return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", pathspec.raw);
+ return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", &pathspec);
}
/* git reset tree [--] paths... can be used to
diff --git a/commit.h b/commit.h
index 4138bb4..9448fda 100644
--- a/commit.h
+++ b/commit.h
@@ -179,7 +179,7 @@ int in_merge_bases(struct commit *, struct commit *);
extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
extern int run_add_interactive(const char *revision, const char *patch_mode,
- const char **pathspec);
+ const struct pathspec *pathspec);
static inline int single_parent(struct commit *commit)
{
--
1.8.0.rc0.19.g7bbb31d
^ permalink raw reply related
* [PATCH v2 14/45] Guard against new pathspec magic in pathspec matching code
From: Nguyễn Thái Ngọc Duy @ 2013-03-20 12:16 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363781779-14947-1-git-send-email-pclouds@gmail.com>
GUARD_PATHSPEC() marks pathspec-sensitive code, basically all those
that touch anything in 'struct pathspec' except fields "nr" and
"original". GUARD_PATHSPEC() is not supposed to fail. It's mainly to
help the designers to catch unsupported codepaths.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/technical/api-setup.txt | 19 +++++++++++++++++++
builtin/diff.c | 2 ++
dir.c | 2 ++
pathspec.h | 7 +++++++
tree-diff.c | 19 +++++++++++++++++++
tree-walk.c | 2 ++
6 files changed, 51 insertions(+)
diff --git a/Documentation/technical/api-setup.txt b/Documentation/technical/api-setup.txt
index 59a947e..f62528e 100644
--- a/Documentation/technical/api-setup.txt
+++ b/Documentation/technical/api-setup.txt
@@ -28,3 +28,22 @@ parse_pathspec(). This function takes several arguments:
- prefix and args come from cmd_* functions
get_pathspec() is obsolete and should never be used in new code.
+
+parse_pathspec() helps catch unsupported features and reject it
+politely. At a lower level, different pathspec-related functions may
+not support the same set of features. Such pathspec-sensitive
+functions are guarded with GUARD_PATHSPEC(), which will die in an
+unfriendly way when an unsupported feature is requested.
+
+The command designers are supposed to make sure that GUARD_PATHSPEC()
+never dies. They have to make sure all unsupported features are caught
+by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC()
+should give the designers all pathspec-sensitive codepaths and what
+features they support.
+
+A similar process is applied when a new pathspec magic is added. The
+designer lifts the GUARD_PATHSPEC restriction in the functions that
+support the new magic. At the same time (s)he has to make sure this
+new feature will be caught at parse_pathspec() in commands that cannot
+handle the new magic in some cases. grepping parse_pathspec() should
+help.
diff --git a/builtin/diff.c b/builtin/diff.c
index 8c2af6c..d237e0a 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -371,6 +371,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
die(_("unhandled object '%s' given."), name);
}
if (rev.prune_data.nr) {
+ /* builtin_diff_b_f() */
+ GUARD_PATHSPEC(&rev.prune_data, PATHSPEC_FROMTOP);
if (!path)
path = rev.prune_data.items[0].match;
paths += rev.prune_data.nr;
diff --git a/dir.c b/dir.c
index 1e9db41..6094ba8 100644
--- a/dir.c
+++ b/dir.c
@@ -297,6 +297,8 @@ int match_pathspec_depth(const struct pathspec *ps,
{
int i, retval = 0;
+ GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+
if (!ps->nr) {
if (!ps->recursive ||
!(ps->magic & PATHSPEC_MAXDEPTH) ||
diff --git a/pathspec.h b/pathspec.h
index 3ca6636..7068f7d 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -27,6 +27,13 @@ struct pathspec {
} *items;
};
+#define GUARD_PATHSPEC(ps, mask) \
+ do { \
+ if ((ps)->magic & ~(mask)) \
+ die("BUG:%s:%d: unsupported magic %x", \
+ __FILE__, __LINE__, (ps)->magic & ~(mask)); \
+ } while (0)
+
/* parse_pathspec flags */
#define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */
#define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */
diff --git a/tree-diff.c b/tree-diff.c
index 826512e..5a87614 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -198,6 +198,25 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
const char *paths[1];
int i;
+ /*
+ * follow-rename code is very specific, we need exactly one
+ * path. Magic that matches more than one path is not
+ * supported.
+ */
+ GUARD_PATHSPEC(&opt->pathspec, PATHSPEC_FROMTOP);
+#if 0
+ /*
+ * We should reject wildcards as well. Unfortunately we
+ * haven't got a reliable way to detect that 'foo\*bar' in
+ * fact has no wildcards. nowildcard_len is merely a hint for
+ * optimization. Let it slip for now until wildmatch is taught
+ * about dry-run mode and returns wildcard info.
+ */
+ if (opt->pathspec.has_wildcard)
+ die("BUG:%s:%d: wildcards are not supported",
+ __FILE__, __LINE__);
+#endif
+
/* Remove the file creation entry from the diff queue, and remember it */
choice = q->queue[0];
q->nr = 0;
diff --git a/tree-walk.c b/tree-walk.c
index d399ca9..37b157e 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -636,6 +636,8 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
enum interesting never_interesting = ps->has_wildcard ?
entry_not_interesting : all_entries_not_interesting;
+ GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+
if (!ps->nr) {
if (!ps->recursive ||
!(ps->magic & PATHSPEC_MAXDEPTH) ||
--
1.8.0.rc0.19.g7bbb31d
^ permalink raw reply related
* [PATCH v2 12/45] parse_pathspec: support stripping/checking submodule paths
From: Nguyễn Thái Ngọc Duy @ 2013-03-20 12:16 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363781779-14947-1-git-send-email-pclouds@gmail.com>
PATHSPEC_SYMLINK_LEADING_PATH and _STRIP_SUBMODULE_SLASH_EXPENSIVE are
respectively the alternate implementation of
pathspec.c:die_if_path_beyond_symlink() and
pathspec.c:check_path_for_gitlink(). They are intended to replace
those functions when builtin/add.c and builtin/check-ignore.c are
converted to use parse_pathspec.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
pathspec.c | 26 ++++++++++++++++++++++++++
pathspec.h | 10 ++++++++++
2 files changed, 36 insertions(+)
diff --git a/pathspec.c b/pathspec.c
index 57ad9ba..40bf178 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -213,6 +213,26 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
match[item->len] = '\0';
}
+ if (flags & PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE)
+ for (i = 0; i < active_nr; i++) {
+ struct cache_entry *ce = active_cache[i];
+ int ce_len = ce_namelen(ce);
+
+ if (!S_ISGITLINK(ce->ce_mode))
+ continue;
+
+ if (item->len <= ce_len || match[ce_len] != '/' ||
+ memcmp(ce->name, match, ce_len))
+ continue;
+ if (item->len == ce_len + 1) {
+ /* strip trailing slash */
+ item->len--;
+ match[item->len] = '\0';
+ } else
+ die (_("Pathspec '%s' is in submodule '%.*s'"),
+ elt, ce_len, ce->name);
+ }
+
if (limit_pathspec_to_literal())
item->nowildcard_len = item->len;
else
@@ -328,6 +348,12 @@ void parse_pathspec(struct pathspec *pathspec,
unsupported_magic(entry,
item[i].magic & magic_mask,
short_magic);
+
+ if ((flags & PATHSPEC_SYMLINK_LEADING_PATH) &&
+ has_symlink_leading_path(item[i].match, item[i].len)) {
+ die(_("pathspec '%s' is beyond a symbolic link"), entry);
+ }
+
if (item[i].nowildcard_len < item[i].len)
pathspec->has_wildcard = 1;
pathspec->magic |= item[i].magic;
diff --git a/pathspec.h b/pathspec.h
index 7935b26..b631514 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -33,6 +33,16 @@ struct pathspec {
#define PATHSPEC_MAXDEPTH_VALID (1<<2) /* max_depth field is valid */
/* stripping the trailing slash if the given path is a gitlink */
#define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (1<<3)
+/* die if a symlink is part of the given path's directory */
+#define PATHSPEC_SYMLINK_LEADING_PATH (1<<4)
+/*
+ * This is like a combination of ..LEADING_PATH and .._SLASH_CHEAP
+ * (but not the same): it strips the trailing slash if the given path
+ * is a gitlink but also checks and dies if gitlink is part of the
+ * leading path (i.e. the given path goes beyond a submodule). It's
+ * safer than _SLASH_CHEAP and also more expensive.
+ */
+#define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (1<<5)
extern int init_pathspec(struct pathspec *, const char **);
extern void parse_pathspec(struct pathspec *pathspec,
--
1.8.0.rc0.19.g7bbb31d
^ permalink raw reply related
* [PATCH v2 11/45] parse_pathspec: support stripping submodule trailing slashes
From: Nguyễn Thái Ngọc Duy @ 2013-03-20 12:16 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363781779-14947-1-git-send-email-pclouds@gmail.com>
This flag is equivalent to builtin/ls-files.c:strip_trailing_slashes()
and is intended to replace that function when ls-files is converted to
use parse_pathspec.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
pathspec.c | 9 +++++++++
pathspec.h | 2 ++
2 files changed, 11 insertions(+)
diff --git a/pathspec.c b/pathspec.c
index fb5443c..57ad9ba 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -204,6 +204,15 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
*raw = item->match = match;
item->original = elt;
item->len = strlen(item->match);
+
+ if ((flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) &&
+ (item->len >= 1 && item->match[item->len - 1] == '/') &&
+ (i = cache_name_pos(item->match, item->len - 1)) >= 0 &&
+ S_ISGITLINK(active_cache[i]->ce_mode)) {
+ item->len--;
+ match[item->len] = '\0';
+ }
+
if (limit_pathspec_to_literal())
item->nowildcard_len = item->len;
else
diff --git a/pathspec.h b/pathspec.h
index aa98597..7935b26 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -31,6 +31,8 @@ struct pathspec {
#define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */
#define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */
#define PATHSPEC_MAXDEPTH_VALID (1<<2) /* max_depth field is valid */
+/* stripping the trailing slash if the given path is a gitlink */
+#define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (1<<3)
extern int init_pathspec(struct pathspec *, const char **);
extern void parse_pathspec(struct pathspec *pathspec,
--
1.8.0.rc0.19.g7bbb31d
^ permalink raw reply related
* [PATCH v2 06/45] Add parse_pathspec() that converts cmdline args to struct pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-03-20 12:16 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363781779-14947-1-git-send-email-pclouds@gmail.com>
Currently to fill a struct pathspec, we do:
const char **paths;
paths = get_pathspec(prefix, argv);
...
init_pathspec(&pathspec, paths);
"paths" can only carry bare strings, which loses information from
command line arguments such as pathspec magic or the prefix part's
length for each argument.
parse_pathspec() is introduced to combine the two calls into one. The
plan is gradually replace all get_pathspec() and init_pathspec() with
parse_pathspec(). get_pathspec() now becomes a thin wrapper of
parse_pathspec().
parse_pathspec() allows the caller to reject the pathspec magics that
it does not support. When a new pathspec magic is introduced, we can
enable it per command after making sure that all underlying code has no
problem with the new magic.
"flags" parameter is currently unused. But it would allow callers to
pass certain instructions to parse_pathspec, for example forcing
literal pathspec when no magic is used.
With the introduction of parse_pathspec, there are now two functions
that can initialize struct pathspec: init_pathspec and
parse_pathspec. Any semantic changes in struct pathspec must be
reflected in both functions. init_pathspec() will be phased out in
favor of parse_pathspec().
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/technical/api-setup.txt | 19 +++-
dir.c | 4 +-
dir.h | 2 +
pathspec.c | 168 ++++++++++++++++++++++++++--------
pathspec.h | 11 +++
5 files changed, 163 insertions(+), 41 deletions(-)
diff --git a/Documentation/technical/api-setup.txt b/Documentation/technical/api-setup.txt
index 4f63a04..59a947e 100644
--- a/Documentation/technical/api-setup.txt
+++ b/Documentation/technical/api-setup.txt
@@ -8,6 +8,23 @@ Talk about
* is_inside_git_dir()
* is_inside_work_tree()
* setup_work_tree()
-* get_pathspec()
(Dscho)
+
+Pathspec
+========
+
+See glossary-context.txt for the syntax of pathspec. In memory, a
+pathspec set is represented by "struct pathspec" and is prepared by
+parse_pathspec(). This function takes several arguments:
+
+- magic_mask specifies what features that are NOT supported by the
+ following code. If a user attempts to use such a feature,
+ parse_pathspec() can reject it early.
+
+- flags specifies other things that the caller wants parse_pathspec to
+ perform.
+
+- prefix and args come from cmd_* functions
+
+get_pathspec() is obsolete and should never be used in new code.
diff --git a/dir.c b/dir.c
index 97ad45b..a442467 100644
--- a/dir.c
+++ b/dir.c
@@ -338,7 +338,7 @@ int match_pathspec_depth(const struct pathspec *ps,
/*
* Return the length of the "simple" part of a path match limiter.
*/
-static int simple_length(const char *match)
+int simple_length(const char *match)
{
int len = -1;
@@ -350,7 +350,7 @@ static int simple_length(const char *match)
}
}
-static int no_wildcard(const char *string)
+int no_wildcard(const char *string)
{
return string[simple_length(string)] == '\0';
}
diff --git a/dir.h b/dir.h
index c3eb4b5..89427fd 100644
--- a/dir.h
+++ b/dir.h
@@ -125,6 +125,8 @@ struct dir_struct {
#define MATCHED_RECURSIVELY 1
#define MATCHED_FNMATCH 2
#define MATCHED_EXACTLY 3
+extern int simple_length(const char *match);
+extern int no_wildcard(const char *string);
extern char *common_prefix(const char **pathspec);
extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
extern int match_pathspec_depth(const struct pathspec *pathspec,
diff --git a/pathspec.c b/pathspec.c
index ab53b8a..ebe9844 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -103,10 +103,6 @@ void die_if_path_beyond_symlink(const char *path, const char *prefix)
/*
* Magic pathspec
*
- * NEEDSWORK: These need to be moved to dir.h or even to a new
- * pathspec.h when we restructure get_pathspec() users to use the
- * "struct pathspec" interface.
- *
* Possible future magic semantics include stuff like:
*
* { PATHSPEC_NOGLOB, '!', "noglob" },
@@ -115,7 +111,6 @@ void die_if_path_beyond_symlink(const char *path, const char *prefix)
* { PATHSPEC_REGEXP, '\0', "regexp" },
*
*/
-#define PATHSPEC_FROMTOP (1<<0)
static struct pathspec_magic {
unsigned bit;
@@ -127,7 +122,7 @@ static struct pathspec_magic {
/*
* Take an element of a pathspec and check for magic signatures.
- * Append the result to the prefix.
+ * Append the result to the prefix. Return the magic bitmap.
*
* For now, we only parse the syntax and throw out anything other than
* "top" magic.
@@ -138,10 +133,15 @@ static struct pathspec_magic {
* the prefix part must always match literally, and a single stupid
* string cannot express such a case.
*/
-static const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
+static unsigned prefix_pathspec(struct pathspec_item *item,
+ unsigned *p_short_magic,
+ const char **raw, unsigned flags,
+ const char *prefix, int prefixlen,
+ const char *elt)
{
- unsigned magic = 0;
+ unsigned magic = 0, short_magic = 0;
const char *copyfrom = elt;
+ char *match;
int i;
if (elt[0] != ':') {
@@ -183,7 +183,7 @@ static const char *prefix_pathspec(const char *prefix, int prefixlen, const char
break;
for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
if (pathspec_magic[i].mnemonic == ch) {
- magic |= pathspec_magic[i].bit;
+ short_magic |= pathspec_magic[i].bit;
break;
}
if (ARRAY_SIZE(pathspec_magic) <= i)
@@ -194,15 +194,128 @@ static const char *prefix_pathspec(const char *prefix, int prefixlen, const char
copyfrom++;
}
+ magic |= short_magic;
+ *p_short_magic = short_magic;
+
if (magic & PATHSPEC_FROMTOP)
- return xstrdup(copyfrom);
+ match = xstrdup(copyfrom);
else
- return prefix_path(prefix, prefixlen, copyfrom);
+ match = prefix_path(prefix, prefixlen, copyfrom);
+ *raw = item->match = match;
+ item->len = strlen(item->match);
+ if (limit_pathspec_to_literal())
+ item->nowildcard_len = item->len;
+ else
+ item->nowildcard_len = simple_length(item->match);
+ item->flags = 0;
+ if (item->nowildcard_len < item->len &&
+ item->match[item->nowildcard_len] == '*' &&
+ no_wildcard(item->match + item->nowildcard_len + 1))
+ item->flags |= PATHSPEC_ONESTAR;
+ return magic;
+}
+
+static int pathspec_item_cmp(const void *a_, const void *b_)
+{
+ struct pathspec_item *a, *b;
+
+ a = (struct pathspec_item *)a_;
+ b = (struct pathspec_item *)b_;
+ return strcmp(a->match, b->match);
+}
+
+static void NORETURN unsupported_magic(const char *pattern,
+ unsigned magic,
+ unsigned short_magic)
+{
+ struct strbuf sb = STRBUF_INIT;
+ int i, n;
+ for (n = i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
+ const struct pathspec_magic *m = pathspec_magic + i;
+ if (!(magic & m->bit))
+ continue;
+ if (sb.len)
+ strbuf_addstr(&sb, " ");
+ if (short_magic & m->bit)
+ strbuf_addf(&sb, "'%c'", m->mnemonic);
+ else
+ strbuf_addf(&sb, "'%s'", m->name);
+ n++;
+ }
+ /*
+ * We may want to substitue "this command" with a command
+ * name. E.g. when add--interactive dies when running
+ * "checkout -p"
+ */
+ die(_("%s: pathspec magic not supported by this command: %s"),
+ pattern, sb.buf);
+}
+
+/*
+ * Given command line arguments and a prefix, convert the input to
+ * pathspec. die() any magic in magic_mask is used.
+ */
+void parse_pathspec(struct pathspec *pathspec,
+ unsigned magic_mask, unsigned flags,
+ const char *prefix, const char **argv)
+{
+ struct pathspec_item *item;
+ const char *entry = argv ? *argv : NULL;
+ int i, n, prefixlen;
+
+ memset(pathspec, 0, sizeof(*pathspec));
+
+ /* No arguments, no prefix -> no pathspec */
+ if (!entry && !prefix)
+ return;
+
+ /* No arguments with prefix -> prefix pathspec */
+ if (!entry) {
+ static const char *raw[2];
+
+ pathspec->items = item = xmalloc(sizeof(*item));
+ memset(item, 0, sizeof(*item));
+ item->match = prefix;
+ item->nowildcard_len = item->len = strlen(prefix);
+ raw[0] = prefix;
+ raw[1] = NULL;
+ pathspec->nr = 1;
+ pathspec->raw = raw;
+ return;
+ }
+
+ n = 0;
+ while (argv[n])
+ n++;
+
+ pathspec->nr = n;
+ pathspec->items = item = xmalloc(sizeof(*item) * n);
+ pathspec->raw = argv;
+ prefixlen = prefix ? strlen(prefix) : 0;
+
+ for (i = 0; i < n; i++) {
+ unsigned short_magic;
+ entry = argv[i];
+
+ item[i].magic = prefix_pathspec(item + i, &short_magic,
+ argv + i, flags,
+ prefix, prefixlen, entry);
+ if (item[i].magic & magic_mask)
+ unsupported_magic(entry,
+ item[i].magic & magic_mask,
+ short_magic);
+ if (item[i].nowildcard_len < item[i].len)
+ pathspec->has_wildcard = 1;
+ pathspec->magic |= item[i].magic;
+ }
+
+ qsort(pathspec->items, pathspec->nr,
+ sizeof(struct pathspec_item), pathspec_item_cmp);
}
/*
* N.B. get_pathspec() is deprecated in favor of the "struct pathspec"
- * based interface - see pathspec_magic above.
+ * based interface - see pathspec.c:parse_pathspec().
*
* Arguments:
* - prefix - a path relative to the root of the working tree
@@ -221,32 +334,11 @@ static const char *prefix_pathspec(const char *prefix, int prefixlen, const char
*/
const char **get_pathspec(const char *prefix, const char **pathspec)
{
- const char *entry = *pathspec;
- const char **src, **dst;
- int prefixlen;
-
- if (!prefix && !entry)
- return NULL;
-
- if (!entry) {
- static const char *spec[2];
- spec[0] = prefix;
- spec[1] = NULL;
- return spec;
- }
-
- /* Otherwise we have to re-write the entries.. */
- src = pathspec;
- dst = pathspec;
- prefixlen = prefix ? strlen(prefix) : 0;
- while (*src) {
- *(dst++) = prefix_pathspec(prefix, prefixlen, *src);
- src++;
- }
- *dst = NULL;
- if (!*pathspec)
- return NULL;
- return pathspec;
+ struct pathspec ps;
+ parse_pathspec(&ps,
+ PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP,
+ 0, prefix, pathspec);
+ return ps.raw;
}
void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
diff --git a/pathspec.h b/pathspec.h
index a621676..937ec91 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -1,6 +1,10 @@
#ifndef PATHSPEC_H
#define PATHSPEC_H
+/* Pathspec magic */
+#define PATHSPEC_FROMTOP (1<<0)
+#define PATHSPEC_ALL_MAGIC PATHSPEC_FROMTOP
+
#define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR */
struct pathspec {
@@ -8,9 +12,11 @@ struct pathspec {
int nr;
unsigned int has_wildcard:1;
unsigned int recursive:1;
+ unsigned magic;
int max_depth;
struct pathspec_item {
const char *match;
+ unsigned magic;
int len;
int nowildcard_len;
int flags;
@@ -18,6 +24,11 @@ struct pathspec {
};
extern int init_pathspec(struct pathspec *, const char **);
+extern void parse_pathspec(struct pathspec *pathspec,
+ unsigned magic_mask,
+ unsigned flags,
+ const char *prefix,
+ const char **args);
extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
extern void free_pathspec(struct pathspec *);
--
1.8.0.rc0.19.g7bbb31d
^ permalink raw reply related
* [PATCH v2 00/45] parse_pathspec and :(glob) magic
From: Nguyễn Thái Ngọc Duy @ 2013-03-20 12:16 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1363327620-29017-1-git-send-email-pclouds@gmail.com>
Junio please pull the series from github [1]. I don't want to spam the
list with 45 patches again so I only send patches that are substantially
different from v1:
- documentation for parse_pathspec
- fix wrong operator precendence in git-reset
- fix initialization that may lead to crashes in git-grep (and
probably the failure in t7300-clean.sh)
Typos found by Eric are also fixed, just not sent here.
[1] https://github.com/pclouds/git/commits/parse-pathspec
Nguyễn Thái Ngọc Duy (6):
Add parse_pathspec() that converts cmdline args to struct pathspec
parse_pathspec: support stripping submodule trailing slashes
parse_pathspec: support stripping/checking submodule paths
Guard against new pathspec magic in pathspec matching code
Convert run_add_interactive to use struct pathspec
parse_pathspec: make sure the prefix part is wildcard-free
--
1.8.0.rc0.19.g7bbb31d
^ permalink raw reply
* [RFC] Add posibility to preload stat information.
From: Fredrik Gustafsson @ 2013-03-20 12:15 UTC (permalink / raw)
To: spearce; +Cc: git, pclouds, iveqy
When entering a git working dir, optionally run a forked process that
stat all files in the whole workdir and therefore loads stat information
to RAM which will speedup things like git status and so on.
The feature is optional and by default it's off.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
---
contrib/completion/git-prompt.sh | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 341422a..e67bc97 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -78,6 +78,12 @@
# If you would like a colored hint about the current dirty state, set
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
# the colored output of "git status -sb".
+#
+# When enter a git work dir you can have a forked process run
+# stat on all files in the top level directory for git and down.
+# This will decrease later calls to git status and alike because
+# stat info will already be loaded into RAM. set GIT_PRE_STAT to
+# a nonempty value.
# __gitdir accepts 0 or 1 arguments (i.e., location)
# returns location of .git repo
@@ -222,6 +228,19 @@ __git_ps1_show_upstream ()
}
+# Forks and recursive do a stat from the toplevel git dir.
+# This will load inodes into RAM for faster access when running
+# A git command, like git show.
+__git_recursive_stat ()
+{
+ if test ! -e /tmp/gitbash.lock
+ then
+ touch /tmp/gitbash.lock
+ cd $(git rev-parse --show-toplevel)
+ find . | xargs stat 2&> /dev/null
+ rm /tmp/gitbash.lock
+ fi
+}
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
# when called from PS1 using command substitution
@@ -320,6 +339,10 @@ __git_ps1 ()
b="GIT_DIR!"
fi
elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
+ if [ -n "${GIT_PRE_STAT-}" ];
+ then
+ (__git_recursive_stat 2&> /dev/null &)
+ fi
if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
[ "$(git config --bool bash.showDirtyState)" != "false" ]
then
--
1.8.1.5
^ permalink raw reply related
* Re: [PATCH] git-p4: support exclusively locked files
From: Danny Thomas @ 2013-03-20 11:33 UTC (permalink / raw)
To: Pete Wyckoff; +Cc: git@vger.kernel.org
In-Reply-To: <20130319192312.GA16872@padd.com>
Sounds good to me. I've got a couple of busy days coming up, but should
have time this week.
Danny
On 19/03/2013 19:23, "Pete Wyckoff" <pw@padd.com> wrote:
>Danny.Thomas@blackboard.com wrote on Mon, 18 Mar 2013 09:26 -0400:
>> Interesting. 'Implementing sitewide pessimistic locking with p4
>>typemap',
>>
>>http://www.perforce.com/perforce/doc.current/manuals/p4sag/03_superuser.h
>>tm
>> l seems to suggest this is all that's needed. I believe we're using the
>> default configuration, the exclusive lock on all files behaviour was
>> researching the exclusive locking problem,
>> http://ericlathrop.com/2012/12/how-to-set-up-git-p4-in-windows/, so I
>> thought I'd mention it.
>>
>> You might be onto something w/ fstat, it doesn't include the exclusive
>> indicator:
>>
>> ... type binary+l
>>
>> Latest P4 client, and fairly recent server build:
>>
>> P4/DARWIN90X86_64/2012.2/536738 (2012/10/16)
>> P4D/LINUX26X86_64/2012.2/538478 (2012/10/16)
>
>Great, thanks for the pointer and explanation. Do you want to
>reroll your patch to use fstat? I'll work on the tests, and
>also look into potential failure modes of "git p4 submit" when somebody
>else has the exclusive file open.
>
> -- Pete
>
>> On 17/03/2013 20:04, "Pete Wyckoff" <pw@padd.com> wrote:
>>
>> >Danny.Thomas@blackboard.com wrote on Wed, 13 Mar 2013 13:51 -0400:
>> >> By default, newly added binary files are exclusively locked by
>>Perforce:
>> >>
>> >> 'add default change (binary+l) *exclusive*'
>> >>
>> >> This results in a 'Could not determine file type' error as the regex
>> >> expects
>> >> the line to end after the file type matching group. Some repositories
>> >>are
>> >> also configured to always require exclusive locks, so may be a
>>problem
>> >>for
>> >> all revisions in some cases.
>> >
>> >Can you explain how to configure p4d to default everything to
>> >binary+l? Also, what version are you using ("p4 info")? I'm
>> >trying to write a test case for this.
>> >
>> >I did find a way to play with typemap to get +l, as:
>> >
>> > ( p4 typemap -o ; printf "\tbinary+l\t//.../bash*" ) | p4 typemap
>>-i
>> >
>> >With this, the 2011.1 here just says:
>> >0
>> > tic-git-test$ p4 opened bash
>> > //depot/bash#1 - add default change (binary+l)
>> >
>> >I've not been able to make it say " *exclusive*" too.
>> >
>> >> result = p4_read_pipe(["opened", wildcard_encode(file)])
>> >> - match = re.match(".*\((.+)\)\r?$", result)
>> >> + match = re.match(".*\((.+)\)(?:.+)?\r?$", result)
>> >
>> >I think this whole function would be less brittle
>> >using p4's "-G" output, like:
>> >
>> > d = p4Cmd(["fstat", "-T", "type", wildcard_encode(file)])
>> > # some error checking
>> > return d['type']
>> >
>> >But I'm curious if your p4d includes " *exclusive*" in the
>> >type there too, in which case we'll have to strip it.
>> >
>> >Thanks for starting the patch on this. It's good if we can keep
>> >others from running into the same problem.
This email and any attachments may contain confidential and proprietary information of Blackboard that is for the sole use of the intended recipient. If you are not the intended recipient, disclosure, copying, re-distribution or other use of any of this information is strictly prohibited. Please immediately notify the sender and delete this transmission if you received this email in error.
^ permalink raw reply
* Re: [PATCH jk/pkt-line-cleanup] t5700-clone-reference: send trace to fd 2, not 3, to please Windows git
From: Johannes Sixt @ 2013-03-20 11:30 UTC (permalink / raw)
To: Jeff King; +Cc: Git Mailing List
In-Reply-To: <20130320093313.GA9482@sigill.intra.peff.net>
Am 3/20/2013 10:33, schrieb Jeff King:
> On Wed, Mar 20, 2013 at 09:24:44AM +0100, Johannes Sixt wrote:
>
>> From: Johannes Sixt <j6t@kdbg.org>
>>
>> Two tests use GIT_TRACE=3 to dump debugging information of git. On
>> Windows, however, bash is unable to set up file descriptor 3 correctly
>> for its child process, so that git reports "Bad file descriptor" on
>> every trace attempt. The 'git clone' test succeeds nevertheless because
>> an empty trace file remains, and there is only a check for the
>> absence of a particular line. But the 'git fetch' process ultimately
>> hangs (the dynamics that lead to this surprising result have not been
>> investigated).
>>
>> Since we do not otherwise use stderr in the test cases, divert the
>> trace dump to stderr.
>
> I think that is OK, but I'm curious why this is a problem _now_, and not
> with the code prior to 97a83fa8. The old GIT_DEBUG_SEND_PACK was also
> just calling write() to descriptor 3.
Before this change, both affected commands completed and the trace file
was empty. Notice that in both test cases we only check for the absence of
certain lines, which is naturally true for an empty file, so that the
tests pass.
With the updated code, 'git fetch' hung, which is how I noticed the
problem. As I said, I didn't investigate where and why this happens.
>> This fixes a regression introduced in
>
> ...in 97a83fa8, I assume.
Yes, correct. (Sorry, I got distracted while I looked up the commit.)
-- Hannes
^ permalink raw reply
* Re: [PATCH v1 39/45] parse_pathspec: make sure the prefix part is wildcard-free
From: Duy Nguyen @ 2013-03-20 10:54 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <CACsJy8DjrB45kDRiOs9b=VS5Z5=_sdh37Z3Q20sT6iDacLmM+Q@mail.gmail.com>
On Wed, Mar 20, 2013 at 8:32 AM, Duy Nguyen <pclouds@gmail.com> wrote:
> On Wed, Mar 20, 2013 at 1:34 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> This seems to break t7300-clean.sh #8
>
> Repeatedly? I saw some t7300-clean.sh failures when running tests in
> parallel, but never been able to reproduce it alone.
Never mind. There is a codepath that does not initialize the new field
"prefix" properly. Fixing it now..
--
Duy
^ permalink raw reply
* Re: [PATCH v3 3/4] t7800: modernize tests
From: Johannes Sixt @ 2013-03-20 9:48 UTC (permalink / raw)
To: David Aguilar; +Cc: Junio C Hamano, git, Jonathan Nieder
In-Reply-To: <1361419428-22410-3-git-send-email-davvid@gmail.com>
Am 2/21/2013 5:03, schrieb David Aguilar:
> test_expect_success PERL 'difftool -d' '
> - diff=$(git difftool -d --extcmd ls branch) &&
> - echo "$diff" | stdin_contains sub &&
> - echo "$diff" | stdin_contains file
> + git difftool -d --extcmd ls branch >output &&
> + stdin_contains sub <output &&
> + stdin_contains file <output
> '
This test is broken on Windows. There is this code in git-difftool.perl
for my $file (@worktree) {
...
copy("$b/$file", "$workdir/$file") or
exit_cleanup($tmpdir, 1);
...
}
@worktree is populated with all files in the worktree. At this point,
"output" is among them. Then follows an attempt to copy a file over
"$workdir/$file". I guess that is some link+remove magic going on behind
the scenes. At any rate, this fails on Windows with
"D:/Src/mingw-git/t/trash directory.t7800-difftool/../../git-difftool line
408: Bad file number", because files that are open cannot be written from
outside (the file is open due to the redirection in the test snippet).
What is going on here? Why can this ever succeed even on Unix?
Same for some later tests.
BTW, while debugging this, I found the use of the helper function
stdin_contains() highly unhelpful; it just resolves to a 'grep' that on
top of all hides stdout. Please don't do that. Just use unadorned grep
like we do everywhere else.
-- Hannes
^ permalink raw reply
* Re: [PATCH jk/pkt-line-cleanup] t5700-clone-reference: send trace to fd 2, not 3, to please Windows git
From: Jeff King @ 2013-03-20 9:33 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Git Mailing List
In-Reply-To: <5149724C.3060105@viscovery.net>
On Wed, Mar 20, 2013 at 09:24:44AM +0100, Johannes Sixt wrote:
> From: Johannes Sixt <j6t@kdbg.org>
>
> Two tests use GIT_TRACE=3 to dump debugging information of git. On
> Windows, however, bash is unable to set up file descriptor 3 correctly
> for its child process, so that git reports "Bad file descriptor" on
> every trace attempt. The 'git clone' test succeeds nevertheless because
> an empty trace file remains, and there is only a check for the
> absence of a particular line. But the 'git fetch' process ultimately
> hangs (the dynamics that lead to this surprising result have not been
> investigated).
>
> Since we do not otherwise use stderr in the test cases, divert the
> trace dump to stderr.
I think that is OK, but I'm curious why this is a problem _now_, and not
with the code prior to 97a83fa8. The old GIT_DEBUG_SEND_PACK was also
just calling write() to descriptor 3.
> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
> ---
> This fixes a regression introduced in
...in 97a83fa8, I assume.
-Peff
^ permalink raw reply
* [PATCH jk/checkout-attribute-lookup] t2003: work around path mangling issue on Windows
From: Johannes Sixt @ 2013-03-20 8:47 UTC (permalink / raw)
To: Git Mailing List
From: Johannes Sixt <j6t@kdbg.org>
MSYS bash considers the part "/g" in the sed expression "s/./=/g" as an
absolute path after an assignment, and mangles it to a C:/something
string. Do not attract bash's attention by avoiding the equals sign.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
t/t2003-checkout-cache-mkdir.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/t/t2003-checkout-cache-mkdir.sh b/t/t2003-checkout-cache-mkdir.sh
index 4c97468..ff163cf 100755
--- a/t/t2003-checkout-cache-mkdir.sh
+++ b/t/t2003-checkout-cache-mkdir.sh
@@ -94,14 +94,14 @@ test_expect_success 'apply filter from working tree .gitattributes with --prefix
rm -fr path0 path1 path2 tmp* &&
mkdir path1 &&
mkdir tmp &&
- git config filter.replace-all.smudge "sed -e s/./=/g" &&
+ git config filter.replace-all.smudge "sed -e s/./,/g" &&
git config filter.replace-all.clean cat &&
git config filter.replace-all.required true &&
echo "file1 filter=replace-all" >path1/.gitattributes &&
git checkout-index --prefix=tmp/ -f -a &&
echo frotz >expected &&
test_cmp expected tmp/path0 &&
- echo ====== >expected &&
+ echo ,,,,,, >expected &&
test_cmp expected tmp/path1/file1
'
--
1.8.2.1433.g0074116
^ permalink raw reply related
* [PATCH jk/pkt-line-cleanup] t5700-clone-reference: send trace to fd 2, not 3, to please Windows git
From: Johannes Sixt @ 2013-03-20 8:24 UTC (permalink / raw)
To: Git Mailing List
From: Johannes Sixt <j6t@kdbg.org>
Two tests use GIT_TRACE=3 to dump debugging information of git. On
Windows, however, bash is unable to set up file descriptor 3 correctly
for its child process, so that git reports "Bad file descriptor" on
every trace attempt. The 'git clone' test succeeds nevertheless because
an empty trace file remains, and there is only a check for the
absence of a particular line. But the 'git fetch' process ultimately
hangs (the dynamics that lead to this surprising result have not been
investigated).
Since we do not otherwise use stderr in the test cases, divert the
trace dump to stderr.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
This fixes a regression introduced in
t/t5700-clone-reference.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index 9cd3b4d..8b5c58e 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -55,7 +55,7 @@ cd "$base_dir"
rm -f "$U.D"
test_expect_success 'cloning with reference (no -l -s)' \
-'GIT_TRACE_PACKET=3 git clone --reference B "file://$(pwd)/A" D 3>"$U.D"'
+'GIT_TRACE_PACKET=2 git clone --reference B "file://$(pwd)/A" D 2>"$U.D"'
test_expect_success 'fetched no objects' \
'! grep " want" "$U.D"'
@@ -173,7 +173,7 @@ test_expect_success 'fetch with incomplete alternates' '
(
cd K &&
git remote add J "file://$base_dir/J" &&
- GIT_TRACE_PACKET=3 git fetch J 3>"$U.K"
+ GIT_TRACE_PACKET=2 git fetch J 2>"$U.K"
) &&
master_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/master) &&
! grep " want $master_object" "$U.K" &&
--
1.8.2.1298.g2825a8e
^ permalink raw reply related
* [PATCH] t: don't redefine test_config() in various places
From: Ramkumar Ramachandra @ 2013-03-20 8:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git List
In-Reply-To: <7vk3p3jrrw.fsf@alter.siamese.dyndns.org>
test_config() is already a well-defined function in
test-lib-functions.sh. Don't duplicate it unnecessarily in:
t4018-diff-funcname.sh
t7810-grep.sh
t7811-grep-open.sh
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
Thanks, Junio.
t/t4018-diff-funcname.sh | 5 -----
t/t7810-grep.sh | 5 -----
t/t7811-grep-open.sh | 5 -----
3 files changed, 15 deletions(-)
diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index 082d3e8..38a092a 100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
@@ -93,11 +93,6 @@ sed -e '
s/song;/song();/
' <Beer.perl >Beer-correct.perl
-test_config () {
- git config "$1" "$2" &&
- test_when_finished "git config --unset $1"
-}
-
test_expect_funcname () {
lang=${2-java}
test_expect_code 1 git diff --no-index -U1 \
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index f698001..500eb50 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -1084,11 +1084,6 @@ test_expect_success 'grep -E pattern with grep.patternType=fixed' '
test_cmp expected actual
'
-test_config() {
- git config "$1" "$2" &&
- test_when_finished "git config --unset $1"
-}
-
cat >expected <<EOF
hello.c<RED>:<RESET>int main(int argc, const char **argv)
hello.c<RED>-<RESET>{
diff --git a/t/t7811-grep-open.sh b/t/t7811-grep-open.sh
index a895778..e1951a5 100755
--- a/t/t7811-grep-open.sh
+++ b/t/t7811-grep-open.sh
@@ -125,11 +125,6 @@ test_expect_success 'modified file' '
test_cmp empty out
'
-test_config() {
- git config "$1" "$2" &&
- test_when_finished "git config --unset $1"
-}
-
test_expect_success 'copes with color settings' '
rm -f actual &&
echo grep.h >expect &&
--
1.8.2
^ permalink raw reply related
* Re: USE_NSEC bug?
From: Jeff King @ 2013-03-20 7:53 UTC (permalink / raw)
To: Andrew Rodland; +Cc: git
In-Reply-To: <CABFQKmP6=Thhph4Ug+4LOBmzsVK42qBQYW2QHw87QD3019n+Kw@mail.gmail.com>
On Wed, Mar 20, 2013 at 02:36:32AM -0400, Andrew Rodland wrote:
> While investigating this StackOverflow question:
> http://stackoverflow.com/questions/15516168/how-to-cross-compile-git-for-arm
> I found that fetch-pack.c uses ST_MTIME_NSEC outside of the protection
> of #ifdef USE_NSEC. This results in a broken build if
> !defined(USE_NSEC) && !defined(NO_NSEC) and the target system doesn't
> happen to be recent glibc.
Right; the point of NO_NSEC is to tell git that your libc does not have
those fields. If it's not set, then it is a bug in your config.mak (or
in the autoconf script, if you are using it).
That being said, I really don't see the point of having both USE_NSEC
and NO_NSEC. If you do not set USE_NSEC (which most people do not; it is
off by default), what is the point of not setting NO_NSEC? As far as I
can tell, it means we will copy stat information out "struct st" into
the index, but we will not actually _use_ it for anything.
Should there just be a single option USE_NSEC that defaults to off? And
if it is not set, we do not even bother caring whether libc provides
nsec fields, since we are not going to use them for anything (i.e., we
just do the equivalent of NO_NSEC now).
Which I think is the direction you are proposing with your patches
below, but the rationale should be "why bother requiring users to use
the NO_NSEC knob explicitly when we know we do not care about its value
anyway".
But maybe there is some subtle reason I'm missing for having the two
options separate. Or maybe it's just a historical accident that we ended
up here.
-Peff
^ permalink raw reply
* USE_NSEC bug?
From: Andrew Rodland @ 2013-03-20 6:36 UTC (permalink / raw)
To: git
While investigating this StackOverflow question:
http://stackoverflow.com/questions/15516168/how-to-cross-compile-git-for-arm
I found that fetch-pack.c uses ST_MTIME_NSEC outside of the protection
of #ifdef USE_NSEC. This results in a broken build if
!defined(USE_NSEC) && !defined(NO_NSEC) and the target system doesn't
happen to be recent glibc.
I'm not sure where to pin the bug exactly — on fetch-pack.c, on
git-compat-util.h, on configure for not seeing if one of those fields
actually exists and setting NO_NSEC otherwise, or elsewhere, but I
would be tempted to fix it in one of the two below ways, which should
always be foolproof when !defined(USE_NSEC). That seems right to me,
since USE_NSEC is an experimental-ish feature.
Please Cc any replies as I'm not subscribed.
Way one (smaller diff for an uglier result):
--
diff --git a/git-compat-util.h b/git-compat-util.h
index 90e0372..222caaa 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -638,10 +638,13 @@ void git_qsort(void *base, size_t nmemb, size_t size,
# define FORCE_DIR_SET_GID 0
#endif
#ifdef NO_NSEC
#undef USE_NSEC
+#endif
+
+#ifndef USE_NSEC
#define ST_CTIME_NSEC(st) 0
#define ST_MTIME_NSEC(st) 0
#else
#ifdef USE_ST_TIMESPEC
#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))
--
Way two (bigger diff for a prettier result):
diff --git a/git-compat-util.h b/git-compat-util.h
index 90e0372..0a15b1a 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -638,20 +638,23 @@ void git_qsort(void *base, size_t nmemb, size_t size,
# define FORCE_DIR_SET_GID 0
#endif
#ifdef NO_NSEC
#undef USE_NSEC
-#define ST_CTIME_NSEC(st) 0
-#define ST_MTIME_NSEC(st) 0
-#else
-#ifdef USE_ST_TIMESPEC
-#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))
-#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec))
-#else
-#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec))
-#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec))
#endif
+
+#ifdef USE_NSEC
+# ifdef USE_ST_TIMESPEC
+# define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))
+# define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec))
+# else
+# define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec))
+# define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec))
+# endif
+#else /* !USE_NSEC */
+# define ST_CTIME_NSEC(st) 0
+# define ST_MTIME_NSEC(st) 0
#endif
#ifdef UNRELIABLE_FSTAT
#define fstat_is_reliable() 0
#else
^ permalink raw reply related
* Re: [PATCH 4/6] add -u: only show pathless 'add -u' warning when changes exist outside cwd
From: Jeff King @ 2013-03-20 5:06 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Junio C Hamano, Matthieu Moy, git,
Nguyễn Thái Ngọc Duy
In-Reply-To: <20130319225050.GE19014@google.com>
On Tue, Mar 19, 2013 at 03:50:50PM -0700, Jonathan Nieder wrote:
> This is the interesting one.
> [...]
> * summarized Peff's review with an Ack. I hope that's ok.
Yeah, OK with me. I certainly agree with the intent, and I think your
reasoning on the performance change is valid.
I don't see anything wrong in the patch itself, except for one minor
nit:
> @@ -121,17 +140,30 @@ static void update_callback(struct diff_queue_struct *q,
> }
> }
>
> +#define ADD_CACHE_IMPLICIT_DOT 32
> int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
> {
> struct update_callback_data data;
> struct rev_info rev;
Should this be defined in cache.h with the other flags? I realize it's
mostly private to builtin/add.c, but without even a comment in cache.h
saying "/* 32 is reserved */", we run the risk of another commit
adding a new flag with the same number.
-Peff
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox