* Re: Prompt for merge message?
From: Stephen Bash @ 2011-10-06 20:15 UTC (permalink / raw)
To: in-gitvger; +Cc: Todd A. Jacobs, git
In-Reply-To: <201110061851.p96Ipfui016139@no.baka.org>
----- Original Message -----
> From: in-gitvger@baka.org
> Sent: Thursday, October 6, 2011 2:51:41 PM
> Subject: Re: Prompt for merge message?
>
> In message <20111006182534.GA13628@vfa-6h>, Jacob Helwig writes:
>
> On Thu, 06 Oct 2011 10:49:02 -0700, Todd A. Jacobs wrote:
>
> > I often find myself using "--no-ff -m foo" for merging short-lived
> > branches, because the merge commit usually needs to say something
> > about having finished a feature rather than referring to a branch
> > that
> > will be deleted shortly anyway. However, it's a little annoying to
> > have to always write the commit message on the command-line,
> > especially in cases where a more expository multi-line message would
> > be useful.
>
> "git merge --no-ff --no-commit branch_foo && git commit" ?
>
> While not ideal, you can use a multi-line message on the command line.
> I do it all of the time. Popping up an editor like in the separated
> workflow is more user friendly.
>
> ----------------------------------------------------------------------
> git merge --no-ff -m "My feature is very complex
>
> It requires multiple lines to explain.
>
> Or perhaps I am too verbose." branch_foo
> ----------------------------------------------------------------------
And not so helpful if you want to use the --log option to pre-populate the merge message (which I often run into).
Thanks,
Stephen
^ permalink raw reply
* Re: Prompt for merge message?
From: Andreas Krey @ 2011-10-06 20:19 UTC (permalink / raw)
To: Jacob Helwig; +Cc: Todd A. Jacobs, git
In-Reply-To: <20111006182534.GA13628@vfa-6h>
On Thu, 06 Oct 2011 11:25:34 +0000, Jacob Helwig wrote:
> "git merge --no-ff --no-commit branch_foo && git commit" ?
"git merge --no-ff branch_foo && git commit --amend"
Andreas
^ permalink raw reply
* [PATCH 2/3] fetch: honor the user-provided refspecs when pruning refs
From: Carlos Martín Nieto @ 2011-10-06 20:19 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1317932385-28604-1-git-send-email-cmn@elego.de>
If the user gave us refspecs on the command line, we should use those
when deciding whether to prune a ref instead of relying on the
refspecs in the config.
Previously, running
git fetch --prune origin refs/heads/master:refs/remotes/origin/master
would delete every other tag under the origin namespace because we
were using the refspec to filter the available refs but using the
configured refspec to figure out if a ref had been deleted on the
remote. This is clearly the wrong thing to do.
Teach get_stale_heads about user-provided refspecs and use them if
they're available.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
builtin/fetch.c | 6 ++--
builtin/remote.c | 2 +-
remote.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-----
remote.h | 3 +-
4 files changed, 73 insertions(+), 12 deletions(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 30b485e..b937d71 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -505,10 +505,10 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
return ret;
}
-static int prune_refs(struct transport *transport, struct ref *ref_map)
+static int prune_refs(struct transport *transport, struct refspec *refs, int n, struct ref *ref_map)
{
int result = 0;
- struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map);
+ struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map, refs, n);
const char *dangling_msg = dry_run
? _(" (%s will become dangling)\n")
: _(" (%s has become dangling)\n");
@@ -700,7 +700,7 @@ static int do_fetch(struct transport *transport,
return 1;
}
if (prune)
- prune_refs(transport, ref_map);
+ prune_refs(transport, refs, ref_count, ref_map);
free_refs(ref_map);
/* if neither --no-tags nor --tags was specified, do automated tag
diff --git a/builtin/remote.c b/builtin/remote.c
index b25dfb4..91a2148 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -349,7 +349,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
else
string_list_append(&states->tracked, abbrev_branch(ref->name));
}
- stale_refs = get_stale_heads(states->remote, fetch_map);
+ stale_refs = get_stale_heads(states->remote, fetch_map, NULL, 0);
for (ref = stale_refs; ref; ref = ref->next) {
struct string_list_item *item =
string_list_append(&states->stale, abbrev_branch(ref->name));
diff --git a/remote.c b/remote.c
index 7840d2f..72a26d3 100644
--- a/remote.c
+++ b/remote.c
@@ -1684,26 +1684,84 @@ struct stale_heads_info {
struct remote *remote;
struct string_list *ref_names;
struct ref **stale_refs_tail;
+ struct refspec *refs;
+ int ref_count;
};
+/*
+ * Find a refspec to a remote's
+ * Returns 0 on success, -1 if it couldn't find a the refspec
+ */
+static int find_in_refs(struct refspec *refs, int ref_count, struct refspec *query)
+{
+ int i;
+ struct refspec *refspec;
+
+ for (i = 0; i < ref_count; ++i) {
+ refspec = &refs[i];
+
+ /*
+ * No '*' means that it must match exactly. If it does
+ * have it, try to match it against the pattern. If
+ * the refspec matches, store the ref name as it would
+ * appear in the server in query->src.
+ */
+ if (!strchr(refspec->dst, '*')) {
+ if (!strcmp(query->dst, refspec->dst)) {
+ query->src = xstrdup(refspec->src);
+ return 0;
+ }
+ } else {
+ if (match_name_with_pattern(refspec->dst, query->dst,
+ refspec->src, &query->src)) {
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
static int get_stale_heads_cb(const char *refname,
const unsigned char *sha1, int flags, void *cb_data)
{
struct stale_heads_info *info = cb_data;
struct refspec refspec;
+ int ret;
memset(&refspec, 0, sizeof(refspec));
refspec.dst = (char *)refname;
- if (!remote_find_tracking(info->remote, &refspec)) {
- if (!((flags & REF_ISSYMREF) ||
- string_list_has_string(info->ref_names, refspec.src))) {
- struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
- hashcpy(ref->new_sha1, sha1);
- }
+
+ /*
+ * If the user speicified refspecs on the command line, we
+ * should only use those to check. Otherwise, look in the
+ * remote's configuration for the branch.
+ */
+ if (info->ref_count)
+ ret = find_in_refs(info->refs, info->ref_count, &refspec);
+ else
+ ret = remote_find_tracking(info->remote, &refspec);
+
+ /* No matches */
+ if (ret)
+ return 0;
+
+ /*
+ * If we did find a suitable refspec and it's not a symref and
+ * it's not in the list of refs that currently exist in that
+ * remote we consider it to be stale.
+ */
+ if (!((flags & REF_ISSYMREF) ||
+ string_list_has_string(info->ref_names, refspec.src))) {
+ struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
+ hashcpy(ref->new_sha1, sha1);
}
+
+ free(refspec.src);
return 0;
}
-struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map)
+struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map,
+ struct refspec *refs, int ref_count)
{
struct ref *ref, *stale_refs = NULL;
struct string_list ref_names = STRING_LIST_INIT_NODUP;
@@ -1711,6 +1769,8 @@ struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map)
info.remote = remote;
info.ref_names = &ref_names;
info.stale_refs_tail = &stale_refs;
+ info.refs = refs;
+ info.ref_count = ref_count;
for (ref = fetch_map; ref; ref = ref->next)
string_list_append(&ref_names, ref->name);
sort_string_list(&ref_names);
diff --git a/remote.h b/remote.h
index 9a30a9d..2f753a0 100644
--- a/remote.h
+++ b/remote.h
@@ -164,6 +164,7 @@ struct ref *guess_remote_head(const struct ref *head,
int all);
/* Return refs which no longer exist on remote */
-struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map);
+struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map,
+ struct refspec *refs, int ref_count);
#endif
--
1.7.5.2.354.g349bf
^ permalink raw reply related
* [PATCH 0/3] Be more careful when prunning
From: Carlos Martín Nieto @ 2011-10-06 20:19 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
Hello,
The first patch is not that big a deal, but it's better if we're
freeing the refspecs, we might as well free all of them.
The second patch teaches get_stale_heads to use the user-provided
refspecs instead of the ones in the config. For example, running
git fetch --prune origin refs/heads/master:refs/heads/master
doesn't remove the other branches anymore. For a more interesting (and
believable) example, let's take
git fetch --prune origin refs/heads/b/*:refs/heads/b/*
because you want to prune the refs inside the b/ namespace
only. Currently git will delete all the refs that aren't under that
namespace. With the second patch applied, git won't remove any refs
outside the b/ namespace.
What is probably the most usual case is covered by the third patch,
which pretends that a "refs/tags/*:refs/tags/*" refspec was given on
the command-line.
Cheers,
cmn
Carlos Martín Nieto (3):
fetch: free all the additional refspecs
fetch: honor the user-provided refspecs when pruning refs
fetch: treat --tags like refs/tags/*:refs/tags/* when pruning
builtin/fetch.c | 19 ++++++++++---
builtin/remote.c | 2 +-
remote.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-----
remote.h | 3 +-
4 files changed, 84 insertions(+), 14 deletions(-)
--
1.7.5.2.354.g349bf
^ permalink raw reply
* [PATCH 3/3] fetch: treat --tags like refs/tags/*:refs/tags/* when pruning
From: Carlos Martín Nieto @ 2011-10-06 20:19 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1317932385-28604-1-git-send-email-cmn@elego.de>
If --tags is specified, add that refspec to the list given to prune_refs
so it knows to treat it as a filter on what refs to should consider
for prunning. This way
git fetch --prune --tags origin
only prunes tags and doesn't delete the branch refs.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
builtin/fetch.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index b937d71..94b2bd3 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -699,8 +699,17 @@ static int do_fetch(struct transport *transport,
free_refs(ref_map);
return 1;
}
- if (prune)
+ if (prune) {
+ /* If --tags was specified, we need to tell prune_refs
+ * that we're filtering the refs from the remote */
+ if (tags == TAGS_SET) {
+ const char * tags_refspec = "refs/tags/*:refs/tags/*";
+ refs = xrealloc(refs, (ref_count + 1) * sizeof(struct refspec));
+ refs[ref_count] = *parse_fetch_refspec(1, &tags_refspec);
+ ref_count++;
+ }
prune_refs(transport, refs, ref_count, ref_map);
+ }
free_refs(ref_map);
/* if neither --no-tags nor --tags was specified, do automated tag
--
1.7.5.2.354.g349bf
^ permalink raw reply related
* [PATCH 1/3] fetch: free all the additional refspecs
From: Carlos Martín Nieto @ 2011-10-06 20:19 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1317932385-28604-1-git-send-email-cmn@elego.de>
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
builtin/fetch.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7a4e41c..30b485e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -883,7 +883,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
atexit(unlock_pack);
refspec = parse_fetch_refspec(ref_nr, refs);
exit_code = do_fetch(transport, refspec, ref_nr);
- free(refspec);
+ free_refspec(ref_nr, refspec);
transport_disconnect(transport);
transport = NULL;
return exit_code;
--
1.7.5.2.354.g349bf
^ permalink raw reply related
* Pull --rebase looses merge information
From: Duane Murphy @ 2011-10-06 19:21 UTC (permalink / raw)
To: git
Here is the synopsis:
$ git checkout master
$ git pull
... time passes ...
$ git checkout topic # remote topic
$ git checkout master
$ git merge topic
$ git push
non-fast-forward updates were rejected
$ git pull
merge by rebase; implied by config
$ git push
The result of this process is that the file changes are pushed but the reference back to the topic branch has been lost. This makes it appear as though the topic branch has not been merged properly.
The trigger appears to be the pull (with rebase) that occurs after the merge and before the push. This of course is caused by the repo being out of sync from the point when the merge was started. That window of time can be shortened but it can never be zero.
The problem is fixed by merging again, but it's difficult to notice that this problem has actually occurred.
It has been noted that the problem is that we are using rebase on pull. We set our configurations to always rebase on a pull from a remote branch. This makes sense as it prevents artificial merges and unusual modifications to the history with respect to the shared repository. That is, if I'm working on merging changes into a remote branch and some one beats me, my merge should be after his, not before.
I would hope that a rebase operates mostly like a merge (understanding that rebase is different). I would not expect the merge information (ie the source branch of the merge) to be lost just because of a rebase.
Is there a bug here? Is there some way to avoid this situation without sacrificing the benefits of pull --rebase?
Thanks,
...Duane
^ permalink raw reply
* Re: [PATCH] merge-one-file: fix "expr: non-numeric argument"
From: Junio C Hamano @ 2011-10-06 20:25 UTC (permalink / raw)
To: Jay Soffian; +Cc: git
In-Reply-To: <1317925555-65237-1-git-send-email-jaysoffian@gmail.com>
Thanks.
^ permalink raw reply
* Re: Pull --rebase looses merge information
From: in-gitvger @ 2011-10-06 20:31 UTC (permalink / raw)
To: Duane Murphy; +Cc: git
In-Reply-To: <DECF417E-50BB-4963-965C-BEF1B5C95DAC@mac.com>
In message <DECF417E-50BB-4963-965C-BEF1B5C95DAC@mac.com>, Duane Murphy writes:
$ git merge topic
$ git pull
merge by rebase; implied by config
$ git push
The result of this process is that the file changes are pushed but
the reference back to the topic branch has been lost. This makes
it appear as though the topic branch has not been merged properly.
[...]
Is there a bug here? Is there some way to avoid this situation
without sacrificing the benefits of pull --rebase?
Yes, but it currently is annoying.
Instead of `git pull --rebase` you need to run
`git fetch && git rebase -p @{u}`
It would be very nice if the -p argument to rebase could be
automatically included in the `git pull --rebase`.
I personally believe all pull should be --rebase, all merges should be
--no-ff, and all rebases should be -p. At least by default. But that
is just me.
-Seth Robertson
^ permalink raw reply
* Re: [PATCH 0/3] Be more careful when prunning
From: Ben Boeckel @ 2011-10-06 20:51 UTC (permalink / raw)
To: Carlos Martín Nieto; +Cc: git, Jeff King, Junio C Hamano
In-Reply-To: <1317932385-28604-1-git-send-email-cmn@elego.de>
On Thu, Oct 06, 2011 at 22:19:42 +0200, Carlos Martín Nieto wrote:
> The first patch is not that big a deal, but it's better if we're
> freeing the refspecs, we might as well free all of them.
>
> The second patch teaches get_stale_heads to use the user-provided
> refspecs instead of the ones in the config. For example, running
>
> git fetch --prune origin refs/heads/master:refs/heads/master
>
> doesn't remove the other branches anymore. For a more interesting (and
> believable) example, let's take
>
> git fetch --prune origin refs/heads/b/*:refs/heads/b/*
>
> because you want to prune the refs inside the b/ namespace
> only. Currently git will delete all the refs that aren't under that
> namespace. With the second patch applied, git won't remove any refs
> outside the b/ namespace.
>
> What is probably the most usual case is covered by the third patch,
> which pretends that a "refs/tags/*:refs/tags/*" refspec was given on
> the command-line.
I applied the patches to current master (7f41b6b) and got a segfault
with:
git fetch -p -t origin master
It does not happen with master.
Backtrace:
(gdb) bt
#0 0x00007ffff7395d18 in __strchr_sse42 () from /lib64/libc.so.6
#1 0x00000000004b2d39 in find_in_refs (query=0x7fffffffdb90, ref_count=2, refs=<optimized out>) at remote.c:1709
#2 get_stale_heads_cb (refname=0x7a8f31 "refs/heads/a/branch/name", sha1=0x7a8f09 "\367\343\375C٩\223u\305OG\233)z\347X\370\333\325", <incomplete sequence \335>, flags=0, cb_data=0x7fffffffdc50) at remote.c:1740
#3 0x00000000004adf19 in do_for_each_ref (submodule=<optimized out>, base=0x4ea1c2 "", fn=0x4b2ca0 <get_stale_heads_cb>, trim=0, flags=0, cb_data=0x7fffffffdc50) at refs.c:684
#4 0x00000000004b4249 in get_stale_heads (remote=<optimized out>, fetch_map=<optimized out>, refs=<optimized out>, ref_count=<optimized out>) at remote.c:1777
#5 0x0000000000426cfb in prune_refs (ref_map=<optimized out>, n=<optimized out>, refs=<optimized out>, transport=0x78e040) at builtin/fetch.c:511
#6 do_fetch (ref_count=<optimized out>, refs=<optimized out>, transport=0x78e040) at builtin/fetch.c:711
#7 fetch_one (remote=<optimized out>, argc=<optimized out>, argv=<optimized out>) at builtin/fetch.c:894
#8 0x0000000000427550 in cmd_fetch (argc=2, argv=0x7fffffffe070, prefix=0x0) at builtin/fetch.c:955
#9 0x0000000000405084 in run_builtin (argv=0x7fffffffe070, argc=5, p=0x731b08) at git.c:308
#10 handle_internal_command (argc=5, argv=0x7fffffffe070) at git.c:466
#11 0x000000000040448b in run_argv (argv=0x7fffffffdf10, argcp=0x7fffffffdf1c) at git.c:512
#12 main (argc=5, argv=0x7fffffffe070) at git.c:585
--Ben
^ permalink raw reply
* Re: [PATCH v3 0/5] reroll bc/attr-ignore-case
From: Junio C Hamano @ 2011-10-06 20:57 UTC (permalink / raw)
To: Brandon Casey; +Cc: git, peff, j.sixt
In-Reply-To: <U4wiHVyDLLG1PhI-8iY3YvK8PNPcrE_H1LfZdeQFnOrSJ5O-Hev7KzBOnrAY-vjiT2yzgWpfSAPFG2-cG0LrUPezOcTUNC6trUWFODOXIkXyJzvz-maBv6HrPKDCs98TTT4OGmgo0j8@cipher.nrlssc.navy.mil>
Thanks.
^ permalink raw reply
* Re: [PATCH 0/3] Be more careful when prunning
From: Carlos Martín Nieto @ 2011-10-06 20:58 UTC (permalink / raw)
To: mathstuf; +Cc: git, Jeff King, Junio C Hamano
In-Reply-To: <20111006205103.GA1271@erythro.kitwarein.com>
[-- Attachment #1: Type: text/plain, Size: 3136 bytes --]
On Thu, 2011-10-06 at 16:51 -0400, Ben Boeckel wrote:
> On Thu, Oct 06, 2011 at 22:19:42 +0200, Carlos Martín Nieto wrote:
> > The first patch is not that big a deal, but it's better if we're
> > freeing the refspecs, we might as well free all of them.
> >
> > The second patch teaches get_stale_heads to use the user-provided
> > refspecs instead of the ones in the config. For example, running
> >
> > git fetch --prune origin refs/heads/master:refs/heads/master
> >
> > doesn't remove the other branches anymore. For a more interesting (and
> > believable) example, let's take
> >
> > git fetch --prune origin refs/heads/b/*:refs/heads/b/*
> >
> > because you want to prune the refs inside the b/ namespace
> > only. Currently git will delete all the refs that aren't under that
> > namespace. With the second patch applied, git won't remove any refs
> > outside the b/ namespace.
> >
> > What is probably the most usual case is covered by the third patch,
> > which pretends that a "refs/tags/*:refs/tags/*" refspec was given on
> > the command-line.
>
> I applied the patches to current master (7f41b6b) and got a segfault
> with:
>
> git fetch -p -t origin master
>
> It does not happen with master.
I thought I'd got rid of those problems. Thanks for noticing. I'll
investigate.
>
> Backtrace:
>
> (gdb) bt
> #0 0x00007ffff7395d18 in __strchr_sse42 () from /lib64/libc.so.6
> #1 0x00000000004b2d39 in find_in_refs (query=0x7fffffffdb90, ref_count=2, refs=<optimized out>) at remote.c:1709
> #2 get_stale_heads_cb (refname=0x7a8f31 "refs/heads/a/branch/name", sha1=0x7a8f09 "\367\343\375C٩\223u\305OG\233)z\347X\370\333\325", <incomplete sequence \335>, flags=0, cb_data=0x7fffffffdc50) at remote.c:1740
> #3 0x00000000004adf19 in do_for_each_ref (submodule=<optimized out>, base=0x4ea1c2 "", fn=0x4b2ca0 <get_stale_heads_cb>, trim=0, flags=0, cb_data=0x7fffffffdc50) at refs.c:684
> #4 0x00000000004b4249 in get_stale_heads (remote=<optimized out>, fetch_map=<optimized out>, refs=<optimized out>, ref_count=<optimized out>) at remote.c:1777
> #5 0x0000000000426cfb in prune_refs (ref_map=<optimized out>, n=<optimized out>, refs=<optimized out>, transport=0x78e040) at builtin/fetch.c:511
> #6 do_fetch (ref_count=<optimized out>, refs=<optimized out>, transport=0x78e040) at builtin/fetch.c:711
> #7 fetch_one (remote=<optimized out>, argc=<optimized out>, argv=<optimized out>) at builtin/fetch.c:894
> #8 0x0000000000427550 in cmd_fetch (argc=2, argv=0x7fffffffe070, prefix=0x0) at builtin/fetch.c:955
> #9 0x0000000000405084 in run_builtin (argv=0x7fffffffe070, argc=5, p=0x731b08) at git.c:308
> #10 handle_internal_command (argc=5, argv=0x7fffffffe070) at git.c:466
> #11 0x000000000040448b in run_argv (argv=0x7fffffffdf10, argcp=0x7fffffffdf1c) at git.c:512
> #12 main (argc=5, argv=0x7fffffffe070) at git.c:585
>
> --Ben
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* [PATCHv2 0/3] Be more careful when prunning
From: Carlos Martín Nieto @ 2011-10-06 21:21 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <20111006205103.GA1271@erythro.kitwarein.com>
Hello,
The first patch is not that big a deal, but it's better if we're
freeing the refspecs, we might as well free all of them.
The second patch teaches get_stale_heads to use the user-provided
refspecs instead of the ones in the config. For example, running
git fetch --prune origin refs/heads/master:refs/heads/master
doesn't remove the other branches anymore. For a more interesting (and
believable) example, let's take
git fetch --prune origin refs/heads/b/*:refs/heads/b/*
because you want to prune the refs inside the b/ namespace
only. Currently git will delete all the refs that aren't under that
namespace. With the second patch applied, git won't remove any refs
outside the b/ namespace.
What is probably the most usual case is covered by the third patch,
which pretends that a "refs/tags/*:refs/tags/*" refspec was given on
the command-line.
Version 1 assumed that a refspec would have its dst filled
automatically. This is not the case and was fixed in the second patch.
Cheers,
cmn
Carlos Martín Nieto (3):
fetch: free all the additional refspecs
fetch: honor the user-provided refspecs when pruning refs
fetch: treat --tags like refs/tags/*:refs/tags/* when pruning
builtin/fetch.c | 19 ++++++++++---
builtin/remote.c | 2 +-
remote.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-----
remote.h | 3 +-
4 files changed, 84 insertions(+), 14 deletions(-)
--
1.7.5.2.354.g349bf
^ permalink raw reply
* [PATCH 3/3] fetch: treat --tags like refs/tags/*:refs/tags/* when pruning
From: Carlos Martín Nieto @ 2011-10-06 21:21 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1317936107-1230-1-git-send-email-cmn@elego.de>
If --tags is specified, add that refspec to the list given to prune_refs
so it knows to treat it as a filter on what refs to should consider
for prunning. This way
git fetch --prune --tags origin
only prunes tags and doesn't delete the branch refs.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
builtin/fetch.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index b937d71..94b2bd3 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -699,8 +699,17 @@ static int do_fetch(struct transport *transport,
free_refs(ref_map);
return 1;
}
- if (prune)
+ if (prune) {
+ /* If --tags was specified, we need to tell prune_refs
+ * that we're filtering the refs from the remote */
+ if (tags == TAGS_SET) {
+ const char * tags_refspec = "refs/tags/*:refs/tags/*";
+ refs = xrealloc(refs, (ref_count + 1) * sizeof(struct refspec));
+ refs[ref_count] = *parse_fetch_refspec(1, &tags_refspec);
+ ref_count++;
+ }
prune_refs(transport, refs, ref_count, ref_map);
+ }
free_refs(ref_map);
/* if neither --no-tags nor --tags was specified, do automated tag
--
1.7.5.2.354.g349bf
^ permalink raw reply related
* [PATCH 1/3] fetch: free all the additional refspecs
From: Carlos Martín Nieto @ 2011-10-06 21:21 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1317936107-1230-1-git-send-email-cmn@elego.de>
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
builtin/fetch.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7a4e41c..30b485e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -883,7 +883,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
atexit(unlock_pack);
refspec = parse_fetch_refspec(ref_nr, refs);
exit_code = do_fetch(transport, refspec, ref_nr);
- free(refspec);
+ free_refspec(ref_nr, refspec);
transport_disconnect(transport);
transport = NULL;
return exit_code;
--
1.7.5.2.354.g349bf
^ permalink raw reply related
* [PATCH 2/3] fetch: honor the user-provided refspecs when pruning refs
From: Carlos Martín Nieto @ 2011-10-06 21:21 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano, mathstuf
In-Reply-To: <1317936107-1230-1-git-send-email-cmn@elego.de>
If the user gave us refspecs on the command line, we should use those
when deciding whether to prune a ref instead of relying on the
refspecs in the config.
Previously, running
git fetch --prune origin refs/heads/master:refs/remotes/origin/master
would delete every other tag under the origin namespace because we
were using the refspec to filter the available refs but using the
configured refspec to figure out if a ref had been deleted on the
remote. This is clearly the wrong thing to do.
Teach get_stale_heads about user-provided refspecs and use them if
they're available.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
---
builtin/fetch.c | 6 ++--
builtin/remote.c | 2 +-
remote.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++-----
remote.h | 3 +-
4 files changed, 77 insertions(+), 12 deletions(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 30b485e..b937d71 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -505,10 +505,10 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
return ret;
}
-static int prune_refs(struct transport *transport, struct ref *ref_map)
+static int prune_refs(struct transport *transport, struct refspec *refs, int n, struct ref *ref_map)
{
int result = 0;
- struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map);
+ struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map, refs, n);
const char *dangling_msg = dry_run
? _(" (%s will become dangling)\n")
: _(" (%s has become dangling)\n");
@@ -700,7 +700,7 @@ static int do_fetch(struct transport *transport,
return 1;
}
if (prune)
- prune_refs(transport, ref_map);
+ prune_refs(transport, refs, ref_count, ref_map);
free_refs(ref_map);
/* if neither --no-tags nor --tags was specified, do automated tag
diff --git a/builtin/remote.c b/builtin/remote.c
index b25dfb4..91a2148 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -349,7 +349,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
else
string_list_append(&states->tracked, abbrev_branch(ref->name));
}
- stale_refs = get_stale_heads(states->remote, fetch_map);
+ stale_refs = get_stale_heads(states->remote, fetch_map, NULL, 0);
for (ref = stale_refs; ref; ref = ref->next) {
struct string_list_item *item =
string_list_append(&states->stale, abbrev_branch(ref->name));
diff --git a/remote.c b/remote.c
index 7840d2f..28f7917 100644
--- a/remote.c
+++ b/remote.c
@@ -1684,26 +1684,88 @@ struct stale_heads_info {
struct remote *remote;
struct string_list *ref_names;
struct ref **stale_refs_tail;
+ struct refspec *refs;
+ int ref_count;
};
+/*
+ * Find a refspec to a remote's
+ * Returns 0 on success, -1 if it couldn't find a the refspec
+ */
+static int find_in_refs(struct refspec *refs, int ref_count, struct refspec *query)
+{
+ int i;
+ struct refspec *refspec;
+
+ for (i = 0; i < ref_count; ++i) {
+ refspec = &refs[i];
+
+ /* No dst means it can't be used for prunning. */
+ if (!refspec->dst)
+ continue;
+
+ /*
+ * No '*' means that it must match exactly. If it does
+ * have it, try to match it against the pattern. If
+ * the refspec matches, store the ref name as it would
+ * appear in the server in query->src.
+ */
+ if (!strchr(refspec->dst, '*')) {
+ if (!strcmp(query->dst, refspec->dst)) {
+ query->src = xstrdup(refspec->src);
+ return 0;
+ }
+ } else {
+ if (match_name_with_pattern(refspec->dst, query->dst,
+ refspec->src, &query->src)) {
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
static int get_stale_heads_cb(const char *refname,
const unsigned char *sha1, int flags, void *cb_data)
{
struct stale_heads_info *info = cb_data;
struct refspec refspec;
+ int ret;
memset(&refspec, 0, sizeof(refspec));
refspec.dst = (char *)refname;
- if (!remote_find_tracking(info->remote, &refspec)) {
- if (!((flags & REF_ISSYMREF) ||
- string_list_has_string(info->ref_names, refspec.src))) {
- struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
- hashcpy(ref->new_sha1, sha1);
- }
+
+ /*
+ * If the user speicified refspecs on the command line, we
+ * should only use those to check. Otherwise, look in the
+ * remote's configuration for the branch.
+ */
+ if (info->ref_count)
+ ret = find_in_refs(info->refs, info->ref_count, &refspec);
+ else
+ ret = remote_find_tracking(info->remote, &refspec);
+
+ /* No matches */
+ if (ret)
+ return 0;
+
+ /*
+ * If we did find a suitable refspec and it's not a symref and
+ * it's not in the list of refs that currently exist in that
+ * remote we consider it to be stale.
+ */
+ if (!((flags & REF_ISSYMREF) ||
+ string_list_has_string(info->ref_names, refspec.src))) {
+ struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
+ hashcpy(ref->new_sha1, sha1);
}
+
+ free(refspec.src);
return 0;
}
-struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map)
+struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map,
+ struct refspec *refs, int ref_count)
{
struct ref *ref, *stale_refs = NULL;
struct string_list ref_names = STRING_LIST_INIT_NODUP;
@@ -1711,6 +1773,8 @@ struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map)
info.remote = remote;
info.ref_names = &ref_names;
info.stale_refs_tail = &stale_refs;
+ info.refs = refs;
+ info.ref_count = ref_count;
for (ref = fetch_map; ref; ref = ref->next)
string_list_append(&ref_names, ref->name);
sort_string_list(&ref_names);
diff --git a/remote.h b/remote.h
index 9a30a9d..2f753a0 100644
--- a/remote.h
+++ b/remote.h
@@ -164,6 +164,7 @@ struct ref *guess_remote_head(const struct ref *head,
int all);
/* Return refs which no longer exist on remote */
-struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map);
+struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map,
+ struct refspec *refs, int ref_count);
#endif
--
1.7.5.2.354.g349bf
^ permalink raw reply related
* Re: [PATCH] commit: teach --gpg-sign option
From: Junio C Hamano @ 2011-10-06 21:29 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Shawn Pearce, git
In-Reply-To: <20111006171107.GA10973@elie>
Jonathan Nieder <jrnieder@gmail.com> writes:
>> I like this approach better than the prior "push certificate" idea.
>> The signature information is part of the history graph
>
> I probably missed some earlier discussion (so please forgive me this),
Heh, you are not forgiven when the original message has a clear pointer to
the previous discussion ;-).
> but how is it intended to be used? Would projects
>
> a. require as a matter of policy that all commits be signed
Possible. Personally I would _not_ advise it but they can send in a patch
to add a configuration or two if they do want to run their project that
way.
> b. just sign releases as usual, but as commits in the history graph
> instead of tags
This is not meant to replace tags that is attached after the fact. If
anything...
> c. sign the occasional especially interesting commit
...with the definition of "interesting" being "this is tonight's tip of
branch Linus is pushing out between releases", "I shortly will ask Linus
to pull from the history leading up to this commit", etc., this is the
primary scenario I personally envision the feature would be used in.
Without having to have "nightly" signed tags that clutter the tag
namespace, we can gain more confidence in the integrity of the history
between officially tagged release points that may be a few months apart,
depending on projects.
> ... How
> does this relate to the "push certificate" use case, which seemed to
> be mostly about authenticating published branch tips with signatures
> that are not necessarily important in the long term?
To the upstream project whose participants are signing its history, these
publish points may not be important in the longer term, but for downstream
consumers that have to fork from an in-between point for the next embedded
device release track, it serves the same purpose as push certificates and
is equally important: it allows them to limit the length of near-tip
history that might have been tampered that needs to be validated. If the
downstream consumers fork only from a signed commit point, they only need
to audit their own history without worrying about imported stuff after
incident like what k.org had recently.
I am also somewhat disturbed by "have to sign when committing, long before
I am confident that this is worth pushing" aspect of this approach, but I
do not think it would be much of an issue in practice.
- If you are only pubishing one independent branch, it is just the matter
of either "commit --amend --gpg-sign" or "commit --allow-empty --gpg-sign"
before you push;
- If you are publishing multiple related branches (e.g. maint, master,
next) like I do, and want to correct a mistake discovered at a lower
branch (e.g. master) after it has been already merged in higher
branches (e.g. next), you have to either amend the tip of the lower
branch and rebuild the higher branches, or queue a fix-up to the tip of
the lower branch and merge the result to the higher branches _anyway_,
before you push.
^ permalink raw reply
* Re: [PATCH WIP 0/3] git log --exclude
From: Nguyen Thai Ngoc Duy @ 2011-10-06 21:47 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, git, Jonathan Nieder
In-Reply-To: <20111006143441.GA21558@sigill.intra.peff.net>
2011/10/7 Jeff King <peff@peff.net>:
> I'm really just a bystander on this topic, and haven't given it too much
> thought. But one stumbling block I see for narrow clone is how narrow
> repositories will interact with object transfer from other repositories.
>
> For example, if I have a narrow git.git that omits Documentation, and I
> do a "git fetch" from a non-narrow repository, then how do we tell the
> non-narrow remote that we don't have blobs in Documentation, and that
> they should not be used as delta bases for any objects that are sent?
Pretty much how shallow cloned repos interacts. In shallow clone we
send depth info. In narrow clone, we send width info, in terms of
(restricted) pathspec. With pathspec (possibly plus exclude rules but
this possibility is getting smaller), I can express "fetch this
directory only", or "fetch this directory, but not this subdirectory
(because I already have it)".
We can prohibit certain use cases at client side just like shallow clone.
> The current protocol relies on certain repository properties on the
> remote end that narrow clone will violate. I don't see a way around that
> without a protocol extension to communicate the narrowness. What will
> that extension look like?
Something like this
http://thread.gmane.org/gmane.comp.version-control.git/155427/focus=155613
--
Duy
^ permalink raw reply
* Re: [PATCH] revert.c: defer writing CHERRY_PICK_HEAD till it is safe to do so
From: Junio C Hamano @ 2011-10-06 21:49 UTC (permalink / raw)
To: Jay Soffian; +Cc: git, nicolas.dichtel, Jeff King
In-Reply-To: <CAG+J_Dx0W0oRL-MkoZSGuOfmUNCqmMRUigmgND_0o7kbKppu1Q@mail.gmail.com>
Jay Soffian <jaysoffian@gmail.com> writes:
> For that matter, I don't see how to distinguish "the merge did not
> even start" from "the merge had conflicts" when using
> try_merge_command().
I suspect you figured it out by now (sorry I have been tending other
topics and general project maintenance issues), but in case you haven't,
the exit values from the strategy backends are returned straight back to
the caller. The strategy backends are supposed to exit with 1 when they
left the conflicts, and 2 when they punted and did not touch the index nor
the working tree.
^ permalink raw reply
* Re: [PATCH v2] revert.c: defer writing CHERRY_PICK_HEAD till it is safe to do so
From: Junio C Hamano @ 2011-10-06 21:55 UTC (permalink / raw)
To: Jay Soffian; +Cc: git, nicolas.dichtel, Jeff King
In-Reply-To: <CAG+J_Dw8w9UGBzq4xK+i+QtA4ZuwJ5w1+mPg15mPNcGLuRaXyg@mail.gmail.com>
Jay Soffian <jaysoffian@gmail.com> writes:
> On Thu, Oct 6, 2011 at 1:48 PM, Jay Soffian <jaysoffian@gmail.com> wrote:
>> Note that do_recursive_merge() aborts if the merge cannot start, while
>> try_merge_command() returns a non-zero value other than 1.
>
> Maybe you want this on-top:
Good thinking.
commit 4ed15ff067b548011b1eda8b12d46d887c4f056c
Author: Jay Soffian <jaysoffian@gmail.com>
Date: Thu Oct 6 13:58:01 2011 -0400
cherry-pick: do not give irrelevant advice when cherry-pick punted
If a cherry-pick did not even start because the working tree had local
changes that would overlap with the operation, we shouldn't be advising
the users to resolve conflicts nor to conclude it with "git commit".
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Thanks. Care to sign-off?
^ permalink raw reply
* Re: Prompt for merge message?
From: Junio C Hamano @ 2011-10-06 22:02 UTC (permalink / raw)
To: Todd A. Jacobs; +Cc: git
In-Reply-To: <6eb7acc7-f4be-4b90-a2fa-a0c91ed9a5a8@t11g2000yqk.googlegroups.com>
"Todd A. Jacobs" <nospam+listmail@codegnome.org> writes:
> I often find myself using "--no-ff -m foo" for merging short-lived
> branches, because the merge commit usually needs to say something
> about having finished a feature rather than referring to a branch that
> will be deleted shortly anyway....
> ... Is there currently a way to get git to prompt for the merge message,
> rather than using the default or requiring the -m flag? If not, isn't
> this a common-enough use case to have that ability added to the merge
> function?
Others commented on the current practices and gave their own useful tips
already, but an additional hint is to name your branch more sensibly, so
that you do not feel it is useless to record it in the history.
As to a real longer-term solution, I wouldn't mind a patch that teaches
"git merge" an "-e" option just like "git commit" has.
$ git commit -m "Finish frotz feature" -e -a
... editor opens with the first line filled already here ...
is something I find myself using fairly often.
Thanks.
[offtopic: It is annoying that my MUA warns me
"nospam+listmail@domain" may be bogus; do you really want to send?
Could you do something about it please?]
^ permalink raw reply
* Re: [PATCH v2] revert.c: defer writing CHERRY_PICK_HEAD till it is safe to do so
From: Jay Soffian @ 2011-10-06 22:02 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, nicolas.dichtel, Jeff King
In-Reply-To: <7vzkhdyecy.fsf@alter.siamese.dyndns.org>
On Thu, Oct 6, 2011 at 5:55 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Jay Soffian <jaysoffian@gmail.com> writes:
>
>> On Thu, Oct 6, 2011 at 1:48 PM, Jay Soffian <jaysoffian@gmail.com> wrote:
>>> Note that do_recursive_merge() aborts if the merge cannot start, while
>>> try_merge_command() returns a non-zero value other than 1.
>>
>> Maybe you want this on-top:
>
> Good thinking.
>
> commit 4ed15ff067b548011b1eda8b12d46d887c4f056c
> Author: Jay Soffian <jaysoffian@gmail.com>
> Date: Thu Oct 6 13:58:01 2011 -0400
>
> cherry-pick: do not give irrelevant advice when cherry-pick punted
>
> If a cherry-pick did not even start because the working tree had local
> changes that would overlap with the operation, we shouldn't be advising
> the users to resolve conflicts nor to conclude it with "git commit".
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
>
> Thanks. Care to sign-off?
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Thank you for making it a proper commit. :-)
j.
^ permalink raw reply
* Re: Prompt for merge message?
From: Shawn Pearce @ 2011-10-06 22:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Todd A. Jacobs, git
In-Reply-To: <7vsjn5ye0x.fsf@alter.siamese.dyndns.org>
On Thu, Oct 6, 2011 at 15:02, Junio C Hamano <gitster@pobox.com> wrote:
> "Todd A. Jacobs" <nospam+listmail@codegnome.org> writes:
>
>> I often find myself using "--no-ff -m foo" for merging short-lived
>> branches, because the merge commit usually needs to say something
>> about having finished a feature rather than referring to a branch that
>> will be deleted shortly anyway....
>> ... Is there currently a way to get git to prompt for the merge message,
>> rather than using the default or requiring the -m flag? If not, isn't
>> this a common-enough use case to have that ability added to the merge
>> function?
>
> Others commented on the current practices and gave their own useful tips
> already, but an additional hint is to name your branch more sensibly, so
> that you do not feel it is useless to record it in the history.
>
> As to a real longer-term solution, I wouldn't mind a patch that teaches
> "git merge" an "-e" option just like "git commit" has.
>
> $ git commit -m "Finish frotz feature" -e -a
> ... editor opens with the first line filled already here ...
>
> is something I find myself using fairly often.
What about adding something like:
if (isatty(0) && isatty(1) && isatty(2)) {
do_interactive_commit();
}
to git merge? I know the reason we don't want to do it all of the time
is because git merge is already used in a lot of scripts. But how many
of those are running with an active terminal on all 3 standard fds
when it runs git merge?
^ permalink raw reply
* Re: 66 patches and counting
From: Martin Fick @ 2011-10-06 22:16 UTC (permalink / raw)
To: Michael Haggerty; +Cc: git
In-Reply-To: <4E8CCC55.9070408@alum.mit.edu>
On Wednesday, October 05, 2011 03:29:57 pm Michael Haggerty
wrote:
> My renovation of refs.c [1] is currently at 66 patches
> and counting. What can I say?: (1) I like to make
> changes in the smallest irreducible steps and (2) there
> is a lot that needed to be done in refs.c.
>
> When I'm done, is it OK to dump a patch series like that
> on the git mailing list? Is it pointless because nobody
> will review them anyway? Is a big pile of changes like
> this welcome in any form? Would it be better to convey
> the changes via git itself (e.g., github) rather than
> via emails?
>
> Michael
>
> [1] hierarchical-refs at git://github.com/mhagger/git.git
Michael,
I downloaded your patch series and tested it on my repos.
Here are some of the timings I saw with your branch as is:
* git clone 2:50m (same)
* full fetch changes (> 1 hour) (bad!)
* git branch (unpacked, ungced) .7s (good!)
* git branch (packed, gced) .18s (~>same)
* git checkout (unpacked, ungced) 10.5s (~>same)
* git checkout (packed, gced) 9.5 (~>same)
* noop fetch changes (unpacked, ungced) 14s (~>same)
* noop fetch changes (packed, gced) 12s (same)
For the full fetch, I estimated, things were scrolling by
slow enough that after about 15 min I interrupted it. I
suspect it might be at least 6 times longer (if rate stayed
the same).
Here are the best timings for all the good patches that
others have submitted to fix many of the previous problems I
brought up:
* git clone 2:50m
* full fetch changes 4:50m
* git branch (unpacked, ungced) 9s
* git branch (packed, gced) .05s
* git checkout (unpacked, ungced) 9s
* git checkout (packed, gced) 8s
* noop fetch changes (unpacked, ungced) 12s
* noop fetch changes (packed, gced) 12s
(my internal patches bring full fetch down to 2:50m)
It would be nice if you could rebase your work on top of
some of the other patches also so that I could see those
results. I might give that a try if I have the time and it
is easy (or I might rebase those patches on yours).
Thanks,
-Martin
--
Employee of Qualcomm Innovation Center, Inc. which is a
member of Code Aurora Forum
^ permalink raw reply
* Re: [PATCH] commit: teach --gpg-sign option
From: Robin H. Johnson @ 2011-10-06 22:24 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <7vaa9f3pk8.fsf@alter.siamese.dyndns.org>
On Wed, Oct 05, 2011 at 05:56:55PM -0700, Junio C Hamano wrote:
> And this uses the gpg-interface.[ch] to allow signing the commit, i.e.
>
> $ git commit --gpg-sign -m foo
> You need a passphrase to unlock the secret key for
> user: "Junio C Hamano <gitster@pobox.com>"
> 4096-bit RSA key, ID 96AFE6CB, created 2011-10-03 (main key ID 713660A7)
>
> [master 8457d13] foo
> 1 files changed, 1 insertions(+), 0 deletions(-)
I like it, but I have a couple of questions:
1. Are the sig lines used in computed SHA1/commitid of a given commit (I
see examples w/ --amend and that would usually change the SHA1)?
2. Can we allow more than one person sign a commit?
3. If I have prepared a series on a local branch, and I want to sign all
of them, is this a variant of rebase or?
I think this isn't a replacement for push certificates, but has value in
itself. It's certainly provides better integration than the
signature-in-note variants.
--
Robin Hugh Johnson
Gentoo Linux: Developer, Trustee & Infrastructure Lead
E-Mail : robbat2@gentoo.org
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox