git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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);

  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).