* [PATCH 4/6] push, send-pack: support pushing HEAD to real ref name
From: Steffen Prohaska @ 2007-10-14 8:54 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <11923520853189-git-send-email-prohaska@zib.de>
This teaches "push <remote> HEAD" to resolve HEAD on the local
side to its real ref name, e.g. refs/heads/master, and then
use the real ref name on the remote side to search a matching
remote ref.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
remote.c | 18 +++++++++++++-----
t/t5516-fetch-push.sh | 22 ++++++++++++++++++++++
2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/remote.c b/remote.c
index 36071b2..58bc019 100644
--- a/remote.c
+++ b/remote.c
@@ -439,6 +439,8 @@ static struct ref *try_explicit_object_name(const char *name)
unsigned char sha1[20];
struct ref *ref;
int len;
+ char *real_name = 0;
+ const char *best_name;
if (!*name) {
ref = alloc_ref(20);
@@ -446,12 +448,17 @@ static struct ref *try_explicit_object_name(const char *name)
hashclr(ref->new_sha1);
return ref;
}
- if (get_sha1(name, sha1))
+ if (get_sha1_with_real_ref(name, sha1, &real_name))
return NULL;
- len = strlen(name) + 1;
+ best_name = real_name ? real_name : name;
+ len = strlen(best_name) + 1;
ref = alloc_ref(len);
- memcpy(ref->name, name, len);
+ memcpy(ref->name, best_name, len);
hashcpy(ref->new_sha1, sha1);
+
+ if (real_name) {
+ free(real_name);
+ }
return ref;
}
@@ -475,6 +482,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
struct ref *matched_src, *matched_dst;
const char *dst_value = rs->dst;
+ const char * const orig_dst_value = rs->dst ? rs->dst : rs->src;
if (rs->pattern)
return errs;
@@ -511,12 +519,12 @@ static int match_explicit(struct ref *src, struct ref *dst,
case 1:
break;
case 0:
- if (!memcmp(rs->dst ? rs->dst : rs->src , "refs/", 5))
+ if (!memcmp(orig_dst_value , "refs/", 5))
matched_dst = make_linked_ref(dst_value, dst_tail);
else
error("dst refspec %s does not match any "
"existing ref on the remote and does "
- "not start with refs/.", rs->dst ? rs->dst : rs->src);
+ "not start with refs/.", orig_dst_value);
break;
default:
matched_dst = NULL;
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 8629cf2..97a032e 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -274,4 +274,26 @@ test_expect_success 'push with colon-less refspec (4)' '
'
+test_expect_success 'push with HEAD' '
+
+ mk_test heads/master &&
+ git push testrepo HEAD &&
+ check_push_result $the_commit heads/master
+
+'
+
+test_expect_success 'push with HEAD not existing at remote' '
+
+ mk_test heads/master &&
+ git checkout -b local master &&
+ if git push testrepo HEAD
+ then
+ echo "Oops, should have failed"
+ false
+ else
+ check_push_result $the_first_commit heads/master
+ fi
+
+'
+
test_done
--
1.5.3.4.224.gc6b84
^ permalink raw reply related
* [PATCH 6/6] push, send-pack: use same rules as git-rev-parse to resolve refspecs
From: Steffen Prohaska @ 2007-10-14 8:54 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <11923520853014-git-send-email-prohaska@zib.de>
This commit changes the rules for resolving refspecs to match the
rules for resolving refs in rev-parse. git-rev-parse uses clear rules
to resolve a short ref to its full name, which are well documented.
The rules for resolving refspecs documented in git-send-pack were
less strict and harder to understand. This commit replaces them by
the rules of git-rev-parse.
The unified rules are easier to understand and better resolve ambiguous
cases. You can now push from a repository containing several branches
ending on the same short name.
Note, this breaks existing setups. For example "master" will no longer
resolve to "origin/master".
TODO: this patch does not yet include a modified documentation of
git-send-pack. I prefer to wait for some comments first.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
remote.c | 5 +----
t/t5516-fetch-push.sh | 12 +++++++++++-
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/remote.c b/remote.c
index 58bc019..09cb611 100644
--- a/remote.c
+++ b/remote.c
@@ -383,10 +383,7 @@ static int count_refspec_match(const char *pattern,
char *name = refs->name;
int namelen = strlen(name);
- if (namelen < patlen ||
- memcmp(name + namelen - patlen, pattern, patlen))
- continue;
- if (namelen != patlen && name[namelen - patlen - 1] != '/')
+ if (ref_cmp_full_short(name, pattern))
continue;
/* A match is "weak" if it is with refs outside
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 97a032e..2664060 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -175,11 +175,21 @@ test_expect_success 'push with no ambiguity (1)' '
test_expect_success 'push with no ambiguity (2)' '
mk_test remotes/origin/master &&
- git push testrepo master:master &&
+ git push testrepo master:origin/master &&
check_push_result $the_commit remotes/origin/master
'
+test_expect_success 'push with colon-less refspec, no ambiguity' '
+
+ mk_test heads/master heads/t/master &&
+ git branch -f t/master master &&
+ git push testrepo master &&
+ check_push_result $the_commit heads/master &&
+ check_push_result $the_first_commit heads/t/master
+
+'
+
test_expect_success 'push with weak ambiguity (1)' '
mk_test heads/master remotes/origin/master &&
--
1.5.3.4.224.gc6b84
^ permalink raw reply related
* [PATCH 5/6] add ref_cmp_full_short() comparing full ref name with a short name
From: Steffen Prohaska @ 2007-10-14 8:54 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <11923520851656-git-send-email-prohaska@zib.de>
ref_cmp_full_short(full_name, short_name) expands short_name according
to the rules documented in git-rev-parse and compares the expanded
name with full_name. It reports a match by returning 0.
This function makes the rules for resolving refs to sha1s available
for string comparison. Before this change, the rules were buried in
get_sha1*() and dwim_ref().
ref_cmp_full_short() will be used for matching refspecs in git-send-pack.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
cache.h | 1 +
sha1_name.c | 13 +++++++++++++
2 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/cache.h b/cache.h
index f98d57a..59345b5 100644
--- a/cache.h
+++ b/cache.h
@@ -406,6 +406,7 @@ extern int get_sha1_hex(const char *hex, unsigned char *sha1);
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
extern int read_ref(const char *filename, unsigned char *sha1);
extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *);
+extern int ref_cmp_full_short(const char *full_name, const char* short_name);
extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
diff --git a/sha1_name.c b/sha1_name.c
index b820909..ae235be 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -249,6 +249,19 @@ static const char *ref_fmt[] = {
NULL
};
+int ref_cmp_full_short(const char* full_name, const char* short_name)
+{
+ const char **p;
+ const int short_name_len = strlen(short_name);
+
+ for (p = ref_fmt; *p; p++) {
+ if (strcmp(full_name, mkpath(*p, short_name_len, short_name)) == 0) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
{
const char **p, *r;
--
1.5.3.4.224.gc6b84
^ permalink raw reply related
* [PATCH 1/6 v2] push, send-pack: fix test if remote branch exists for colon-less refspec
From: Steffen Prohaska @ 2007-10-14 9:04 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <1192352085653-git-send-email-prohaska@zib.de>
A push must fail if the remote ref does not yet exist and the refspec
does not start with refs/. Remote refs must explicitly be created with
their full name.
This commit adds some tests and fixes the existence check in send-pack.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
remote.c | 5 +++--
t/t5516-fetch-push.sh | 34 ++++++++++++++++++++++++++++++++--
2 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/remote.c b/remote.c
index bb774d0..f26f0e0 100644
--- a/remote.c
+++ b/remote.c
@@ -475,6 +475,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
struct ref *matched_src, *matched_dst;
const char *dst_value = rs->dst;
+ const char * const orig_dst_value = rs->dst ? rs->dst : rs->src;
if (rs->pattern)
return errs;
@@ -511,12 +512,12 @@ static int match_explicit(struct ref *src, struct ref *dst,
case 1:
break;
case 0:
- if (!memcmp(dst_value, "refs/", 5))
+ if (!memcmp(orig_dst_value , "refs/", 5))
matched_dst = make_linked_ref(dst_value, dst_tail);
else
error("dst refspec %s does not match any "
"existing ref on the remote and does "
- "not start with refs/.", dst_value);
+ "not start with refs/.", orig_dst_value);
break;
default:
matched_dst = NULL;
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index ca46aaf..8629cf2 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -126,6 +126,36 @@ test_expect_success 'push with wildcard' '
)
'
+test_expect_success 'push nonexisting (1)' '
+
+ mk_test &&
+ if git push testrepo master
+ then
+ echo "Oops, should have failed"
+ false
+ fi
+
+'
+
+test_expect_success 'push nonexisting (2)' '
+
+ mk_test &&
+ if git push testrepo heads/master
+ then
+ echo "Oops, should have failed"
+ false
+ fi
+
+'
+
+test_expect_success 'push nonexisting (3)' '
+
+ mk_test &&
+ git push testrepo refs/heads/master &&
+ check_push_result $the_commit heads/master
+
+'
+
test_expect_success 'push with matching heads' '
mk_test heads/master &&
@@ -225,7 +255,7 @@ test_expect_success 'push with colon-less refspec (3)' '
git tag -d frotz
fi &&
git branch -f frotz master &&
- git push testrepo frotz &&
+ git push testrepo refs/heads/frotz &&
check_push_result $the_commit heads/frotz &&
test 1 = $( cd testrepo && git show-ref | wc -l )
'
@@ -238,7 +268,7 @@ test_expect_success 'push with colon-less refspec (4)' '
git branch -D frotz
fi &&
git tag -f frotz &&
- git push testrepo frotz &&
+ git push testrepo refs/tags/frotz &&
check_push_result $the_commit tags/frotz &&
test 1 = $( cd testrepo && git show-ref | wc -l )
--
1.5.3.4.224.gc6b84
^ permalink raw reply related
* Re: change push's refspec behavior to match rev-parse
From: Steffen Prohaska @ 2007-10-14 9:04 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <11923520851713-git-send-email-prohaska@zib.de>
On Oct 14, 2007, at 10:54 AM, Steffen Prohaska wrote:
>
>
> [PATCH 1/6] push, send-pack: fix test if remote branch exists for
> colon-less refspec
>
> This is a bug fix that should go to maint. All following patches
> modifying
> the push test script require this.
>
> [PATCH 4/6] push, send-pack: support pushing HEAD to real ref name
>
> Requires 1/6.
These two patches got mixed. I'll send updated versions in a minute.
Sorry for the noise,
Steffen
^ permalink raw reply
* [PATCH 4/6 v2] push, send-pack: support pushing HEAD to real ref name
From: Steffen Prohaska @ 2007-10-14 9:05 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <11923520851656-git-send-email-prohaska@zib.de>
This teaches "push <remote> HEAD" to resolve HEAD on the local
side to its real ref name, e.g. refs/heads/master, and then
use the real ref name on the remote side to search a matching
remote ref.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
remote.c | 13 ++++++++++---
t/t5516-fetch-push.sh | 22 ++++++++++++++++++++++
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/remote.c b/remote.c
index f26f0e0..58bc019 100644
--- a/remote.c
+++ b/remote.c
@@ -439,6 +439,8 @@ static struct ref *try_explicit_object_name(const char *name)
unsigned char sha1[20];
struct ref *ref;
int len;
+ char *real_name = 0;
+ const char *best_name;
if (!*name) {
ref = alloc_ref(20);
@@ -446,12 +448,17 @@ static struct ref *try_explicit_object_name(const char *name)
hashclr(ref->new_sha1);
return ref;
}
- if (get_sha1(name, sha1))
+ if (get_sha1_with_real_ref(name, sha1, &real_name))
return NULL;
- len = strlen(name) + 1;
+ best_name = real_name ? real_name : name;
+ len = strlen(best_name) + 1;
ref = alloc_ref(len);
- memcpy(ref->name, name, len);
+ memcpy(ref->name, best_name, len);
hashcpy(ref->new_sha1, sha1);
+
+ if (real_name) {
+ free(real_name);
+ }
return ref;
}
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 8629cf2..97a032e 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -274,4 +274,26 @@ test_expect_success 'push with colon-less refspec (4)' '
'
+test_expect_success 'push with HEAD' '
+
+ mk_test heads/master &&
+ git push testrepo HEAD &&
+ check_push_result $the_commit heads/master
+
+'
+
+test_expect_success 'push with HEAD not existing at remote' '
+
+ mk_test heads/master &&
+ git checkout -b local master &&
+ if git push testrepo HEAD
+ then
+ echo "Oops, should have failed"
+ false
+ else
+ check_push_result $the_first_commit heads/master
+ fi
+
+'
+
test_done
--
1.5.3.4.224.gc6b84
^ permalink raw reply related
* Re: [PATCH 0/14] fork/exec removal series
From: Andreas Ericsson @ 2007-10-14 9:10 UTC (permalink / raw)
To: Pierre Habouzit, Shawn O. Pearce, Johannes Schindelin,
Johannes Sixt, gitster
In-Reply-To: <20071014072849.GD1198@artemis.corp>
Pierre Habouzit wrote:
> On dim, oct 14, 2007 at 07:17:51 +0000, Pierre Habouzit wrote:
>> On dim, oct 14, 2007 at 07:12:39 +0000, Pierre Habouzit wrote:
>>> The trivial way is to add a __thread keyword to make them TLS
>>> variables, though, it's not really a step in the direction of
>>> portability, and last time I looked at it, mingw didn't had TLS support,
>>> not sure if msys has. Though, if Msys has, it's worth using, and we
>> Okay forget it, mingw and msys are one and the same *g*.
>> So well, maybe threading isn't such a so great idea :/
>
> And again last time I checked it was still a mingw 3.x in debian, now
> that it's 4.2.1 it seems to support __thread (but not
> __declspec(thread)) and their changelog seems to confirm that fact [0].
>
> So the question holds again, do we require pthread-using targets to
> support TLS ? It feels sane and right to me, but …
>
To me it's a sane place to start. As time goes by and people on non-TLS
capable systems come along that need the functionality (or the speedup;
fork() is expensive on some systems), they can probably implement it
themselves or at least give voice to the fact that they need it.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [RFC] CLI option parsing and usage generation for porcelains
From: Eric Wong @ 2007-10-14 9:18 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: git
In-Reply-To: <1192282153-26684-1-git-send-email-madcoder@debian.org>
Pierre Habouzit <madcoder@debian.org> wrote:
> Following Kristian momentum, I've reworked his parse_option module
> quite a lot, and now have some quite interesting features. The series is
> available from git://git.madism.org/git.git (branch ph/strbuf).
>
> The following series is open for comments, it's not 100% ready for
> inclusion IMHO, as some details may need to be sorted out first, and
> that I've not re-read the patches thoroughly yet. Though I uses the tip
> of that branch as my everyday git for 2 weeks or so without any
> noticeable issues.
>
> And as examples are always easier to grok:
>
> $ git fetch -h
> usage: git-fetch [options] [<repository> <refspec>...]
>
> -q, --quiet be quiet
> -v, --verbose be verbose
>
> -a, --append append in .git/FETCH_HEAD
> -f, --force force non fast-forwards updates
> --no-tags don't follow tags at all
> -t, --tags fetch all tags
> --depth <depth> deepen history of a shallow clone
>
> Advanced Options
> -k, --keep keep downloaded pack
> -u, --update-head-ok allow to update the head in the current branch
> --upload-pack <path> path to git-upload-pack on the remote
>
> $ git rm -rf xdiff # yeah -rf now works !
Very nice. I worked on gitopt around summer of 2006 but never had the
time to test it thoroughly. It was a _lot_ more intrusive than yours
currently is (it touched the diff + revision family of commands).
One feature I really like is automatically handling of long option
abbreviations. gitopt supported this at the expense of complexity
and the aforementioned intrusivenes. This allows automatic handling
of the abbreviation style seen commonly in git shell scripts:
--a|--am|--ame|--amen|--amend) (from git-commit.sh)
--
Eric Wong
^ permalink raw reply
* Re: Git User's Survey 2007 unfinished summary continued
From: David Kastrup @ 2007-10-14 9:21 UTC (permalink / raw)
To: Andreas Ericsson
Cc: Johannes Schindelin, Linus Torvalds, J. Bruce Fields,
Jakub Narebski, git
In-Reply-To: <4711D72B.2080107@op5.se>
Andreas Ericsson <ae@op5.se> writes:
> I also think Linus made a very wise decision in picking Junio to
> maintain it. So far, I haven't seen him accept a single
> feature-patch into git that wasn't explained to solve a specific
> problem.
While I hold Junio's technical judgment in high regard, it is actually
the area of communication skills and conversation tone where I would
really wish more to follow his example.
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
^ permalink raw reply
* Re: [PATCH 14/14] Use the asyncronous function infrastructure to run the content filter.
From: Johannes Sixt @ 2007-10-14 9:39 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, gitster
In-Reply-To: <Pine.LNX.4.64.0710140404480.25221@racer.site>
On Sunday 14 October 2007 05:07, Johannes Schindelin wrote:
> Hi,
>
> On Sat, 13 Oct 2007, Johannes Sixt wrote:
> > status = finish_command(&child_process);
> > if (status)
> > - error("external filter %s failed %d", cmd, -status);
> > + error("external filter %s failed", params->cmd);
>
> Did you mean to remove the status from the output (it should probably read
> "(exit status %d)" instead of just "%d", but an exit status can help
> identify problems, right?
Oops, that looks like an artefact. Will correct.
> > + if (start_async(&async))
> > + return 0; /* error was already reported */
>
> Please write "return NULL;"
Will do.
-- Hannes
^ permalink raw reply
* Re: [PATCH 01/14] Change git_connect() to return a struct child_process instead of a pid_t.
From: Johannes Sixt @ 2007-10-14 9:40 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, gitster
In-Reply-To: <Pine.LNX.4.64.0710140156100.25221@racer.site>
On Sunday 14 October 2007 02:57, Johannes Schindelin wrote:
> Hi,
>
> On Sat, 13 Oct 2007, Johannes Sixt wrote:
> > -int finish_connect(pid_t pid)
> > +int finish_connect(struct child_process *conn)
> > {
> > - if (pid == 0)
> > + if (conn == NULL)
> > return 0;
> >
> > - while (waitpid(pid, NULL, 0) < 0) {
> > + while (waitpid(conn->pid, NULL, 0) < 0) {
> > if (errno != EINTR)
> > return -1;
>
> Just for completeness' sake: could you do a free(conn); before return -1;?
I know. But the loop is going away with the next patch, so I didn't bother.
Can you live with that?
-- Hannes
^ permalink raw reply
* Re: [PATCH 1/2] instaweb: allow for use of auto-generated scripts
From: Eric Wong @ 2007-10-14 9:49 UTC (permalink / raw)
To: mike; +Cc: Junio C Hamano, git
In-Reply-To: <55e906d58f15c79c61d83ad4c52ef085de8ad736.1191687881.git.mike@csa.net>
mike@csa.net wrote:
> this patch allows scripts that reside in $fqgitdir/gitweb to be used
> for firing up an instaweb server. this lays the groundwork for
> extending instaweb support to non-standard web servers, which may
> require a script for proper invocation.
>
> Signed-off-by: Mike Dalessio <mike@csa.net>
Thanks, sorry for the late reply, it slipped my mind for a while.
Both patches in this series:
Acked-by: Eric Wong <normalperson@yhbt.net>
> ---
> git-instaweb.sh | 4 +++-
> 1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/git-instaweb.sh b/git-instaweb.sh
> index b79c6b6..42d9c34 100755
> --- a/git-instaweb.sh
> +++ b/git-instaweb.sh
> @@ -37,7 +37,9 @@ start_httpd () {
> else
> # many httpds are installed in /usr/sbin or /usr/local/sbin
> # these days and those are not in most users $PATHs
> - for i in /usr/local/sbin /usr/sbin
> + # in addition, we may have generated a server script
> + # in $fqgitdir/gitweb.
> + for i in /usr/local/sbin /usr/sbin "$fqgitdir/gitweb"
> do
> if test -x "$i/$httpd_only"
> then
> --
--
Eric Wong
^ permalink raw reply
* Re: [RFC] CLI option parsing and usage generation for porcelains
From: Pierre Habouzit @ 2007-10-14 9:57 UTC (permalink / raw)
To: Eric Wong; +Cc: git
In-Reply-To: <20071014091855.GA17397@soma>
[-- Attachment #1: Type: text/plain, Size: 3121 bytes --]
On Sun, Oct 14, 2007 at 09:18:55AM +0000, Eric Wong wrote:
> Pierre Habouzit <madcoder@debian.org> wrote:
> > Following Kristian momentum, I've reworked his parse_option module
> > quite a lot, and now have some quite interesting features. The series is
> > available from git://git.madism.org/git.git (branch ph/strbuf).
> >
> > The following series is open for comments, it's not 100% ready for
> > inclusion IMHO, as some details may need to be sorted out first, and
> > that I've not re-read the patches thoroughly yet. Though I uses the tip
> > of that branch as my everyday git for 2 weeks or so without any
> > noticeable issues.
> >
> > And as examples are always easier to grok:
> >
> > $ git fetch -h
> > usage: git-fetch [options] [<repository> <refspec>...]
> >
> > -q, --quiet be quiet
> > -v, --verbose be verbose
> >
> > -a, --append append in .git/FETCH_HEAD
> > -f, --force force non fast-forwards updates
> > --no-tags don't follow tags at all
> > -t, --tags fetch all tags
> > --depth <depth> deepen history of a shallow clone
> >
> > Advanced Options
> > -k, --keep keep downloaded pack
> > -u, --update-head-ok allow to update the head in the current branch
> > --upload-pack <path> path to git-upload-pack on the remote
> >
> > $ git rm -rf xdiff # yeah -rf now works !
>
> Very nice. I worked on gitopt around summer of 2006 but never had the
> time to test it thoroughly. It was a _lot_ more intrusive than yours
> currently is (it touched the diff + revision family of commands).
>
> One feature I really like is automatically handling of long option
> abbreviations. gitopt supported this at the expense of complexity
> and the aforementioned intrusivenes. This allows automatic handling
> of the abbreviation style seen commonly in git shell scripts:
>
> --a|--am|--ame|--amen|--amend) (from git-commit.sh)
Yes, but if you do that, you can't order options in the order you
want (because of first match issues), making the help dumps hopelessly
random. I prefer exact match, especially since your shell can help you
autocomplete the proper command.
I intend to have some magic in the parse_options module to dump the
options in a machine parseable way, so that zsh/bash completion for the
parseopt aware commands is almost trivial. (this was requested from one
of the zsh upstream developpers, and it definitely make sense).
Note that I didn't migrated all the commands yet especially not
diff.c, We'll need a new construct for that: embedding a struct options
array into another to inherit its flags, though I'm not sure it's
enough, as a struct options right now embeds pointers to the variables
it fills, which doesn't work with the "pure" `diff_opt_parse` approach
right now. But I'm sure I'll come up with something :)
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Git User's Survey 2007 unfinished summary continued
From: Reece Dunn @ 2007-10-14 10:20 UTC (permalink / raw)
To: Shawn O. Pearce
Cc: Linus Torvalds, Johannes Schindelin, J. Bruce Fields,
Jakub Narebski, git
In-Reply-To: <20071014014445.GN27899@spearce.org>
On 14/10/2007, Shawn O. Pearce <spearce@spearce.org> wrote:
> But just saying "MY GOD FIX THE UI" is not a wishlist item (yes,
> that was a real survey answer). It provides the community no
> chance to understand what parts of the UI we need to work on, and
> what parts the end-user is OK with or just hasn't even tried to use.
My interpretation of that answer is that your average user
(specifically Windows user) is more focused on a graphical interface,
and will mean GUI when they say UI.
The core plumbing in git is solid. The porcelain, with the 1.5 series,
makes git simpler to use from the command line. Now, the GUI available
for git is seriously lacking.
If you look at the GUI tools available for CVS, SVN, Perforce and
others, these offer you the complete functionality of those tools from
within them. They provide command line tools for those that need them,
but also come with a GUI application that allows the user to manage
their files within the source control system they are using (e.g.
WinCVS and P4V), shell integration (e.g. TortoiseCVS/SVN), IDE
integration and others.
At the moment, git has a good timeline view of commits through the
GUI, but have found the mingw version to be slow in places (I can't
remember when, but was likely before some performance improvements in
that area were made) and haven't tried out the Linux version yet. This
is a good starting point to build on, but to be more useful it needs
to extend to all of git's functionality.
- Reece
^ permalink raw reply
* [PATCH] git-add (-a|-u) and -n support
From: Michael Witten @ 2007-10-14 10:26 UTC (permalink / raw)
To: git
Hello,
The git-add command doesn't handle -n when using -u.
I fixed this and added -a for adding ALL files, not
just those below the current directory (just like
git-commit).
The patch is below, but you can also download it from
http://web.mit.edu/mfwitten/git/0001-git-add-now-understands-two-
kinds-of-update.patch
From acc846f5243d26a96aaf0bf1c4f04ecc021385a2 Mon Sep 17 00:00:00 2001
From: Michael Witten <mfwitten@mit.edu>
Date: Sun, 14 Oct 2007 06:13:20 -0400
Subject: [PATCH] git-add now understands two kinds of update:
-u: update as before
-a: update all as in a true 'git commit -a'
Also, -n works correctly now with the above options.
Signed-off-by: Michael Witten <mfwitten@mit.edu>
---
builtin-add.c | 69 +++++++++++++++++++++++++++++++++++++
+-------------------
1 files changed, 46 insertions(+), 23 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index f9a6580..24887c7 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -13,10 +13,11 @@
#include "commit.h"
#include "revision.h"
+enum update_type {NONE, ALL, CURRENT_DIRECTORY};
+
static const char builtin_add_usage[] =
"git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--]
<filepattern>...";
-static int take_worktree_changes;
static const char *excludes_file;
static void prune_directory(struct dir_struct *dir, const char
**pathspec, int prefix)
@@ -83,40 +84,57 @@ static void fill_directory(struct dir_struct
*dir, const char **pathspec,
static void update_callback(struct diff_queue_struct *q,
struct diff_options *opt, void *cbdata)
{
- int i, verbose;
-
- verbose = *((int *)cbdata);
+ int i;
+
+ int* options = (int*)cbdata;
+ int verbose = options[0];
+ int show_only = options[1];
+
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
const char *path = p->one->path;
- switch (p->status) {
- default:
- die("unexpected diff status %c", p->status);
- case DIFF_STATUS_UNMERGED:
- case DIFF_STATUS_MODIFIED:
- case DIFF_STATUS_TYPE_CHANGED:
- add_file_to_cache(path, verbose);
- break;
- case DIFF_STATUS_DELETED:
- remove_file_from_cache(path);
- if (verbose)
- printf("remove '%s'\n", path);
- break;
+
+ switch (p->status) {
+ case DIFF_STATUS_UNMERGED:
+ case DIFF_STATUS_MODIFIED:
+ case DIFF_STATUS_TYPE_CHANGED:
+ if (show_only)
+ printf("add '%s'\n", path);
+ else
+ add_file_to_cache(path, verbose);
+ break;
+
+ case DIFF_STATUS_DELETED:
+ if (show_only)
+ remove_file_from_cache(path);
+ if (verbose)
+ printf("remove '%s'\n", path);
+ break;
+
+ default:
+ die("unexpected diff status %c", p->status);
}
}
}
-static void update(int verbose, const char *prefix, const char **files)
+static void update(enum update_type type, int verbose, int show_only,
+ const char *prefix, const char **files)
{
struct rev_info rev;
+ int callback_options[] = {verbose, show_only};
+
init_revisions(&rev, prefix);
setup_revisions(0, NULL, &rev, NULL);
- rev.prune_data = get_pathspec(prefix, files);
+
+ rev.prune_data = type == ALL ? NULL : get_pathspec(prefix, files);
+
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback;
- rev.diffopt.format_callback_data = &verbose;
+ rev.diffopt.format_callback_data = callback_options;
+
if (read_cache() < 0)
die("index file corrupt");
+
run_diff_files(&rev, 0);
}
@@ -158,6 +176,7 @@ int cmd_add(int argc, const char **argv, const
char *prefix)
{
int i, newfd;
int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
+ enum update_type update_type = NONE;
const char **pathspec;
struct dir_struct dir;
int add_interactive = 0;
@@ -201,8 +220,12 @@ int cmd_add(int argc, const char **argv, const
char *prefix)
verbose = 1;
continue;
}
+ if (!strcmp(arg, "-a")) {
+ update_type = ALL;
+ continue;
+ }
if (!strcmp(arg, "-u")) {
- take_worktree_changes = 1;
+ update_type = CURRENT_DIRECTORY;
continue;
}
if (!strcmp(arg, "--refresh")) {
@@ -212,8 +235,8 @@ int cmd_add(int argc, const char **argv, const
char *prefix)
usage(builtin_add_usage);
}
- if (take_worktree_changes) {
- update(verbose, prefix, argv + i);
+ if (update_type) {
+ update(update_type, verbose, show_only, prefix, argv + i);
goto finish;
}
--
1.5.3.4.206.g58ba4-dirty
^ permalink raw reply related
* How to manage heads on a remote repository?
From: Theodore Ts'o @ 2007-10-14 10:46 UTC (permalink / raw)
To: git
I'm currently exploring the idea of not only making the equivalent of
"pu" and "next" available on a public repository for one of my projects,
but also the topics/* branches. When thinking about how I might do
this, one snag I ran into is that the topics/foo and topics/bar branches
are ephemeral, and so when I replicate them to a remote repository,
either on kernel.org or repo.or.cz, I would need a way of removing a
head for a topic branch that had already been merged.
Creating new topics/foo branch or updating is easy; just do a git push,
and they will get created on the remote side. I don't see an easy way
of deleting a ref on a remote branch, so any automation at the moment
looks like it would require me writing my own script and using something
like this:
ssh remote-host git --git-dir=xxx branch -D topics/foo
... which of course wouldn't work repo.or.cz since it requires shell
access.
Am I missing anything?
- Ted
^ permalink raw reply
* Re: How to manage heads on a remote repository?
From: Michael Witten @ 2007-10-14 10:55 UTC (permalink / raw)
To: git; +Cc: Theodore Ts'o
In-Reply-To: <E1Ih0zJ-0004FZ-0A@tinytim.thunk.org>
On 14 Oct 2007, at 6:46:25 AM, Theodore Ts'o wrote:
> so any automation at the moment
> looks like it would require me writing my own script and using
> something
> like this:
>
> ssh remote-host git --git-dir=xxx branch -D topics/foo
>
> ... which of course wouldn't work repo.or.cz since it requires shell
> access.
>
> Am I missing anything?
With my little exposure to git, I'd say it's not currently possible
with the git ui, but please wait for someone more authoritative to
say so.
In any case, I've run across similar problems, and I think this is
a good time to point out the feature that would be nice:
All (most) git ui operations should be (relatively)
transparent across networks;
I would like to clone to a remote server, for instance.
Michael Witten
^ permalink raw reply
* Re: How to manage heads on a remote repository?
From: David Symonds @ 2007-10-14 11:03 UTC (permalink / raw)
To: Theodore Ts'o; +Cc: git
In-Reply-To: <E1Ih0zJ-0004FZ-0A@tinytim.thunk.org>
On 14/10/2007, Theodore Ts'o <tytso@mit.edu> wrote:
>
> I'm currently exploring the idea of not only making the equivalent of
> "pu" and "next" available on a public repository for one of my projects,
> but also the topics/* branches. When thinking about how I might do
> this, one snag I ran into is that the topics/foo and topics/bar branches
> are ephemeral, and so when I replicate them to a remote repository,
> either on kernel.org or repo.or.cz, I would need a way of removing a
> head for a topic branch that had already been merged.
git push <remote> :<branch_name>
If the left side of the colon in a push refspec is empty, it deletes
the remote ref given by the right hand side.
Dave.
^ permalink raw reply
* Re: How to manage heads on a remote repository?
From: Theodore Tso @ 2007-10-14 11:07 UTC (permalink / raw)
To: David Symonds; +Cc: git
In-Reply-To: <ee77f5c20710140403j7a88ffa4q579a8c4118d8fd71@mail.gmail.com>
On Sun, Oct 14, 2007 at 09:03:48PM +1000, David Symonds wrote:
> On 14/10/2007, Theodore Ts'o <tytso@mit.edu> wrote:
> >
> > I'm currently exploring the idea of not only making the equivalent of
> > "pu" and "next" available on a public repository for one of my projects,
> > but also the topics/* branches. When thinking about how I might do
> > this, one snag I ran into is that the topics/foo and topics/bar branches
> > are ephemeral, and so when I replicate them to a remote repository,
> > either on kernel.org or repo.or.cz, I would need a way of removing a
> > head for a topic branch that had already been merged.
>
> git push <remote> :<branch_name>
>
> If the left side of the colon in a push refspec is empty, it deletes
> the remote ref given by the right hand side.
Cool, thanks! It's not in the git-push man page. I'll play with it
some and then submit a patch update the man page.
- Ted
^ permalink raw reply
* Re: How to manage heads on a remote repository?
From: David Symonds @ 2007-10-14 11:12 UTC (permalink / raw)
To: Theodore Tso; +Cc: git
In-Reply-To: <20071014110714.GA17368@thunk.org>
On 14/10/2007, Theodore Tso <tytso@mit.edu> wrote:
> On Sun, Oct 14, 2007 at 09:03:48PM +1000, David Symonds wrote:
> > git push <remote> :<branch_name>
> >
> > If the left side of the colon in a push refspec is empty, it deletes
> > the remote ref given by the right hand side.
>
> Cool, thanks! It's not in the git-push man page. I'll play with it
> some and then submit a patch update the man page.
Yes, it is, including in the examples section. Under the <refspec>
options description it says:
Pushing an empty <src> allows you to delete the <dst> ref from
the remote repository.
In the examples section, it says:
git push origin :experimental
Find a ref that matches experimental in the origin repository
(e.g. refs/heads/experimental), and delete it.
Dave.
^ permalink raw reply
* Re: How to manage heads on a remote repository?
From: Theodore Tso @ 2007-10-14 11:32 UTC (permalink / raw)
To: David Symonds; +Cc: git
In-Reply-To: <ee77f5c20710140412s1eb68991ke552995dbbd226b@mail.gmail.com>
On Sun, Oct 14, 2007 at 09:12:43PM +1000, David Symonds wrote:
> On 14/10/2007, Theodore Tso <tytso@mit.edu> wrote:
> > On Sun, Oct 14, 2007 at 09:03:48PM +1000, David Symonds wrote:
> > > git push <remote> :<branch_name>
> > >
> > > If the left side of the colon in a push refspec is empty, it deletes
> > > the remote ref given by the right hand side.
> >
> > Cool, thanks! It's not in the git-push man page. I'll play with it
> > some and then submit a patch update the man page.
>
> Yes, it is, including in the examples section.
Wow, I completely missed that! It would be nice if:
<refspec>
The canonical format of a <refspec> parameter is +?<src>:<dst>; that
is, an optional plus +, followed by the source ref, followed by a
colon :, followed by the destination ref.
.... mentioned that the source ref could be optional (just like it
explicitly says the '+' is optional)...
The <src> side can be an arbitrary "SHA1 expression" that can be
used as an argument to git-cat-file -t. E.g. master~4 (push four
parents before the current master head).
.... and I think the throwaway sentence at the end of the refspec
would be better at the end of the second paragraph above. I'll send a
patch.
Thanks for pointing that out!
- Ted
^ permalink raw reply
* Re: [PATCH] Add color to git-add--interactive diffs (Take 2: now without spurious line break!)
From: Wincent Colaiuta @ 2007-10-14 11:36 UTC (permalink / raw)
To: Tom Tobin; +Cc: Git Mailing List
In-Reply-To: <1192351494.7226.18.camel@athena>
El 14/10/2007, a las 10:44, Tom Tobin escribió:
> After banging my head against parsing colorized output of git-add-
> files,
> I gave up and implemented internal colorization keying off of the
> color.diff configuration.
Great!
> +sub parse_color {
You could simplify the manual escape sequence construction that
you're doing here by using Term::ANSIColor like the other patches
did. I see that git-send-email.perl uses that module too, so I guess
depending on that module is ok.
I also wonder whether the config code should be using the git.pm
module like git-send-email.perl and a couple others do (although it
would be slower than slurping in all the config in one shot like you
do; perhaps there's justification for a new function in git.pm that
wraps git-config --get-regexp...).
> +sub colorize_head_line {
> + my $line = shift @_;
> + if ($use_color) {
> + # git doesn't colorize these by default, soooo
> + # if ($line =~ /^\+/) {
> + # return parse_color($colorconfig{'color.diff.new'}) . "$line\e
> [m";
> + # }
> + # if ($line =~ /^-/) {
> + # return parse_color($colorconfig{'color.diff.old'}) . "$line\e
> [m";
> + # }
> + return parse_color($colorconfig{'color.diff.meta'}) . "$line\e[m";
> + }
> + return $line;
> +}
> +
> +sub colorize_hunk_line {
> + my $line = shift @_;
> + if ($use_color) {
> + if ($line =~ /^\+/) {
> + return parse_color($colorconfig{'color.diff.new'}) . "$line\e[m";
> + }
> + if ($line =~ /^-/) {
> + return parse_color($colorconfig{'color.diff.old'}) . "$line\e[m";
> + }
> + if ($line =~ /^@@ /) {
> + return parse_color($colorconfig{'color.diff.frag'}) . "$line\e[m";
> + }
> + }
> + return $line;
> +}
This is a good start but to completely match the colorized output
produced by diff it will need some additional logic; for example,
highlighting spurious whitespace. Search for
need_highlight_leading_space in diff.c and you'll see that the test
is basically for any space which precedes a tab in the leading
whitespace on newly inserted lines. In this case the spaces are
highlighted using the whitespace color (normally red background).
I don't know when color.diff.commit is ever used in diff output, but
perhaps that would need to be handled as well.
Cheers,
Wincent
^ permalink raw reply
* Re: [PATCH] [BUG FIXED] git-add (-a|-u) and -n support
From: Michael Witten @ 2007-10-14 12:11 UTC (permalink / raw)
To: git
In-Reply-To: <E1DCA1D1-1ED3-498A-A919-9EBAF3BA0870@mit.edu>
On 14 Oct 2007, at 6:26:28 AM, Michael Witten wrote:
> Hello,
>
> The git-add command doesn't handle -n when using -u.
>
> I fixed this and added -a for adding ALL files, not
> just those below the current directory (just like
> git-commit).
>
> The patch is below, but you can also download it from
> http://web.mit.edu/mfwitten/git/0001-git-add-now-understands-two-
> kinds-of-update.patch
>
Unfortunately, I introduced a bug.
The following:
> + if (show_only)
> + remove_file_from_cache(path);
> + if (verbose)
> + printf("remove '%s'\n", path);
Should be:
> + if (!show_only)
> + remove_file_from_cache(path);
> + if (verbose)
> + printf("remove '%s'\n", path);
The new patch is listed below:
(http://web.mit.edu/mfwitten/git/0001-git-add-now-understands-two-
kinds-of-update.patch)
From 6d7480062b1e1c513441d4bbc17a9a8b5d9b1c8f Mon Sep 17 00:00:00 2001
From: Michael Witten <mfwitten@mit.edu>
Date: Sun, 14 Oct 2007 06:13:20 -0400
Subject: [PATCH] git-add now understands two kinds of update:
-u: update as before
-a: update all as in a true 'git commit -a'
Also, -n works correctly now with the above options.
Signed-off-by: Michael Witten <mfwitten@mit.edu>
---
builtin-add.c | 69 +++++++++++++++++++++++++++++++++++++
+-------------------
1 files changed, 46 insertions(+), 23 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index f9a6580..f180afe 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -13,10 +13,11 @@
#include "commit.h"
#include "revision.h"
+enum update_type {NONE, ALL, CURRENT_DIRECTORY};
+
static const char builtin_add_usage[] =
"git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--]
<filepattern>...";
-static int take_worktree_changes;
static const char *excludes_file;
static void prune_directory(struct dir_struct *dir, const char
**pathspec, int prefix)
@@ -83,40 +84,57 @@ static void fill_directory(struct dir_struct
*dir, const char **pathspec,
static void update_callback(struct diff_queue_struct *q,
struct diff_options *opt, void *cbdata)
{
- int i, verbose;
-
- verbose = *((int *)cbdata);
+ int i;
+
+ int* options = (int*)cbdata;
+ int verbose = options[0];
+ int show_only = options[1];
+
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
const char *path = p->one->path;
- switch (p->status) {
- default:
- die("unexpected diff status %c", p->status);
- case DIFF_STATUS_UNMERGED:
- case DIFF_STATUS_MODIFIED:
- case DIFF_STATUS_TYPE_CHANGED:
- add_file_to_cache(path, verbose);
- break;
- case DIFF_STATUS_DELETED:
- remove_file_from_cache(path);
- if (verbose)
- printf("remove '%s'\n", path);
- break;
+
+ switch (p->status) {
+ case DIFF_STATUS_UNMERGED:
+ case DIFF_STATUS_MODIFIED:
+ case DIFF_STATUS_TYPE_CHANGED:
+ if (show_only)
+ printf("add '%s'\n", path);
+ else
+ add_file_to_cache(path, verbose);
+ break;
+
+ case DIFF_STATUS_DELETED:
+ if (verbose)
+ printf("remove '%s'\n", path);
+ if (!show_only)
+ remove_file_from_cache(path);
+ break;
+
+ default:
+ die("unexpected diff status %c", p->status);
}
}
}
-static void update(int verbose, const char *prefix, const char **files)
+static void update(enum update_type type, int verbose, int show_only,
+ const char *prefix, const char **files)
{
struct rev_info rev;
+ int callback_options[] = {verbose, show_only};
+
init_revisions(&rev, prefix);
setup_revisions(0, NULL, &rev, NULL);
- rev.prune_data = get_pathspec(prefix, files);
+
+ rev.prune_data = type == ALL ? NULL : get_pathspec(prefix, files);
+
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback;
- rev.diffopt.format_callback_data = &verbose;
+ rev.diffopt.format_callback_data = callback_options;
+
if (read_cache() < 0)
die("index file corrupt");
+
run_diff_files(&rev, 0);
}
@@ -158,6 +176,7 @@ int cmd_add(int argc, const char **argv, const
char *prefix)
{
int i, newfd;
int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
+ enum update_type update_type = NONE;
const char **pathspec;
struct dir_struct dir;
int add_interactive = 0;
@@ -201,8 +220,12 @@ int cmd_add(int argc, const char **argv, const
char *prefix)
verbose = 1;
continue;
}
+ if (!strcmp(arg, "-a")) {
+ update_type = ALL;
+ continue;
+ }
if (!strcmp(arg, "-u")) {
- take_worktree_changes = 1;
+ update_type = CURRENT_DIRECTORY;
continue;
}
if (!strcmp(arg, "--refresh")) {
@@ -212,8 +235,8 @@ int cmd_add(int argc, const char **argv, const
char *prefix)
usage(builtin_add_usage);
}
- if (take_worktree_changes) {
- update(verbose, prefix, argv + i);
+ if (update_type) {
+ update(update_type, verbose, show_only, prefix, argv + i);
goto finish;
}
--
1.5.3.4.206.g58ba4-dirty
^ permalink raw reply related
* [PATCH 0/7] Bisect dunno
From: Christian Couder @ 2007-10-14 12:28 UTC (permalink / raw)
To: Junio Hamano, Johannes Schindelin; +Cc: git
Hi all,
Here is my bisect dunno patch series again.
The changes since last time are the following:
[PATCH 1/7] rev-list: implement --bisect-all
[PATCH 2/7] Bisect: fix some white spaces and empty lines breakages.
-> No change.
[PATCH 3/7] Bisect: implement "bisect dunno" to mark untestable revisions.
-> Added dunno stuff in "bisect_replay" that I had forgotten.
-> Use "bisect_write_good" and "bisect_write_bad" in "bisect_replay"
while at it.
[PATCH 4/7] Bisect: factorise "bisect_write_*" functions.
[PATCH 5/7] Bisect: factorise some logging into "bisect_write".
[PATCH 6/7] Bisect: factorise "bisect_{bad,good,dunno}" into "bisect_state".
-> Some new factorisation and clean up work.
[PATCH 7/7] Bisect: add "bisect dunno" to the documentation.
-> Document "bisect dunno" and fix some short usage descriptions.
Regards,
Christian.
^ permalink raw reply
* [PATCH 1/7] rev-list: implement --bisect-all
From: Christian Couder @ 2007-10-14 12:28 UTC (permalink / raw)
To: Junio Hamano, Johannes Schindelin; +Cc: git
This is Junio's patch with some stuff to make --bisect-all
compatible with --bisect-vars.
This option makes it possible to see all the potential
bisection points. The best ones are displayed first.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-rev-list.c | 100 ++++++++++++++++++++++++++++++++++++++++++++-------
log-tree.c | 2 +-
log-tree.h | 1 +
3 files changed, 88 insertions(+), 15 deletions(-)
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 33726b8..4439332 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -9,6 +9,7 @@
#include "revision.h"
#include "list-objects.h"
#include "builtin.h"
+#include "log-tree.h"
/* bits #0-15 in revision.h */
@@ -38,7 +39,8 @@ static const char rev_list_usage[] =
" --left-right\n"
" special purpose:\n"
" --bisect\n"
-" --bisect-vars"
+" --bisect-vars\n"
+" --bisect-all"
;
static struct rev_info revs;
@@ -74,6 +76,7 @@ static void show_commit(struct commit *commit)
parents = parents->next;
}
}
+ show_decorations(commit);
if (revs.commit_format == CMIT_FMT_ONELINE)
putchar(' ');
else
@@ -278,6 +281,57 @@ static struct commit_list *best_bisection(struct commit_list *list, int nr)
return best;
}
+struct commit_dist {
+ struct commit *commit;
+ int distance;
+};
+
+static int compare_commit_dist(const void *a_, const void *b_)
+{
+ struct commit_dist *a, *b;
+
+ a = (struct commit_dist *)a_;
+ b = (struct commit_dist *)b_;
+ if (a->distance != b->distance)
+ return b->distance - a->distance; /* desc sort */
+ return hashcmp(a->commit->object.sha1, b->commit->object.sha1);
+}
+
+static struct commit_list *best_bisection_sorted(struct commit_list *list, int nr)
+{
+ struct commit_list *p;
+ struct commit_dist *array = xcalloc(nr, sizeof(*array));
+ int cnt, i;
+
+ for (p = list, cnt = 0; p; p = p->next) {
+ int distance;
+ unsigned flags = p->item->object.flags;
+
+ if (revs.prune_fn && !(flags & TREECHANGE))
+ continue;
+ distance = weight(p);
+ if (nr - distance < distance)
+ distance = nr - distance;
+ array[cnt].commit = p->item;
+ array[cnt].distance = distance;
+ cnt++;
+ }
+ qsort(array, cnt, sizeof(*array), compare_commit_dist);
+ for (p = list, i = 0; i < cnt; i++) {
+ struct name_decoration *r = xmalloc(sizeof(*r) + 100);
+ struct object *obj = &(array[i].commit->object);
+
+ sprintf(r->name, "dist=%d", array[i].distance);
+ r->next = add_decoration(&name_decoration, obj, r);
+ p->item = array[i].commit;
+ p = p->next;
+ }
+ if (p)
+ p->next = NULL;
+ free(array);
+ return list;
+}
+
/*
* zero or positive weight is the number of interesting commits it can
* reach, including itself. Especially, weight = 0 means it does not
@@ -292,7 +346,8 @@ static struct commit_list *best_bisection(struct commit_list *list, int nr)
* or positive distance.
*/
static struct commit_list *do_find_bisection(struct commit_list *list,
- int nr, int *weights)
+ int nr, int *weights,
+ int find_all)
{
int n, counted;
struct commit_list *p;
@@ -351,7 +406,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
clear_distance(list);
/* Does it happen to be at exactly half-way? */
- if (halfway(p, nr))
+ if (!find_all && halfway(p, nr))
return p;
counted++;
}
@@ -389,19 +444,22 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
weight_set(p, weight(q));
/* Does it happen to be at exactly half-way? */
- if (halfway(p, nr))
+ if (!find_all && halfway(p, nr))
return p;
}
}
show_list("bisection 2 counted all", counted, nr, list);
- /* Then find the best one */
- return best_bisection(list, nr);
+ if (!find_all)
+ return best_bisection(list, nr);
+ else
+ return best_bisection_sorted(list, nr);
}
static struct commit_list *find_bisection(struct commit_list *list,
- int *reaches, int *all)
+ int *reaches, int *all,
+ int find_all)
{
int nr, on_list;
struct commit_list *p, *best, *next, *last;
@@ -434,14 +492,13 @@ static struct commit_list *find_bisection(struct commit_list *list,
weights = xcalloc(on_list, sizeof(*weights));
/* Do the real work of finding bisection commit. */
- best = do_find_bisection(list, nr, weights);
-
+ best = do_find_bisection(list, nr, weights, find_all);
if (best) {
- best->next = NULL;
+ if (!find_all)
+ best->next = NULL;
*reaches = weight(best);
}
free(weights);
-
return best;
}
@@ -468,6 +525,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
int i;
int read_from_stdin = 0;
int bisect_show_vars = 0;
+ int bisect_find_all = 0;
git_config(git_default_config);
init_revisions(&revs, prefix);
@@ -490,6 +548,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
bisect_list = 1;
continue;
}
+ if (!strcmp(arg, "--bisect-all")) {
+ bisect_list = 1;
+ bisect_find_all = 1;
+ continue;
+ }
if (!strcmp(arg, "--bisect-vars")) {
bisect_list = 1;
bisect_show_vars = 1;
@@ -536,9 +599,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
if (bisect_list) {
int reaches = reaches, all = all;
- revs.commits = find_bisection(revs.commits, &reaches, &all);
+ revs.commits = find_bisection(revs.commits, &reaches, &all,
+ bisect_find_all);
if (bisect_show_vars) {
int cnt;
+ char hex[41];
if (!revs.commits)
return 1;
/*
@@ -550,15 +615,22 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
* A bisect set of size N has (N-1) commits further
* to test, as we already know one bad one.
*/
- cnt = all-reaches;
+ cnt = all - reaches;
if (cnt < reaches)
cnt = reaches;
+ strcpy(hex, sha1_to_hex(revs.commits->item->object.sha1));
+
+ if (bisect_find_all) {
+ traverse_commit_list(&revs, show_commit, show_object);
+ printf("------\n");
+ }
+
printf("bisect_rev=%s\n"
"bisect_nr=%d\n"
"bisect_good=%d\n"
"bisect_bad=%d\n"
"bisect_all=%d\n",
- sha1_to_hex(revs.commits->item->object.sha1),
+ hex,
cnt - 1,
all - reaches - 1,
reaches - 1,
diff --git a/log-tree.c b/log-tree.c
index 2319154..f766758 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -15,7 +15,7 @@ static void show_parents(struct commit *commit, int abbrev)
}
}
-static void show_decorations(struct commit *commit)
+void show_decorations(struct commit *commit)
{
const char *prefix;
struct name_decoration *decoration;
diff --git a/log-tree.h b/log-tree.h
index e82b56a..b33f7cd 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -12,5 +12,6 @@ int log_tree_diff_flush(struct rev_info *);
int log_tree_commit(struct rev_info *, struct commit *);
int log_tree_opt_parse(struct rev_info *, const char **, int);
void show_log(struct rev_info *opt, const char *sep);
+void show_decorations(struct commit *commit);
#endif
--
1.5.3.4.213.g68ad5
^ permalink raw reply related
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