* [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch
@ 2007-03-29 8:02 Junio C Hamano
2007-03-29 10:44 ` Xavier Maillard
2007-03-31 0:11 ` Jakub Narebski
0 siblings, 2 replies; 8+ messages in thread
From: Junio C Hamano @ 2007-03-29 8:02 UTC (permalink / raw)
To: git
You cannot currently checkout the tip of an existing branch
without moving to the branch.
This allows you to detach your HEAD and place it at such a
commit, with:
$ git checkout -d master
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Documentation/git-checkout.txt | 6 +++-
git-checkout.sh | 18 +++++++++--
t/t7201-co.sh | 63 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 81 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index f5b2d50..d00eeaa 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -8,7 +8,7 @@ git-checkout - Checkout and switch to a branch
SYNOPSIS
--------
[verse]
-'git-checkout' [-q] [-f] [-b [--track | --no-track] <new_branch> [-l]] [-m] [<branch>]
+'git-checkout' [-q] [-f] [-b [--track | --no-track] <new_branch> [-l] | -d] [-m] [<branch>]
'git-checkout' [<tree-ish>] <paths>...
DESCRIPTION
@@ -61,6 +61,10 @@ OPTIONS
all changes to made the branch ref, enabling use of date
based sha1 expressions such as "<branchname>@{yesterday}".
+-d::
+ Explicitly ask to detach HEAD, even when named revision
+ to switch to is at the tip of a branch.
+
-m::
If you have local modifications to one or more files that
are different between the current branch and the branch to
diff --git a/git-checkout.sh b/git-checkout.sh
index a7390e8..e551443 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-USAGE='[-q] [-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]'
+USAGE='[-q] [-f] [-b <new_branch> | -d] [-m] [<branch>] [<paths>...]'
SUBDIRECTORY_OK=Sometimes
. git-sh-setup
require_work_tree
@@ -17,6 +17,7 @@ newbranch=
newbranch_log=
merge=
quiet=
+explicit_detach=
LF='
'
while [ "$#" != "0" ]; do
@@ -39,6 +40,9 @@ while [ "$#" != "0" ]; do
"--track"|"--no-track")
track="$arg"
;;
+ -d)
+ explicit_detach=1
+ ;;
"-f")
force=1
;;
@@ -94,6 +98,11 @@ case "$newbranch,$track" in
die "git checkout: --track and --no-track require -b"
esac
+case "$newbranch$explicit_detach" in
+11)
+ die "git checkout: -d and -b are incompatible"
+esac
+
case "$force$merge" in
11)
die "git checkout: -f and -m are incompatible"
@@ -117,7 +126,7 @@ then
hint="
Did you intend to checkout '$@' which can not be resolved as commit?"
fi
- if test '' != "$newbranch$force$merge"
+ if test '' != "$newbranch$force$merge$explicit_detach"
then
die "git checkout: updating paths is incompatible with switching branches/forcing$hint"
fi
@@ -170,7 +179,8 @@ describe_detached_head () {
}
}
-if test -z "$branch$newbranch" && test "$new" != "$old"
+if test -z "$branch$newbranch" && test "$new" != "$old" ||
+ test -n "$explicit_detach"
then
detached="$new"
if test -n "$oldbranch" && test -z "$quiet"
@@ -254,7 +264,7 @@ if [ "$?" -eq 0 ]; then
git-branch $track $newbranch_log "$newbranch" "$new_name" || exit
branch="$newbranch"
fi
- if test -n "$branch"
+ if test -n "$branch" && test -z "$explicit_detach"
then
GIT_DIR="$GIT_DIR" git-symbolic-ref -m "checkout: moving to $branch" HEAD "refs/heads/$branch"
if test -n "$quiet"
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 867bbd2..caa04f9 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -3,7 +3,20 @@
# Copyright (c) 2006 Junio C Hamano
#
-test_description='git-checkout tests.'
+test_description='git-checkout tests.
+
+Creates master, forks renamer and side branches from it.
+Test switching across them.
+
+ ! [master] Initial A one, A two
+ * [renamer] Renamer R one->uno, M two
+ ! [side] Side M one, D two, A three
+ ---
+ + [side] Side M one, D two, A three
+ * [renamer] Renamer R one->uno, M two
+ +*+ [master] Initial A one, A two
+
+'
. ./test-lib.sh
@@ -129,4 +142,52 @@ test_expect_success 'checkout -m with merge conflict' '
! test -s current
'
+test_expect_success 'checkout to detach HEAD' '
+
+ git checkout -f renamer && git clean &&
+ git checkout renamer^ &&
+ H=$(git rev-parse --verify HEAD) &&
+ M=$(git show-ref -s --verify refs/heads/master) &&
+ test "z$H" = "z$M" &&
+ if git symbolic-ref HEAD >/dev/null 2>&1
+ then
+ echo "OOPS, HEAD is still symbolic???"
+ false
+ else
+ : happy
+ fi
+'
+
+test_expect_success 'checkout to detach HEAD with explicit -d' '
+
+ git checkout -f master && git clean &&
+ git checkout -d renamer^ &&
+ H=$(git rev-parse --verify HEAD) &&
+ M=$(git show-ref -s --verify refs/heads/master) &&
+ test "z$H" = "z$M" &&
+ if git symbolic-ref HEAD >/dev/null 2>&1
+ then
+ echo "OOPS, HEAD is still symbolic???"
+ false
+ else
+ : happy
+ fi
+'
+
+test_expect_success 'checkout to detach HEAD with explicit -d' '
+
+ git checkout -f master && git clean &&
+ git checkout -d &&
+ H=$(git rev-parse --verify HEAD) &&
+ M=$(git show-ref -s --verify refs/heads/master) &&
+ test "z$H" = "z$M" &&
+ if git symbolic-ref HEAD >/dev/null 2>&1
+ then
+ echo "OOPS, HEAD is still symbolic???"
+ false
+ else
+ : happy
+ fi
+'
+
test_done
--
1.5.1.rc3.1.ga429d
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch
2007-03-29 8:02 [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch Junio C Hamano
@ 2007-03-29 10:44 ` Xavier Maillard
2007-03-29 17:10 ` Alex Riesen
2007-03-31 0:11 ` Jakub Narebski
1 sibling, 1 reply; 8+ messages in thread
From: Xavier Maillard @ 2007-03-29 10:44 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This allows you to detach your HEAD and place it at such a
$ git checkout -d master
Hum, excuse my ignorance, but can you explain what exactly could
be a use case of this ?
Xavier
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch
2007-03-29 10:44 ` Xavier Maillard
@ 2007-03-29 17:10 ` Alex Riesen
2007-03-29 20:54 ` Xavier Maillard
0 siblings, 1 reply; 8+ messages in thread
From: Alex Riesen @ 2007-03-29 17:10 UTC (permalink / raw)
To: Xavier Maillard; +Cc: Junio C Hamano, git
Xavier Maillard, Thu, Mar 29, 2007 12:44:42 +0200:
> This allows you to detach your HEAD and place it at such a
>
> $ git checkout -d master
>
> Hum, excuse my ignorance, but can you explain what exactly could
> be a use case of this ?
A throw-away or an experimental work. A commit importer which cares
about the branch it commits on: to update the branch reference only
when it has reached a stable state.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch
2007-03-29 17:10 ` Alex Riesen
@ 2007-03-29 20:54 ` Xavier Maillard
0 siblings, 0 replies; 8+ messages in thread
From: Xavier Maillard @ 2007-03-29 20:54 UTC (permalink / raw)
To: Alex Riesen; +Cc: junkio, git
A throw-away or an experimental work. A commit importer which cares
about the branch it commits on: to update the branch reference only
when it has reached a stable state.
Hum, yes, I see. Thank you.
Xavier
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch
2007-03-29 8:02 [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch Junio C Hamano
2007-03-29 10:44 ` Xavier Maillard
@ 2007-03-31 0:11 ` Jakub Narebski
2007-03-31 14:55 ` Xavier Maillard
1 sibling, 1 reply; 8+ messages in thread
From: Jakub Narebski @ 2007-03-31 0:11 UTC (permalink / raw)
To: git
Junio C Hamano wrote:
> You cannot currently checkout the tip of an existing branch
> without moving to the branch.
>
> This allows you to detach your HEAD and place it at such a
> commit, with:
>
> $ git checkout -d master
What about
$ git checkout master^0
trick to force detaching?
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch
2007-03-31 0:11 ` Jakub Narebski
@ 2007-03-31 14:55 ` Xavier Maillard
2007-04-04 0:11 ` Junio C Hamano
0 siblings, 1 reply; 8+ messages in thread
From: Xavier Maillard @ 2007-03-31 14:55 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
> You cannot currently checkout the tip of an existing branch
> without moving to the branch.
>
> This allows you to detach your HEAD and place it at such a
> commit, with:
>
> $ git checkout -d master
What about
$ git checkout master^0
trick to force detaching?
I love this idea.
Xavier
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch
2007-03-31 14:55 ` Xavier Maillard
@ 2007-04-04 0:11 ` Junio C Hamano
2007-04-04 1:55 ` Linus Torvalds
0 siblings, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2007-04-04 0:11 UTC (permalink / raw)
To: Xavier Maillard; +Cc: Jakub Narebski, Linus Torvalds, git
Xavier Maillard <zedek@gnu.org> writes:
> > You cannot currently checkout the tip of an existing branch
> > without moving to the branch.
> >
> > This allows you to detach your HEAD and place it at such a
> > commit, with:
> >
> > $ git checkout -d master
>
> What about
>
> $ git checkout master^0
>
> trick to force detaching?
>
> I love this idea.
Could anybody remind me why we have the "new != old" check here?
diff --git a/git-checkout.sh b/git-checkout.sh
index a7390e8..573a3c0 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -170,7 +170,7 @@ describe_detached_head () {
}
}
-if test -z "$branch$newbranch" && test "$new" != "$old"
+if test -z "$branch$newbranch"
then
detached="$new"
if test -n "$oldbranch" && test -z "$quiet"
I think I do not need an explicit -d option if we just remove
that second test. It is coming from an ancient commit 91dcdfd3,
and I _think_ it was to prevent something like:
git-checkout-script v2.6.12^0
from succeeding, while allowing
git-checkout-script HEAD^0
to be a no-op (as it happens to be naming the same commit).
commit 91dcdfd3b5331d955cfb60edf8930f1b5c142905
Author: Linus Torvalds <torvalds@g5.osdl.org>
Date: Mon Jul 11 20:44:20 2005 -0700
Make "git checkout" create new branches on demand
diff --git a/git-checkout-script b/git-checkout-script
index 48e1da9..7e70338 100755
--- a/git-checkout-script
+++ b/git-checkout-script
@@ -5,10 +5,19 @@ old=$(git-rev-parse HEAD)
...
@@ -32,6 +41,16 @@ while [ "$#" != "0" ]; do
done
[ -z "$new" ] && new=$old
+#
+# If we don't have an old branch that we're switching to,
+# and we don't have a new branch name for the target we
+# are switching to, then we'd better just be checking out
+# what we already had
+#
+[ -z "$branch$newbranch" ] &&
+ [ "$new" != "$old" ] &&
+ die "git checkout: you need to specify a new branch name"
+
if [ "$force" ]
then
git-read-tree --reset $new &&
@@ -47,6 +66,10 @@ fi
...
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch
2007-04-04 0:11 ` Junio C Hamano
@ 2007-04-04 1:55 ` Linus Torvalds
0 siblings, 0 replies; 8+ messages in thread
From: Linus Torvalds @ 2007-04-04 1:55 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Xavier Maillard, Jakub Narebski, git
On Tue, 3 Apr 2007, Junio C Hamano wrote:
>
> Could anybody remind me why we have the "new != old" check here?
Afaik, it's just so that you can do
git checkout -f
without having it complain. And I think it just comes from the earlier:
[ -z "$new" ] && new=$old && new_name="$old_name"
that we did - ie without that it would incorrectly just overwrite the
current working tree with the new commit, but not actually do the "git
reset" part.
So without that check, the way things used to work (*before* detached
heads), if you were to have done
git checkout <some-random-head>
it would have screwed up the current branch horribly.
With detached heads, I don't think it's needed.
Linus
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2007-04-04 1:55 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-29 8:02 [PATCH] checkout -d: explicitly detach HEAD even when switching to the tip of a branch Junio C Hamano
2007-03-29 10:44 ` Xavier Maillard
2007-03-29 17:10 ` Alex Riesen
2007-03-29 20:54 ` Xavier Maillard
2007-03-31 0:11 ` Jakub Narebski
2007-03-31 14:55 ` Xavier Maillard
2007-04-04 0:11 ` Junio C Hamano
2007-04-04 1:55 ` Linus Torvalds
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).