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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).