* [PATCH 1/6] builtin-commit: fix author date with --amend --author=<author>
From: Johannes Schindelin @ 2007-11-11 17:35 UTC (permalink / raw)
To: git, krh, gitster
In-Reply-To: <Pine.LNX.4.64.0711111730580.4362@racer.site>
When amending a commit with a new author, the author date is taken
from the original commit.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
builtin-commit.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/builtin-commit.c b/builtin-commit.c
index a84a729..6be6def 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -527,6 +527,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
} else if (amend) {
struct commit_list *c;
struct commit *commit;
+ const char *author;
reflog_msg = "commit (amend)";
commit = lookup_commit(head_sha1);
@@ -536,6 +537,21 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
for (c = commit->parents; c; c = c->next)
strbuf_addf(&sb, "parent %s\n",
sha1_to_hex(c->item->object.sha1));
+
+ /* determine author date */
+ author = strstr(commit->buffer, "\nauthor");
+ if (author && !memmem(commit->buffer,
+ author + 1 - commit->buffer,
+ "\n\n", 2)) {
+ const char *email_end = strchr(author + 1, '>');
+ const char *line_end = strchr(author + 1, '\n');
+ if (email_end && line_end && email_end < line_end) {
+ char *date = xstrndup(email_end + 1,
+ line_end - email_end - 1);
+ setenv("GIT_AUTHOR_DATE", date, 1);
+ free(date);
+ }
+ }
} else if (in_merge) {
struct strbuf m;
FILE *fp;
--
1.5.3.5.1693.g26ed
^ permalink raw reply related
* [PATCH 0/6] Various (replacement) patches to builtin-commit
From: Johannes Schindelin @ 2007-11-11 17:35 UTC (permalink / raw)
To: git, krh, gitster
Hi,
I did some more work on top of kh/commit (rebased to next, + Kristian's
refresh_cache() patch which is still waiting to be enhanced with
refresh_cache()-after-commit-with-paths).
They are in chronological order. In particular, all patches except 2/6
resurrect old behaviour.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 6/6] refactor fetch's ref matching to use ref_abbrev_matches_full_with_rules()
From: Steffen Prohaska @ 2007-11-11 17:31 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <fh7548$15u$1@ger.gmane.org>
On Nov 11, 2007, at 3:55 PM, Jakub Narebski wrote:
> Steffen Prohaska wrote:
>
>> The old rules used by fetch were coded as a series of ifs. The old
>> rules are:
>> 1) match full refname if it starts with "refs/" or matches "HEAD"
>> 2) verify that full refname starts with "refs/"
>> 3) match abbreviated name in "refs/" if it starts with "heads/",
>> "tags/", or "remotes/".
>> 4) match abbreviated name in "refs/heads/"
>>
>> This is replaced by the new rules
>> a) match full refname
>> b) match abbreviated name prefixed with "refs/"
>> c) match abbreviated name prefixed with "refs/heads/"
>>
>> The details of the new rules are different from the old rules. We no
>> longer verify that the full refname starts with "refs/". The new
>> rule
>> (a) matches any full string. The old rules (1) and (2) were
>> stricter.
>> Now, the caller is responsible for using sensible full refnames.
>> This
>> should be the case for the current code. The new rule (b) is less
>> strict than old rule (3). The new rule accepts abbreviated names
>> that
>> start with a non-standard prefix below "refs/".
>>
>> Despite this modifications the new rules should handle all cases as
>> expected. Two tests are added to verify that fetch does not resolve
>> short tags or HEAD in remotes.
>>
>> We may even think about loosening the rules a bit more and unify them
>> with the rev-parse rules. This would be done by replacing
>> ref_ref_fetch_rules with ref_ref_parse_rules. Note, the two new test
>> would break.
>
> Does still "origin" matches "origin/HEAD" if we have emote "origin"?
No, and it did not before. fetch does _not_ match origin as
refs/remotes/origin/HEAD. I added a test to confirm the old
behaviour. Only the git-rev-parse rules match origin as
refs/remotes/origin/HEAD.
Steffen
^ permalink raw reply
* [PATCH] Move stripspace() and launch_editor() to strbuf.c
From: Johannes Schindelin @ 2007-11-11 17:29 UTC (permalink / raw)
To: git, gitster
These functions are already declared in strbuf.h, so it is only
logical to move their implementations to the corresponding file.
Particularly, since strbuf.h is in LIB_H, but both functions
were missing from libgit.a.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
builtin-stripspace.c | 67 --------------------------------
builtin-tag.c | 35 -----------------
strbuf.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 103 insertions(+), 102 deletions(-)
diff --git a/builtin-stripspace.c b/builtin-stripspace.c
index c0b2130..5de5a3f 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -1,73 +1,6 @@
#include "builtin.h"
#include "cache.h"
-/*
- * Returns the length of a line, without trailing spaces.
- *
- * If the line ends with newline, it will be removed too.
- */
-static size_t cleanup(char *line, size_t len)
-{
- while (len) {
- unsigned char c = line[len - 1];
- if (!isspace(c))
- break;
- len--;
- }
-
- return len;
-}
-
-/*
- * Remove empty lines from the beginning and end
- * and also trailing spaces from every line.
- *
- * Note that the buffer will not be NUL-terminated.
- *
- * Turn multiple consecutive empty lines between paragraphs
- * into just one empty line.
- *
- * If the input has only empty lines and spaces,
- * no output will be produced.
- *
- * If last line does not have a newline at the end, one is added.
- *
- * Enable skip_comments to skip every line starting with "#".
- */
-void stripspace(struct strbuf *sb, int skip_comments)
-{
- int empties = 0;
- size_t i, j, len, newlen;
- char *eol;
-
- /* We may have to add a newline. */
- strbuf_grow(sb, 1);
-
- for (i = j = 0; i < sb->len; i += len, j += newlen) {
- eol = memchr(sb->buf + i, '\n', sb->len - i);
- len = eol ? eol - (sb->buf + i) + 1 : sb->len - i;
-
- if (skip_comments && len && sb->buf[i] == '#') {
- newlen = 0;
- continue;
- }
- newlen = cleanup(sb->buf + i, len);
-
- /* Not just an empty line? */
- if (newlen) {
- if (empties > 0 && j > 0)
- sb->buf[j++] = '\n';
- empties = 0;
- memmove(sb->buf + j, sb->buf + i, newlen);
- sb->buf[newlen + j++] = '\n';
- } else {
- empties++;
- }
- }
-
- strbuf_setlen(sb, j);
-}
-
int cmd_stripspace(int argc, const char **argv, const char *prefix)
{
struct strbuf buf;
diff --git a/builtin-tag.c b/builtin-tag.c
index 566b9d1..c70564b 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -17,41 +17,6 @@ static const char builtin_tag_usage[] =
static char signingkey[1000];
-void launch_editor(const char *path, struct strbuf *buffer)
-{
- const char *editor, *terminal;
-
- editor = getenv("GIT_EDITOR");
- if (!editor && editor_program)
- editor = editor_program;
- if (!editor)
- editor = getenv("VISUAL");
- if (!editor)
- editor = getenv("EDITOR");
-
- terminal = getenv("TERM");
- if (!editor && (!terminal || !strcmp(terminal, "dumb"))) {
- fprintf(stderr,
- "Terminal is dumb but no VISUAL nor EDITOR defined.\n"
- "Please supply the message using either -m or -F option.\n");
- exit(1);
- }
-
- if (!editor)
- editor = "vi";
-
- if (strcmp(editor, ":")) {
- const char *args[] = { editor, path, NULL };
-
- if (run_command_v_opt(args, 0))
- die("There was a problem with the editor %s.", editor);
- }
-
- if (strbuf_read_file(buffer, path, 0) < 0)
- die("could not read message file '%s': %s",
- path, strerror(errno));
-}
-
struct tag_filter {
const char *pattern;
int lines;
diff --git a/strbuf.c b/strbuf.c
index 536b432..6e99358 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -1,4 +1,5 @@
#include "cache.h"
+#include "run-command.h"
/*
* Used as the default ->buf value, so that people can always assume
@@ -224,3 +225,105 @@ int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
return len;
}
+
+/*
+ * Returns the length of a line, without trailing spaces.
+ *
+ * If the line ends with newline, it will be removed too.
+ */
+static size_t cleanup(char *line, size_t len)
+{
+ while (len) {
+ unsigned char c = line[len - 1];
+ if (!isspace(c))
+ break;
+ len--;
+ }
+
+ return len;
+}
+
+/*
+ * Remove empty lines from the beginning and end
+ * and also trailing spaces from every line.
+ *
+ * Note that the buffer will not be NUL-terminated.
+ *
+ * Turn multiple consecutive empty lines between paragraphs
+ * into just one empty line.
+ *
+ * If the input has only empty lines and spaces,
+ * no output will be produced.
+ *
+ * If last line does not have a newline at the end, one is added.
+ *
+ * Enable skip_comments to skip every line starting with "#".
+ */
+void stripspace(struct strbuf *sb, int skip_comments)
+{
+ int empties = 0;
+ size_t i, j, len, newlen;
+ char *eol;
+
+ /* We may have to add a newline. */
+ strbuf_grow(sb, 1);
+
+ for (i = j = 0; i < sb->len; i += len, j += newlen) {
+ eol = memchr(sb->buf + i, '\n', sb->len - i);
+ len = eol ? eol - (sb->buf + i) + 1 : sb->len - i;
+
+ if (skip_comments && len && sb->buf[i] == '#') {
+ newlen = 0;
+ continue;
+ }
+ newlen = cleanup(sb->buf + i, len);
+
+ /* Not just an empty line? */
+ if (newlen) {
+ if (empties > 0 && j > 0)
+ sb->buf[j++] = '\n';
+ empties = 0;
+ memmove(sb->buf + j, sb->buf + i, newlen);
+ sb->buf[newlen + j++] = '\n';
+ } else {
+ empties++;
+ }
+ }
+
+ strbuf_setlen(sb, j);
+}
+
+void launch_editor(const char *path, struct strbuf *buffer)
+{
+ const char *editor, *terminal;
+
+ editor = getenv("GIT_EDITOR");
+ if (!editor && editor_program)
+ editor = editor_program;
+ if (!editor)
+ editor = getenv("VISUAL");
+ if (!editor)
+ editor = getenv("EDITOR");
+
+ terminal = getenv("TERM");
+ if (!editor && (!terminal || !strcmp(terminal, "dumb"))) {
+ fprintf(stderr,
+ "Terminal is dumb but no VISUAL nor EDITOR defined.\n"
+ "Please supply the message using either -m or -F option.\n");
+ exit(1);
+ }
+
+ if (!editor)
+ editor = "vi";
+
+ if (strcmp(editor, ":")) {
+ const char *args[] = { editor, path, NULL };
+
+ if (run_command_v_opt(args, 0))
+ die("There was a problem with the editor %s.", editor);
+ }
+
+ if (strbuf_read_file(buffer, path, 0) < 0)
+ die("could not read message file '%s': %s",
+ path, strerror(errno));
+}
--
1.5.3.5.1693.g26ed
^ permalink raw reply related
* Re: Installing without rebuilding
From: Benoit Sigoure @ 2007-11-11 16:55 UTC (permalink / raw)
To: Brian Gernhardt; +Cc: Git Mailing List
In-Reply-To: <8B92E213-17DB-4E83-B045-01CE0E7D26CB@silverinsanity.com>
[-- Attachment #1: Type: text/plain, Size: 1286 bytes --]
On Nov 11, 2007, at 5:49 PM, Brian Gernhardt wrote:
> Git has a very clever Makefile. Sometimes its a little overly clever.
>
> 1) I use stow to manage my /usr/local directory. With many other
> programs I am able to build with a prefix of /usr/local and install
> with a prefix of /usr/local/stow/$program. Git detects a change in
> the build variables and recompiles pretty much everything.
>
> 2) If I remove the old copy of git before installing the new, git
> will notice this and again start a (smaller) recompile because the
> GIT-VERSION-FILE file changes from something detailed like
> "1.5.3.5.622.g6fd7a" to "1.5.3.GIT".
>
> Is there a way to tell git to be a bit less clever and just install
> the already compiled program? If not, would changing the Makefile
> to read something like the following be accepted?
>
> ----- 8< -----
>
> install: all install-dumb
>
> install-dumb: # No rebuild!
> # Current install process
>
> ----- 8< -----
I also stow git (which doesn't come with a make uninstall grrrrrr)
and what I do is that I dropped the dependency of `install' on
`all'. Also, I always install the new version before removing (stow -
D) the previous one.
Cheers,
--
Benoit Sigoure aka Tsuna
EPITA Research and Development Laboratory
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 186 bytes --]
^ permalink raw reply
* Installing without rebuilding
From: Brian Gernhardt @ 2007-11-11 16:49 UTC (permalink / raw)
To: Git Mailing List
Git has a very clever Makefile. Sometimes its a little overly clever.
1) I use stow to manage my /usr/local directory. With many other
programs I am able to build with a prefix of /usr/local and install
with a prefix of /usr/local/stow/$program. Git detects a change in
the build variables and recompiles pretty much everything.
2) If I remove the old copy of git before installing the new, git will
notice this and again start a (smaller) recompile because the GIT-
VERSION-FILE file changes from something detailed like
"1.5.3.5.622.g6fd7a" to "1.5.3.GIT".
Is there a way to tell git to be a bit less clever and just install
the already compiled program? If not, would changing the Makefile to
read something like the following be accepted?
----- 8< -----
install: all install-dumb
install-dumb: # No rebuild!
# Current install process
----- 8< -----
~~ Brian
^ permalink raw reply
* Re: [PATCH 3/3] git-svn log: handle unreachable revisions like "svn log"
From: Benoit Sigoure @ 2007-11-11 16:36 UTC (permalink / raw)
To: ddkilzer; +Cc: Git Mailing List
In-Reply-To: <189577.85054.qm@web52407.mail.re2.yahoo.com>
[-- Attachment #1: Type: text/plain, Size: 3769 bytes --]
On Nov 11, 2007, at 3:20 PM, David D. Kilzer wrote:
> Benoit Sigoure <tsuna@lrde.epita.fr> wrote:
>
>> On Nov 11, 2007, at 7:10 AM, David D Kilzer wrote:
>>
>>> sub find_rev_before {
>>> - my ($self, $rev, $eq_ok) = @_;
>>> + my ($self, $rev, $eq_ok, $min_rev) = @_;
>>
>> Could you please document this function? I guess that you had to
>> figure out what each argument was for, so please save the time of the
>> contributors that will read this code after you :)
>
> What is the format for documenting functions in git Perl scripts?
> I haven't
> see any "perlpod" use anywhere. Do you just want comments before
> the function?
>
> This method returns the git commit hash and svn revision of the
> first svn
> revision that exists on the current branch that is less than $rev (or
> less-than-or-equal-to $rev if $eq_ok is true).
Personally, I don't care. Maybe Eric has his own preference. For
me, as long as the code is documented one way or another, that's fine
by me. Under-documented code hinders new contributors, so I think
it's important to add documentation whenever possible.
> Please note that I don't have a full understanding of how
> find_rev_before()
> works (other than it's computing an offset into a sparse? data file
> based on
> the revision number) since I'm still new to git.
>
>>> +sub find_rev_after {
>>> + my ($self, $rev, $eq_ok, $max_rev) = @_;
>>> + ++$rev unless $eq_ok;
>>> + $max_rev ||= $self->rev_db_max();
>>> + while ($rev <= $max_rev) {
>>> + if (my $c = $self->rev_db_get($rev)) {
>>> + return ($rev, $c);
>>> + }
>>> + ++$rev;
>>> + }
>>> + return (undef, undef);
>>> +}
>>
>> Too much code duplication. It should be possible to write a sub
>> find_rev_ (or _find_rev, don't know what's the naming convention for
>> internal details) that takes a 5th argument, an anonymous sub that
>> does the comparison. So that basically, find_rev_before will be
>> something along these (untested) lines:
>>
>> sub find_rev_before {
>> my ($self, $rev, $eq_ok, $min_rev) = @_;
>> return find_rev_($self, $rev, $eq_ok, $min_rev, sub { my ($a, $b) =
>> @_; return $a >= $b; });
>> }
>
> I think that combining find_rev_before() and find_rev_after() would
> greatly
> sacrifice readability of the code in exchange for removing ~10
> lines of code.
> Also, you must do more than just replace the comparison in the while
> () loop:
>
> - before() decrements $rev while after() increments it
> - stop limits are different ($max_rev versus $min_rev)
>
> This is what such a method might look like (untested). Since you
> already
> requested find_rev_before() be documented, is this really going to
> help?
>
> sub find_rev_ {
> my ($self, $rev, $eq_ok, $is_before, $limit_rev) = @_;
> ($is_before ? --$rev : ++$rev) unless $eq_ok;
> $limit_rev ||= ($is_before ? 1 : $self->rev_db_max());
> while ($is_before ? $rev >= $limit_rev : $rev <= $limit_rev) {
> if (my $c = $self->rev_db_get($rev)) {
> return ($rev, $c);
> }
> $is_before ? --$rev : ++$rev;
> }
> return (undef, undef);
> }
>
> Defining wrapper functions would help, but I still think it's just
> as clear to
> keep the two methods separate.
>
> sub find_rev_before() {
> my ($self, $rev, $eq_ok, $min_rev) = @_;
> return $self->find_rev_($rev, $eq_ok, 1, $min_rev);
> }
>
> sub find_rev_after() {
> my ($self, $rev, $eq_ok, $max_rev) = @_;
> return $self->find_rev_($rev, $eq_ok, 0, $max_rev);
> }
>
> Do you agree, or do you think the methods should still be combined?
Er... you're right, I overlooked the differences between the two
functions. So merging them would make the code more complex than it
needs to be, or so I think.
Thanks!
--
Benoit Sigoure aka Tsuna
EPITA Research and Development Laboratory
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 186 bytes --]
^ permalink raw reply
* Re: t7005 and vi in GIT_EXEC_PATH
From: Johannes Schindelin @ 2007-11-11 16:28 UTC (permalink / raw)
To: Brian Gernhardt; +Cc: Git Mailing List
In-Reply-To: <FCFF59B3-D3F1-4BEB-B3C3-D07DD5D5D8EF@silverinsanity.com>
Hi,
On Sun, 11 Nov 2007, Brian Gernhardt wrote:
> On Nov 11, 2007, at 10:58 AM, Johannes Schindelin wrote:
>
> > > If vi is in GIT_EXEC_PATH, then t7005-editor.sh fails because the
> > > real vi is invoked instead of the test vi script. This is because
> > > the git wrapper puts GIT_EXEC_PATH ahead of ".". I see no easy
> > > solution to this problem, and thought I should bring it up with the
> > > list.
> >
> > I don't understand. GIT_EXEC_PATH should be set to the build
> > directory when you are running the tests. Unless you copy vi _there_,
> > you should not have any problem.
>
> I'm sorry, I should have been more clear. I was referring to the
> GIT_EXEC_PATH build variable, not the environment variable. The git
> wrapper always adds the path determined during build to the front of
> PATH. When I was changing my build script, this got set to
> "/usr/local/bin" (I usually use /usr/local/stow/git, instead). Since I
> have a /usr/local/bin/vim, PATH for git-commit.sh during the test was:
>
> - my git build directory
> - /usr/local/bin (containing a symlink vi -> vim)
> - the t/trash directory, added by the test via `PATH=".:$PATH"` (containing
> the test vi script)
> - my normal path
>
> The test appeared to hang when running it normally. When I ran it with
> -v, I saw that vim was started.
The obvious solution would be to copy "vi" into the git build directory
for the test, or skip the test if that copy could not be performed.
Ciao,
Dscho
^ permalink raw reply
* Re: t7005 and vi in GIT_EXEC_PATH
From: Brian Gernhardt @ 2007-11-11 16:10 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0711111557370.4362@racer.site>
On Nov 11, 2007, at 10:58 AM, Johannes Schindelin wrote:
>> If vi is in GIT_EXEC_PATH, then t7005-editor.sh fails because the
>> real
>> vi is invoked instead of the test vi script. This is because the git
>> wrapper puts GIT_EXEC_PATH ahead of ".". I see no easy solution to
>> this
>> problem, and thought I should bring it up with the list.
>
> I don't understand. GIT_EXEC_PATH should be set to the build
> directory
> when you are running the tests. Unless you copy vi _there_, you
> should
> not have any problem.
I'm sorry, I should have been more clear. I was referring to the
GIT_EXEC_PATH build variable, not the environment variable. The git
wrapper always adds the path determined during build to the front of
PATH. When I was changing my build script, this got set to "/usr/
local/bin" (I usually use /usr/local/stow/git, instead). Since I have
a /usr/local/bin/vim, PATH for git-commit.sh during the test was:
- my git build directory
- /usr/local/bin (containing a symlink vi -> vim)
- the t/trash directory, added by the test via `PATH=".:$PATH"`
(containing the test vi script)
- my normal path
The test appeared to hang when running it normally. When I ran it
with -v, I saw that vim was started.
~~ Brian
^ permalink raw reply
* Re: t7005 and vi in GIT_EXEC_PATH
From: Johannes Schindelin @ 2007-11-11 15:58 UTC (permalink / raw)
To: Brian Gernhardt; +Cc: Git Mailing List
In-Reply-To: <9A9986E7-E03D-458A-9A19-A3EF0E7B203D@silverinsanity.com>
Hi,
On Sat, 10 Nov 2007, Brian Gernhardt wrote:
> If vi is in GIT_EXEC_PATH, then t7005-editor.sh fails because the real
> vi is invoked instead of the test vi script. This is because the git
> wrapper puts GIT_EXEC_PATH ahead of ".". I see no easy solution to this
> problem, and thought I should bring it up with the list.
I don't understand. GIT_EXEC_PATH should be set to the build directory
when you are running the tests. Unless you copy vi _there_, you should
not have any problem.
Ciao,
Dscho
^ permalink raw reply
* Re: (no subject)
From: Johannes Schindelin @ 2007-11-11 15:22 UTC (permalink / raw)
To: Michael Dressel; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0711111359590.9401@castor.milkiway.cos>
Hi,
On Sun, 11 Nov 2007, Michael Dressel wrote:
>
> >Michael Dressel wrote:
> >Ok nice. Another thing is that git-push will push all the tracking
> >branches in refs/remotes/origin.
>
> I learned that I only have to edit the .git/config file to avoid that
> git-push pushes everything.
It is documented that you can use "git push origin <branchname>".
> [remote "origin1"]
> url = /home/repo/src
> fetch = +refs/heads/master:refs/remotes/origin/master
> push = +refs/heads/master:refs/heads/master
With "push", it is not necessary to specify the ":<target>".
Also, if "master" is unambiguous, you can write just "master" instead of
"refs/heads/master".
Furthermore, I suggest not forcing (that's what "+" does) the push, since
it is quite possible that you push something old in the wrong direction.
Hth,
Dscho
^ permalink raw reply
* Re: [PATCH 6/6] refactor fetch's ref matching to use ref_abbrev_matches_full_with_rules()
From: Jakub Narebski @ 2007-11-11 14:55 UTC (permalink / raw)
To: git
In-Reply-To: <11947897092576-git-send-email-prohaska@zib.de>
Steffen Prohaska wrote:
> The old rules used by fetch were coded as a series of ifs. The old
> rules are:
> 1) match full refname if it starts with "refs/" or matches "HEAD"
> 2) verify that full refname starts with "refs/"
> 3) match abbreviated name in "refs/" if it starts with "heads/",
> "tags/", or "remotes/".
> 4) match abbreviated name in "refs/heads/"
>
> This is replaced by the new rules
> a) match full refname
> b) match abbreviated name prefixed with "refs/"
> c) match abbreviated name prefixed with "refs/heads/"
>
> The details of the new rules are different from the old rules. We no
> longer verify that the full refname starts with "refs/". The new rule
> (a) matches any full string. The old rules (1) and (2) were stricter.
> Now, the caller is responsible for using sensible full refnames. This
> should be the case for the current code. The new rule (b) is less
> strict than old rule (3). The new rule accepts abbreviated names that
> start with a non-standard prefix below "refs/".
>
> Despite this modifications the new rules should handle all cases as
> expected. Two tests are added to verify that fetch does not resolve
> short tags or HEAD in remotes.
>
> We may even think about loosening the rules a bit more and unify them
> with the rev-parse rules. This would be done by replacing
> ref_ref_fetch_rules with ref_ref_parse_rules. Note, the two new test
> would break.
Does still "origin" matches "origin/HEAD" if we have emote "origin"?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* [REPLACEMENT PATCH 3/6] push: support pushing HEAD to real branch name
From: Steffen Prohaska @ 2007-11-11 14:35 UTC (permalink / raw)
To: git, ericsson Andreas; +Cc: Steffen Prohaska
In-Reply-To: <47370EDF.3090907@op5.se>
This teaches "push <remote> HEAD" to resolve HEAD on the local
side to its real branch name, e.g. master, and then act as if
the real branch name was specified. So we have a shorthand for
pushing the current branch. Besides HEAD, no other symbolic ref
is resolved.
Thanks to Daniel Barkalow <barkalow@iabervon.org> for suggesting
this implementation, which is much simpler than the
implementation proposed before.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
builtin-push.c | 9 +++++++++
t/t5516-fetch-push.sh | 17 +++++++++++++++++
2 files changed, 26 insertions(+), 0 deletions(-)
prefixcmp() is simpler.
Steffen
diff --git a/builtin-push.c b/builtin-push.c
index 6d1da07..54fba0e 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -44,6 +44,15 @@ static void set_refspecs(const char **refs, int nr)
strcat(tag, refs[i]);
ref = tag;
}
+ if (!strcmp("HEAD", ref)) {
+ unsigned char sha1_dummy[20];
+ ref = resolve_ref(ref, sha1_dummy, 1, NULL);
+ if (!ref)
+ die("HEAD cannot be resolved.");
+ if (prefixcmp(ref, "refs/heads/"))
+ die("HEAD cannot be resolved to branch.");
+ ref = xstrdup(ref + 11);
+ }
add_refspec(ref);
}
}
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 86f9b53..b0ff488 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -244,6 +244,23 @@ test_expect_success 'push with colon-less refspec (4)' '
'
+test_expect_success 'push with HEAD' '
+
+ mk_test heads/master &&
+ git checkout master &&
+ git push testrepo HEAD &&
+ check_push_result $the_commit heads/master
+
+'
+
+test_expect_success 'push with HEAD nonexisting at remote' '
+
+ mk_test heads/master &&
+ git checkout -b local master &&
+ git push testrepo HEAD &&
+ check_push_result $the_commit heads/local
+'
+
test_expect_success 'push with dry-run' '
mk_test heads/master &&
--
1.5.3.5.643.g20245
^ permalink raw reply related
* Re: [PATCH 3/3] git-svn log: handle unreachable revisions like "svn log"
From: David D. Kilzer @ 2007-11-11 14:20 UTC (permalink / raw)
To: Benoit Sigoure; +Cc: git, gitster
In-Reply-To: <D6A0D2B9-A355-4216-8D15-84993C26B503@lrde.epita.fr>
Benoit Sigoure <tsuna@lrde.epita.fr> wrote:
> thanks for the patches, the series looks good to me, I added some
> comments below, for this patch.
Thanks for the review, Benoit! Comments below.
> On Nov 11, 2007, at 7:10 AM, David D Kilzer wrote:
>
> > sub find_rev_before {
> > - my ($self, $rev, $eq_ok) = @_;
> > + my ($self, $rev, $eq_ok, $min_rev) = @_;
>
> Could you please document this function? I guess that you had to
> figure out what each argument was for, so please save the time of the
> contributors that will read this code after you :)
What is the format for documenting functions in git Perl scripts? I haven't
see any "perlpod" use anywhere. Do you just want comments before the function?
This method returns the git commit hash and svn revision of the first svn
revision that exists on the current branch that is less than $rev (or
less-than-or-equal-to $rev if $eq_ok is true).
Please note that I don't have a full understanding of how find_rev_before()
works (other than it's computing an offset into a sparse? data file based on
the revision number) since I'm still new to git.
> > +sub find_rev_after {
> > + my ($self, $rev, $eq_ok, $max_rev) = @_;
> > + ++$rev unless $eq_ok;
> > + $max_rev ||= $self->rev_db_max();
> > + while ($rev <= $max_rev) {
> > + if (my $c = $self->rev_db_get($rev)) {
> > + return ($rev, $c);
> > + }
> > + ++$rev;
> > + }
> > + return (undef, undef);
> > +}
>
> Too much code duplication. It should be possible to write a sub
> find_rev_ (or _find_rev, don't know what's the naming convention for
> internal details) that takes a 5th argument, an anonymous sub that
> does the comparison. So that basically, find_rev_before will be
> something along these (untested) lines:
>
> sub find_rev_before {
> my ($self, $rev, $eq_ok, $min_rev) = @_;
> return find_rev_($self, $rev, $eq_ok, $min_rev, sub { my ($a, $b) =
> @_; return $a >= $b; });
> }
I think that combining find_rev_before() and find_rev_after() would greatly
sacrifice readability of the code in exchange for removing ~10 lines of code.
Also, you must do more than just replace the comparison in the while() loop:
- before() decrements $rev while after() increments it
- stop limits are different ($max_rev versus $min_rev)
This is what such a method might look like (untested). Since you already
requested find_rev_before() be documented, is this really going to help?
sub find_rev_ {
my ($self, $rev, $eq_ok, $is_before, $limit_rev) = @_;
($is_before ? --$rev : ++$rev) unless $eq_ok;
$limit_rev ||= ($is_before ? 1 : $self->rev_db_max());
while ($is_before ? $rev >= $limit_rev : $rev <= $limit_rev) {
if (my $c = $self->rev_db_get($rev)) {
return ($rev, $c);
}
$is_before ? --$rev : ++$rev;
}
return (undef, undef);
}
Defining wrapper functions would help, but I still think it's just as clear to
keep the two methods separate.
sub find_rev_before() {
my ($self, $rev, $eq_ok, $min_rev) = @_;
return $self->find_rev_($rev, $eq_ok, 1, $min_rev);
}
sub find_rev_after() {
my ($self, $rev, $eq_ok, $max_rev) = @_;
return $self->find_rev_($rev, $eq_ok, 0, $max_rev);
}
Do you agree, or do you think the methods should still be combined?
> > + if ($r_max < $r_min) {
> > + ($r_min, $r_max) = ($r_max, $r_min);
> > + }
> > + my (undef, $c_max) = $gs->find_rev_before($r_max, 1, $r_min);
> > + my (undef, $c_min) = $gs->find_rev_after($r_min, 1, $r_max);
> > + # If there are no commits in the range, both $c_max and $c_min
> > + # will be undefined. If there is at least 1 commit in the
> > + # range, both will be defined.
> > + return () if !defined $c_min;
>
> Fair enough but I'd strengthen the test by writing something like:
> return () if not defined $c_min || not defined $c_max;
> unless you can prove that `rev_db_get' can never return `undef' or
> something like that.
Will make this change.
> > +sub commit_log_separator {
> > + return ('-' x 72) . "\n";
> > +}
> > +
>
> This is basically a constant, I think that declaring it with a
> prototype helps Perl to optimize it:
> sub commit_log_separator() {
Will do.
> > +echo
> > ----------------------------------------------------------------------
> > -- > expected-separator
>
> This will choke on shells with buggy/fragile `echo'. I think it'd be
> safer to use printf here.
Will do.
Thanks!
Dave
^ permalink raw reply
* Re: [PATCH 3/6] push: support pushing HEAD to real branch name
From: Andreas Ericsson @ 2007-11-11 14:17 UTC (permalink / raw)
To: Steffen Prohaska; +Cc: git, Steffen Prohaska
In-Reply-To: <11947897083159-git-send-email-prohaska@zib.de>
Steffen Prohaska wrote:
> diff --git a/builtin-push.c b/builtin-push.c
> index 6d1da07..a99ba0c 100644
> --- a/builtin-push.c
> +++ b/builtin-push.c
> @@ -44,6 +44,15 @@ static void set_refspecs(const char **refs, int nr)
> strcat(tag, refs[i]);
> ref = tag;
> }
> + if (!strcmp("HEAD", ref)) {
> + unsigned char sha1_dummy[20];
> + ref = resolve_ref(ref, sha1_dummy, 1, NULL);
> + if (!ref)
> + die("HEAD cannot be resolved.");
> + if (strncmp(ref, "refs/heads/", 11))
Why not prefixcmp(ref, "refs/heads/")?
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH 1/6] push: mention --verbose option in documentation
From: Steffen Prohaska @ 2007-11-11 14:14 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <51B9B630-85F7-42BA-BCFF-4374A2527733@zib.de>
On Nov 11, 2007, at 3:10 PM, Steffen Prohaska wrote:
>
> On Nov 11, 2007, at 3:01 PM, Steffen Prohaska wrote:
>
>> From: Steffen Prohaska <gitster@pobox.com>
>
> This is obviously wrong. I have no clear idea how this happend.
> I remember I took the topic branch sp/push-refspec from pu and
> started to refactor. I used 'rebase' and 'rebase -i' a couple
> of times and now I have my name with Junios email address.
>
> I'll investigate how this could happen.
The Author line was already wrong in Junio's pu branch, commit
f31447f5f06200305393ca16e2eb9485e65dcccc, and I carried this
over without noticing.
Steffen
^ permalink raw reply
* Re: [PATCH 1/6] push: mention --verbose option in documentation
From: Steffen Prohaska @ 2007-11-11 14:10 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <11947897083381-git-send-email-prohaska@zib.de>
On Nov 11, 2007, at 3:01 PM, Steffen Prohaska wrote:
> From: Steffen Prohaska <gitster@pobox.com>
This is obviously wrong. I have no clear idea how this happend.
I remember I took the topic branch sp/push-refspec from pu and
started to refactor. I used 'rebase' and 'rebase -i' a couple
of times and now I have my name with Junios email address.
I'll investigate how this could happen.
Steffen
^ permalink raw reply
* [PATCH 1/6] push: mention --verbose option in documentation
From: Steffen Prohaska @ 2007-11-11 14:01 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska, Steffen Prohaska
In-Reply-To: <1194789708646-git-send-email-prohaska@zib.de>
From: Steffen Prohaska <gitster@pobox.com>
Before this commit, only '-v' was documented.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
Documentation/git-push.txt | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index e5dd4c1..4a68aab 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'git-push' [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>]
- [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]
+ [--repo=all] [-f | --force] [-v | --verbose] [<repository> <refspec>...]
DESCRIPTION
-----------
@@ -95,7 +95,7 @@ the remote repository.
transfer spends extra cycles to minimize the number of
objects to be sent and meant to be used on slower connection.
--v::
+-v, \--verbose::
Run verbosely.
include::urls-remotes.txt[]
--
1.5.3.5.578.g886d
^ permalink raw reply related
* Re: git rm --cached
From: Jan Hudec @ 2007-11-11 14:05 UTC (permalink / raw)
To: git
In-Reply-To: <20071102021711.GA28703@fawkes.hq.digizenstudio.com>
[-- Attachment #1: Type: text/plain, Size: 679 bytes --]
On Thu, Nov 01, 2007 at 22:17:11 -0400, Jing Xue wrote:
> In the following scenario, why do I have to run 'git reset' following
> 'git rm --cached 1.txt' to revert to exactly where I was before 'git add
> 1.txt'? Shouldn't 'git rm --cached' have done that already?
The message in git-commit suggesting to use 'git rm --cached' to unstage is
just plain wrong. It really should mention 'git reset'.
git rm, as the name suggests, *removes* the file.
git reset, as the name suggests, reverts it to the state it was before (but,
somewhat confusingly, with path limit only resets the index, so no --cached
option there).
--
Jan 'Bulb' Hudec <bulb@ucw.cz>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH 2/6] push: teach push to pass --verbose option to transport layer
From: Steffen Prohaska @ 2007-11-11 14:01 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska, Steffen Prohaska
In-Reply-To: <11947897083381-git-send-email-prohaska@zib.de>
From: Steffen Prohaska <gitster@pobox.com>
A --verbose option to push should also be passed to the
transport layer, i.e. git-send-pack, git-http-push.
git push is modified to do so.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-push.c | 2 ++
transport.c | 8 ++++++--
transport.h | 1 +
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/builtin-push.c b/builtin-push.c
index 2c56195..6d1da07 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -115,6 +115,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
flags |= TRANSPORT_PUSH_FORCE;
if (dry_run)
flags |= TRANSPORT_PUSH_DRY_RUN;
+ if (verbose)
+ flags |= TRANSPORT_PUSH_VERBOSE;
if (tags)
add_refspec("refs/tags/*");
if (all)
diff --git a/transport.c b/transport.c
index fa5cfbb..e8a2608 100644
--- a/transport.c
+++ b/transport.c
@@ -386,7 +386,7 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
int argc;
int err;
- argv = xmalloc((refspec_nr + 11) * sizeof(char *));
+ argv = xmalloc((refspec_nr + 12) * sizeof(char *));
argv[0] = "http-push";
argc = 1;
if (flags & TRANSPORT_PUSH_ALL)
@@ -395,6 +395,8 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
argv[argc++] = "--force";
if (flags & TRANSPORT_PUSH_DRY_RUN)
argv[argc++] = "--dry-run";
+ if (flags & TRANSPORT_PUSH_VERBOSE)
+ argv[argc++] = "--verbose";
argv[argc++] = transport->url;
while (refspec_nr--)
argv[argc++] = *refspec++;
@@ -655,7 +657,7 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const
int argc;
int err;
- argv = xmalloc((refspec_nr + 11) * sizeof(char *));
+ argv = xmalloc((refspec_nr + 12) * sizeof(char *));
argv[0] = "send-pack";
argc = 1;
if (flags & TRANSPORT_PUSH_ALL)
@@ -664,6 +666,8 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const
argv[argc++] = "--force";
if (flags & TRANSPORT_PUSH_DRY_RUN)
argv[argc++] = "--dry-run";
+ if (flags & TRANSPORT_PUSH_VERBOSE)
+ argv[argc++] = "--verbose";
if (data->receivepack) {
char *rp = xmalloc(strlen(data->receivepack) + 16);
sprintf(rp, "--receive-pack=%s", data->receivepack);
diff --git a/transport.h b/transport.h
index df12ea7..2f80ab4 100644
--- a/transport.h
+++ b/transport.h
@@ -30,6 +30,7 @@ struct transport {
#define TRANSPORT_PUSH_ALL 1
#define TRANSPORT_PUSH_FORCE 2
#define TRANSPORT_PUSH_DRY_RUN 4
+#define TRANSPORT_PUSH_VERBOSE 8
/* Returns a transport suitable for the url */
struct transport *transport_get(struct remote *, const char *);
--
1.5.3.5.578.g886d
^ permalink raw reply related
* [PATCH 3/6] push: support pushing HEAD to real branch name
From: Steffen Prohaska @ 2007-11-11 14:01 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska, Steffen Prohaska
In-Reply-To: <11947897081278-git-send-email-prohaska@zib.de>
From: Steffen Prohaska <gitster@pobox.com>
This teaches "push <remote> HEAD" to resolve HEAD on the local
side to its real branch name, e.g. master, and then act as if
the real branch name was specified. So we have a shorthand for
pushing the current branch. Besides HEAD, no other symbolic ref
is resolved.
Thanks to Daniel Barkalow <barkalow@iabervon.org> for suggesting
this implementation, which is much simpler than the
implementation proposed before.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin-push.c | 9 +++++++++
t/t5516-fetch-push.sh | 17 +++++++++++++++++
2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/builtin-push.c b/builtin-push.c
index 6d1da07..a99ba0c 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -44,6 +44,15 @@ static void set_refspecs(const char **refs, int nr)
strcat(tag, refs[i]);
ref = tag;
}
+ if (!strcmp("HEAD", ref)) {
+ unsigned char sha1_dummy[20];
+ ref = resolve_ref(ref, sha1_dummy, 1, NULL);
+ if (!ref)
+ die("HEAD cannot be resolved.");
+ if (strncmp(ref, "refs/heads/", 11))
+ die("HEAD cannot be resolved to branch.");
+ ref = xstrdup(ref + 11);
+ }
add_refspec(ref);
}
}
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 86f9b53..b0ff488 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -244,6 +244,23 @@ test_expect_success 'push with colon-less refspec (4)' '
'
+test_expect_success 'push with HEAD' '
+
+ mk_test heads/master &&
+ git checkout master &&
+ git push testrepo HEAD &&
+ check_push_result $the_commit heads/master
+
+'
+
+test_expect_success 'push with HEAD nonexisting at remote' '
+
+ mk_test heads/master &&
+ git checkout -b local master &&
+ git push testrepo HEAD &&
+ check_push_result $the_commit heads/local
+'
+
test_expect_success 'push with dry-run' '
mk_test heads/master &&
--
1.5.3.5.578.g886d
^ permalink raw reply related
* [PATCH 4/6] add ref_abbrev_matches_full_with_rules()
From: Steffen Prohaska @ 2007-11-11 14:01 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <11947897083159-git-send-email-prohaska@zib.de>
We use at least two rulesets for matching abbreviated refnames with
full refnames (starting with 'refs/'). git-rev-parse and git-fetch
use slightly different rules.
This commit introduces a new function
ref_abbrev_matches_full_with_rules(
const char *abbrev_name, const char *full_name, const char **rules).
abbrev_name is expanded using the rules and matched against full_name.
If a match is found the function returns true. rules is a NULL-terminate
list of format patterns with "%.*s", for example
const char *ref_rev_parse_rules[] = {
"%.*s",
"refs/%.*s",
"refs/tags/%.*s",
"refs/heads/%.*s",
"refs/remotes/%.*s",
"refs/remotes/%.*s/HEAD",
NULL
};
Asterisks are included in the format strings because this is the form
required in sha1_name.c. Sharing the list with the functions there is
a good idea to avoid duplicating the rules. Hopefully this
facilitates unified matching rules in the future.
This commit makes the rules used by rev-parse for resolving refs to
sha1s available for string comparison. Before this change, the rules
were buried in get_sha1*() and dwim_ref().
A follow-up commit will refactor the rules used by fetch.
ref_abbrev_matches_full_with_rules() will be used for matching
refspecs in git-send-pack.
Thanks to Daniel Barkalow <barkalow@iabervon.org> for pointing
out that ref_matches_abbrev in remote.c solves a similar problem
and care should be taken to avoid confusion.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
cache.h | 3 +++
refs.c | 24 ++++++++++++++++++++++++
sha1_name.c | 14 ++------------
3 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/cache.h b/cache.h
index f0a25c7..d36b91d 100644
--- a/cache.h
+++ b/cache.h
@@ -409,6 +409,9 @@ extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *
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);
+extern int ref_abbrev_matches_full_with_rules(const char *abbrev_name, const char *full_name, const char **rules);
+extern const char *ref_rev_parse_rules[];
+
extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg);
extern int validate_headref(const char *ref);
diff --git a/refs.c b/refs.c
index aff02cd..4bb16e5 100644
--- a/refs.c
+++ b/refs.c
@@ -655,6 +655,30 @@ int check_ref_format(const char *ref)
}
}
+const char *ref_rev_parse_rules[] = {
+ "%.*s",
+ "refs/%.*s",
+ "refs/tags/%.*s",
+ "refs/heads/%.*s",
+ "refs/remotes/%.*s",
+ "refs/remotes/%.*s/HEAD",
+ NULL
+};
+
+int ref_abbrev_matches_full_with_rules(const char *abbrev_name, const char *full_name, const char **rules)
+{
+ const char **p;
+ const int abbrev_name_len = strlen(abbrev_name);
+
+ for (p = rules; *p; p++) {
+ if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static struct ref_lock *verify_lock(struct ref_lock *lock,
const unsigned char *old_sha1, int mustexist)
{
diff --git a/sha1_name.c b/sha1_name.c
index 2d727d5..d364244 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -239,23 +239,13 @@ static int ambiguous_path(const char *path, int len)
return slash;
}
-static const char *ref_fmt[] = {
- "%.*s",
- "refs/%.*s",
- "refs/tags/%.*s",
- "refs/heads/%.*s",
- "refs/remotes/%.*s",
- "refs/remotes/%.*s/HEAD",
- NULL
-};
-
int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
{
const char **p, *r;
int refs_found = 0;
*ref = NULL;
- for (p = ref_fmt; *p; p++) {
+ for (p = ref_rev_parse_rules; *p; p++) {
unsigned char sha1_from_ref[20];
unsigned char *this_result;
@@ -277,7 +267,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
int logs_found = 0;
*log = NULL;
- for (p = ref_fmt; *p; p++) {
+ for (p = ref_rev_parse_rules; *p; p++) {
struct stat st;
unsigned char hash[20];
char path[PATH_MAX];
--
1.5.3.5.578.g886d
^ permalink raw reply related
* [REPLACEMENT PATCH 0/6] improve refspec handling in push, refactor matching in fetch
From: Steffen Prohaska @ 2007-11-11 14:01 UTC (permalink / raw)
To: git
This is a replacement for sp/push-refspec. It is rebased to the current master.
Documentation/git-push.txt | 4 ++--
Documentation/git-send-pack.txt | 4 +++-
builtin-push.c | 11 +++++++++++
cache.h | 4 ++++
refs.c | 31 +++++++++++++++++++++++++++++++
remote.c | 28 +++-------------------------
sha1_name.c | 14 ++------------
t/t5510-fetch.sh | 25 +++++++++++++++++++++++++
t/t5516-fetch-push.sh | 29 ++++++++++++++++++++++++++++-
transport.c | 8 ++++++--
transport.h | 1 +
11 files changed, 116 insertions(+), 43 deletions(-)
[PATCH 1/6] push: mention --verbose option in documentation
Push uses parseopts, which supports '--verbose'.
[PATCH 2/6] push: teach push to pass --verbose option to transport layer
Adapted to paresopts changes.
[PATCH 3/6] push: support pushing HEAD to real branch name
Same as before.
[PATCH 4/6] add ref_abbrev_matches_full_with_rules()
[PATCH 5/6] push: use same rules as git-rev-parse to resolve refspecs
[PATCH 6/6] refactor fetch's ref matching to use ref_abbrev_matches_full_with_rules()
Start unification of refspec matching rules.
^ permalink raw reply
* [PATCH 6/6] refactor fetch's ref matching to use ref_abbrev_matches_full_with_rules()
From: Steffen Prohaska @ 2007-11-11 14:01 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <1194789709671-git-send-email-prohaska@zib.de>
The old rules used by fetch were coded as a series of ifs. The old
rules are:
1) match full refname if it starts with "refs/" or matches "HEAD"
2) verify that full refname starts with "refs/"
3) match abbreviated name in "refs/" if it starts with "heads/",
"tags/", or "remotes/".
4) match abbreviated name in "refs/heads/"
This is replaced by the new rules
a) match full refname
b) match abbreviated name prefixed with "refs/"
c) match abbreviated name prefixed with "refs/heads/"
The details of the new rules are different from the old rules. We no
longer verify that the full refname starts with "refs/". The new rule
(a) matches any full string. The old rules (1) and (2) were stricter.
Now, the caller is responsible for using sensible full refnames. This
should be the case for the current code. The new rule (b) is less
strict than old rule (3). The new rule accepts abbreviated names that
start with a non-standard prefix below "refs/".
Despite this modifications the new rules should handle all cases as
expected. Two tests are added to verify that fetch does not resolve
short tags or HEAD in remotes.
We may even think about loosening the rules a bit more and unify them
with the rev-parse rules. This would be done by replacing
ref_ref_fetch_rules with ref_ref_parse_rules. Note, the two new test
would break.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
cache.h | 1 +
refs.c | 7 +++++++
remote.c | 23 ++---------------------
t/t5510-fetch.sh | 25 +++++++++++++++++++++++++
4 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/cache.h b/cache.h
index d36b91d..1313378 100644
--- a/cache.h
+++ b/cache.h
@@ -411,6 +411,7 @@ extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
extern int ref_abbrev_matches_full_with_rules(const char *abbrev_name, const char *full_name, const char **rules);
extern const char *ref_rev_parse_rules[];
+extern const char *ref_fetch_rules[];
extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg);
extern int validate_headref(const char *ref);
diff --git a/refs.c b/refs.c
index 4bb16e5..7db2146 100644
--- a/refs.c
+++ b/refs.c
@@ -665,6 +665,13 @@ const char *ref_rev_parse_rules[] = {
NULL
};
+const char *ref_fetch_rules[] = {
+ "%.*s",
+ "refs/%.*s",
+ "refs/heads/%.*s",
+ NULL
+};
+
int ref_abbrev_matches_full_with_rules(const char *abbrev_name, const char *full_name, const char **rules)
{
const char **p;
diff --git a/remote.c b/remote.c
index 28d8eb7..2dfce70 100644
--- a/remote.c
+++ b/remote.c
@@ -417,25 +417,6 @@ int remote_has_url(struct remote *remote, const char *url)
return 0;
}
-/*
- * Returns true if, under the matching rules for fetching, name is the
- * same as the given full name.
- */
-static int ref_matches_abbrev(const char *name, const char *full)
-{
- if (!prefixcmp(name, "refs/") || !strcmp(name, "HEAD"))
- return !strcmp(name, full);
- if (prefixcmp(full, "refs/"))
- return 0;
- if (!prefixcmp(name, "heads/") ||
- !prefixcmp(name, "tags/") ||
- !prefixcmp(name, "remotes/"))
- return !strcmp(name, full + 5);
- if (prefixcmp(full + 5, "heads/"))
- return 0;
- return !strcmp(full + 11, name);
-}
-
int remote_find_tracking(struct remote *remote, struct refspec *refspec)
{
int find_src = refspec->src == NULL;
@@ -804,7 +785,7 @@ int branch_merge_matches(struct branch *branch,
{
if (!branch || i < 0 || i >= branch->merge_nr)
return 0;
- return ref_matches_abbrev(branch->merge[i]->src, refname);
+ return ref_abbrev_matches_full_with_rules(branch->merge[i]->src, refname, ref_fetch_rules);
}
static struct ref *get_expanded_map(struct ref *remote_refs,
@@ -843,7 +824,7 @@ static struct ref *find_ref_by_name_abbrev(struct ref *refs, const char *name)
{
struct ref *ref;
for (ref = refs; ref; ref = ref->next) {
- if (ref_matches_abbrev(name, ref->name))
+ if (ref_abbrev_matches_full_with_rules(name, ref->name, ref_fetch_rules))
return ref;
}
return NULL;
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index aad863d..2025742 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -95,6 +95,31 @@ test_expect_success 'fetch following tags' '
'
+test_expect_failure 'fetch must not resolve short tag name' '
+
+ cd "$D" &&
+
+ mkdir five &&
+ cd five &&
+ git init &&
+
+ git fetch .. anno:five
+
+'
+
+test_expect_failure 'fetch must not resolve short remote name' '
+
+ cd "$D" &&
+ git-update-ref refs/remotes/six/HEAD HEAD
+
+ mkdir six &&
+ cd six &&
+ git init &&
+
+ git fetch .. six:six
+
+'
+
test_expect_success 'create bundle 1' '
cd "$D" &&
echo >file updated again by origin &&
--
1.5.3.5.578.g886d
^ permalink raw reply related
* [PATCH 5/6] push: use same rules as git-rev-parse to resolve refspecs
From: Steffen Prohaska @ 2007-11-11 14:01 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <11947897083265-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 may break existing setups. For example "master" will no longer
resolve to "origin/master".
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
Documentation/git-send-pack.txt | 4 +++-
remote.c | 5 +----
t/t5516-fetch-push.sh | 12 +++++++++++-
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index 2fa01d4..a2d9cb6 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -85,7 +85,9 @@ Each pattern pair consists of the source side (before the colon)
and the destination side (after the colon). The ref to be
pushed is determined by finding a match that matches the source
side, and where it is pushed is determined by using the
-destination side.
+destination side. The rules used to match a ref are the same
+rules used by gitlink:git-rev-parse[1] to resolve a symbolic ref
+name.
- It is an error if <src> does not match exactly one of the
local refs.
diff --git a/remote.c b/remote.c
index bec2ba1..28d8eb7 100644
--- a/remote.c
+++ b/remote.c
@@ -519,10 +519,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_abbrev_matches_full_with_rules(pattern, name, ref_rev_parse_rules))
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 b0ff488..fd5f284 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -145,11 +145,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.5.578.g886d
^ 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