From: Junio C Hamano <gitster@pobox.com>
To: "Avery Pennarun" <apenwarr@gmail.com>
Cc: "Nicolas Pitre" <nico@cam.org>,
"Johan Herland" <johan@herland.net>,
git@vger.kernel.org, "Stephan Beyer" <s-beyer@gmx.net>,
"Junio C Hamano" <gitster@pobox.com>,
"Pieter de Bie" <pdebie@ai.rug.nl>
Subject: Re: [RFC] Detached-HEAD reminder on commit?
Date: Fri, 05 Sep 2008 16:43:52 -0700 [thread overview]
Message-ID: <7vabemupjb.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <7vbpz479zs.fsf@gitster.siamese.dyndns.org> (Junio C. Hamano's message of "Wed, 03 Sep 2008 22:31:19 -0700")
Junio C Hamano <gitster@pobox.com> writes:
> "Avery Pennarun" <apenwarr@gmail.com> writes:
> ...
>> 1) Checking out a remote branch "git checkout origin/master" detaches
>> my HEAD, which is kind of bad, since it's such a common thing to want
>> to do.
>
> I do not think it is bad at all. The feature to detach HEAD was designed
> for that kind of usage. Start sightseeing, possibly futz with the code,
> and even create some snapshot commits, and then:
>
> * if it starts to take a usable shape, say "git checkout -b my-topic",
> from there, to give your exploration a lasting home; or
>
> * if it doesn't pan out, just discard it with "git checkout -f master"
> (or whatever you wanted to switch back to).
>
> One thing that might help for downstream people would be to be able to say
> "I am making 'my-topic' branch out of a detached HEAD, but it really is
> meant to be a fork of origin/master that I detached my HEAD from, so
> please set up tracking for that one".
>
> You could force people to say "git checkout -b my-topic origin/master"
> from the beginning, but that is very unreasonable and unworkable. When
> you are exploring, you more often than not do not know where your quest
> would lead to until spending some time. It is quite important to be able
> to delay the decision to create a local branch to keep what you did, and
> (more importantly) to be able to delay deciding what to name that topic.
>
> Perhaps "git checkout -b my-topic" from a detached HEAD should inspect the
> HEAD reflog to see which remote (or local) branch you came from, and give
> that to the --track logic.
So here is a patch for discussion, not heavily tested, but:
$ git checkout origin/master
$ git commit; hack hack hack ...
$ git checkout --track -b mybranch
sequence should result in mybranch tracking the 'master' branch from the
'origin'.
The patch is just a proof of concept; doing this for HEAD reflog that is
several megabytes long might take nontrivial amount of time (at least from
performance standard of git); if we wanted to go this route, we should add
an API to read the reflog entries from more recent to older.
branch.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 59 insertions(+), 0 deletions(-)
diff --git c/branch.c w/branch.c
index b1e59f2..2ec6418 100644
--- c/branch.c
+++ w/branch.c
@@ -48,6 +48,62 @@ static int should_setup_rebase(const struct tracking *tracking)
}
/*
+ * A branch is created out of "HEAD" and we would want tracking;
+ * go back the reflog to figure out where we really came from.
+ */
+static int refine_head_one(const char *name, size_t namelen,
+ struct strbuf *found_ref)
+{
+ char *real_ref;
+ unsigned char sha1[20];
+ if (dwim_ref(name, namelen, sha1, &real_ref) != 1)
+ return 0;
+ strbuf_reset(found_ref);
+ strbuf_addstr(found_ref, real_ref);
+ return 0;
+}
+
+static int one_head_ent(unsigned char *osha1, unsigned char *nsha1,
+ const char *ident, unsigned long timestamp, int zone,
+ const char *message, void *cbdata)
+{
+ /*
+ * Look for signs of HEAD coming from elsewhere.
+ *
+ * "checkout: moving from %*s to %s" done by "git checkout"
+ * "%s: updating HEAD" done by "git reset"
+ */
+ struct strbuf *found_ref = cbdata;
+ char *cp;
+ size_t len;
+
+ if (!prefixcmp(message, "checkout: moving from ")) {
+ cp = strstr(message, " to ");
+ if (!cp)
+ return 0;
+ cp += 4;
+ len = strlen(cp);
+ if (cp[len-1] == '\n')
+ len--;
+ return refine_head_one(cp, len, found_ref);
+ }
+
+ cp = strstr(message, ": updating HEAD");
+ if (cp && !cp[15])
+ return refine_head_one(message, cp - message, found_ref);
+ return 0;
+}
+
+static const char *refine_head_ref(void)
+{
+ struct strbuf found = STRBUF_INIT;
+
+ strbuf_addstr(&found, "HEAD");
+ for_each_reflog_ent("HEAD", one_head_ent, &found);
+ return strbuf_detach(&found, NULL);
+}
+
+/*
* This is called when new_ref is branched off of orig_ref, and tries
* to infer the settings for branch.<new_ref>.{remote,merge} from the
* config.
@@ -58,6 +114,9 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
char key[1024];
struct tracking tracking;
+ if (!strcmp(orig_ref, "HEAD"))
+ orig_ref = refine_head_ref();
+
if (strlen(new_ref) > 1024 - 7 - 7 - 1)
return error("Tracking not set up: name too long: %s",
new_ref);
next prev parent reply other threads:[~2008-09-05 23:45 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-02 19:31 [RFC] Detached-HEAD reminder on commit? Pieter de Bie
2008-09-02 19:43 ` Robin Rosenberg
2008-09-02 20:24 ` Nicolas Pitre
2008-09-02 20:26 ` Matthieu Moy
2008-09-02 20:35 ` Nicolas Pitre
2008-09-02 20:39 ` Junio C Hamano
2008-09-02 21:05 ` Stephan Beyer
2008-09-02 21:39 ` Johan Herland
2008-09-02 21:44 ` Jeff King
2008-09-02 21:51 ` Jeff King
2008-09-03 7:45 ` Johan Herland
2008-09-03 8:07 ` Junio C Hamano
2008-09-03 9:47 ` Johan Herland
2008-09-03 13:15 ` Jeff King
2008-09-03 13:34 ` Jeff King
2008-09-03 13:46 ` Andreas Ericsson
2008-09-03 16:49 ` Daniel Barkalow
2008-09-03 18:07 ` Jeff King
2008-09-03 19:36 ` Junio C Hamano
2008-09-03 19:41 ` Jeff King
2008-09-03 14:11 ` Wincent Colaiuta
2008-09-03 18:08 ` Jeff King
2008-09-03 15:16 ` Nicolas Pitre
2008-09-02 21:58 ` Junio C Hamano
2008-09-02 22:53 ` Nicolas Pitre
2008-09-04 4:50 ` Avery Pennarun
2008-09-04 5:31 ` Junio C Hamano
2008-09-05 23:43 ` Junio C Hamano [this message]
2008-09-02 21:51 ` Pieter de Bie
2008-09-02 22:11 ` Jakub Narebski
2008-09-02 22:50 ` Junio C Hamano
2008-09-02 22:58 ` Nicolas Pitre
2008-09-03 11:27 ` Pieter de Bie
2008-09-05 17:13 ` [PATCH] Builtin-commit: show on which branch a commit was added Pieter de Bie
2008-09-07 5:27 ` Junio C Hamano
2008-09-07 5:59 ` Junio C Hamano
2008-09-07 23:05 ` [PATCH 1/2] pretty.c: add %% format specifier Pieter de Bie
2008-09-07 23:05 ` [PATCH 2/2] builtin-commit: show on which branch a commit was added Pieter de Bie
2008-09-21 10:42 ` [PATCH] Builtin-commit: " Jeff King
2008-09-29 20:09 ` Pieter de Bie
2008-09-29 22:44 ` Jeff King
2008-09-30 6:13 ` Andreas Ericsson
2008-09-30 6:16 ` Jeff King
2008-09-30 9:45 ` Andreas Ericsson
2008-09-30 9:52 ` [PATCH] git commit: Reformat output somewhat Andreas Ericsson
2008-09-30 6:37 ` [PATCH] Builtin-commit: show on which branch a commit was added Wincent Colaiuta
2008-09-30 7:09 ` Jeff King
2008-09-30 9:59 ` Andreas Ericsson
2008-10-01 3:14 ` Jeff King
2008-10-01 8:13 ` Andreas Ericsson
2008-10-01 15:10 ` Shawn O. Pearce
2008-10-01 15:22 ` Andreas Ericsson
2008-10-01 15:25 ` Jeff King
2008-10-01 15:36 ` Shawn O. Pearce
2008-10-01 15:42 ` Jeff King
2008-10-01 15:44 ` Shawn O. Pearce
2008-10-01 21:06 ` [PATCH] git commit: Repaint the output format bikeshed (again) Andreas Ericsson
2008-10-01 22:06 ` Jeff King
2008-10-01 22:31 ` Jeff King
2008-10-02 5:40 ` Andreas Ericsson
2008-10-02 21:13 ` Jeff King
2008-10-03 0:15 ` Shawn O. Pearce
2008-10-03 4:24 ` Jeff King
2008-10-03 14:09 ` Shawn O. Pearce
2008-10-04 2:13 ` Jeff King
2008-10-02 8:36 ` Wincent Colaiuta
2008-10-01 15:18 ` [PATCH] Builtin-commit: show on which branch a commit was added Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vabemupjb.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=apenwarr@gmail.com \
--cc=git@vger.kernel.org \
--cc=johan@herland.net \
--cc=nico@cam.org \
--cc=pdebie@ai.rug.nl \
--cc=s-beyer@gmx.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.