All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] git checkout -b: unparent the new branch with -o
@ 2010-03-16 18:19 Erick Mattos
  2010-03-16 22:56 ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: Erick Mattos @ 2010-03-16 18:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Erick Mattos

Sometimes it is interesting to start a new unparented branch in an
existing repository.

The new -o/--orphan is intended to solve this situation allowing the
creation of a new branch unparented to any other.

After the 'checkout -o -b' the new branch is not saved until committed.
Before committing you should 'git rm -rf' anything which is not going to
take part in the new branch and change the work tree and index the way
you want it to be since they remain untouched as before checkout
command.

There are two potential work flows where this feature is most useful:

(1) "mostly common paths" work flow;
(2) "no common paths" work flow;

Signed-off-by: Erick Mattos <erick.mattos@gmail.com>
---

Major rewrite to conform to Junio's demands.

Now after checkout to the new unparented branch, the index and the work tree
remain unchanged.

 Documentation/git-checkout.txt |   13 ++++++++++
 builtin/checkout.c             |   10 ++++++-
 t/t2017-checkout-orphan.sh     |   49 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 2 deletions(-)
 create mode 100755 t/t2017-checkout-orphan.sh

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 37c1810..92562ce 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -9,6 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git checkout' [-q] [-f] [-m] [<branch>]
+'git checkout' [-q] [-f] [-m] [-b <new_branch> [-o]]
 'git checkout' [-q] [-f] [-m] [-b <new_branch>] [<start_point>]
 'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
 'git checkout' --patch [<tree-ish>] [--] [<paths>...]
@@ -26,6 +27,13 @@ use the --track or --no-track options, which will be passed to `git
 branch`.  As a convenience, --track without `-b` implies branch
 creation; see the description of --track below.
 
+When using -b, it is possible to use the option -o to set the new branch
+as unparented thus unrelated to the previous branch.  The new branch is
+not saved until committed.  But before committing you should first do
+'git rm -rf' anything which is not going to take part in the new branch
+and change the work tree and index the way you want it to be since they
+remain untouched as before checkout command.
+
 When <paths> or --patch are given, this command does *not* switch
 branches.  It updates the named paths in the working tree from
 the index file, or from a named <tree-ish> (most often a commit).  In
@@ -86,6 +94,11 @@ explicitly give a name with '-b' in such a case.
 	Do not set up "upstream" configuration, even if the
 	branch.autosetupmerge configuration variable is true.
 
+-o::
+--orphan::
+	When creating a new branch, set it up as unparented thus
+	unrelated to the previous branch.
+
 -l::
 	Create the new branch's reflog; see linkgit:git-branch[1] for
 	details.
diff --git a/builtin/checkout.c b/builtin/checkout.c
index acefaaf..405de7e 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -34,6 +34,7 @@ struct checkout_opts {
 
 	const char *new_branch;
 	int new_branch_log;
+	int new_branch_orphan;
 	enum branch_track track;
 };
 
@@ -491,8 +492,9 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 	struct strbuf msg = STRBUF_INIT;
 	const char *old_desc;
 	if (opts->new_branch) {
-		create_branch(old->name, opts->new_branch, new->name, 0,
-			      opts->new_branch_log, opts->track);
+		if (!opts->new_branch_orphan)
+			create_branch(old->name, opts->new_branch, new->name, 0,
+				      opts->new_branch_log, opts->track);
 		new->name = opts->new_branch;
 		setup_branch_path(new);
 	}
@@ -629,6 +631,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT__QUIET(&opts.quiet),
 		OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
+		OPT_BOOLEAN('o', "orphan", &opts.new_branch_orphan, "make the new branch unparented"),
 		OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "log for new branch"),
 		OPT_SET_INT('t', "track",  &opts.track, "track",
 			BRANCH_TRACK_EXPLICIT),
@@ -677,6 +680,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		opts.new_branch = argv0 + 1;
 	}
 
+	if (opts.new_branch_orphan && !opts.new_branch)
+		die("-o is used only with -b");
+
 	if (conflict_style) {
 		opts.merge = 1; /* implied */
 		git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh
new file mode 100755
index 0000000..c1b77ac
--- /dev/null
+++ b/t/t2017-checkout-orphan.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Erick Mattos
+#
+
+test_description='git checkout -b
+
+Tests for -o functionality.'
+
+. ./test-lib.sh
+
+TEST_FILE=foo
+
+test_expect_success 'Setup' '
+	echo "initial" >"$TEST_FILE" &&
+	git add "$TEST_FILE" &&
+	git commit -m "First Commit"
+'
+
+test_expect_success '-b without -o checkout into a new clone branch' '
+	test_tick &&
+	echo "Test 1" >>"$TEST_FILE" &&
+	git add "$TEST_FILE" &&
+	git commit -m "Second Commit" &&
+	git log --pretty=oneline >base &&
+	git checkout -b alpha &&
+	test "alpha" = "$(git symbolic-ref HEAD | sed "s,.*/,,")" &&
+	git log --pretty=oneline >actual &&
+	test_cmp base actual
+'
+
+test_expect_success '-b with -o checkout into an orphan branch' '
+	git checkout -ob beta &&
+	test_must_fail PAGER= git log >/dev/null 2>/dev/null &&
+	test "beta" = "$(git symbolic-ref HEAD | sed "s,.*/,,")" &&
+	test_tick &&
+	echo "Test 2" >>"$TEST_FILE" &&
+	git add "$TEST_FILE" &&
+	git commit -m "Third Commit" &&
+	git log --pretty=oneline >actual &&
+	test 1 -eq $(wc -l actual | sed "s/ .*//") &&
+	! test_cmp base actual
+'
+
+test_expect_success '-o must be rejected without -b' '
+	test_must_fail git checkout -o alpha
+'
+
+test_done
-- 
1.7.0.2.274.gc8f05

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] git checkout -b: unparent the new branch with -o
  2010-03-16 18:19 [PATCH v3] git checkout -b: unparent the new branch with -o Erick Mattos
@ 2010-03-16 22:56 ` Junio C Hamano
  2010-03-17  1:10   ` Erick Mattos
  0 siblings, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2010-03-16 22:56 UTC (permalink / raw)
  To: Erick Mattos; +Cc: git

Erick Mattos <erick.mattos@gmail.com> writes:

> Sometimes it is interesting to start a new unparented branch in an
> existing repository.
>
> The new -o/--orphan is intended to solve this situation allowing the
> creation of a new branch unparented to any other.
>
> After the 'checkout -o -b' the new branch is not saved until committed.
> Before committing you should 'git rm -rf' anything which is not going to
> take part in the new branch and change the work tree and index the way
> you want it to be since they remain untouched as before checkout
> command.

This paragraph makes the patch incoherent.  It talks as if "no common
paths" is the majority case, and everybody inconveniently has to perform
an extra step that shouldn't be needed if the implementation were done
right.  If "no common paths" is indeed the assumed primary target, why
doesn't the implementation empty both index and files in the working tree
so that users don't have to do so themselves?

My _only_ complaint was that your version that _only_ emptied the index
without touching the working tree made things difficult for everybody,
both "no common paths" people and "mostly common paths" people.

You need to at least qualify the above paragraph with something like "if
you want to create an unrelated branch whose contents do not resemble the
original branch at all, then you should ...".

Better yet, try to advertise what you are giving your users in a positive
way, instead of in a way that only scares users, perhaps like this:

    After 'checkout --orphan', your HEAD will point at an unborn branch,
    and the next commit will start a new history without any prior commit.
    To help create such a new history that has contents mostly the same as
    that of the original branch, the command does not touch the index nor
    the working tree, and "checkout --orphan" immediately followed by
    "commit -a" would record a tree very similar to what you had in the
    original branch.  This is useful when you want to ... [insert a
    summary of "going open source" example from my previous message if you
    want here].

    If on the other hand you want to start a new branch whose contents do
    not resemble the original branch at all, you may want to start from an
    empty index and the working tree, with "git rm -rf ." immediately
    after running this command.

The same comment applies to the documentation part.

By the way, I wouldn't mind if you believe "no common paths" is the
majority case; if that is the case, then the code and behaviour would be
different, and the presentation would say something like this:

    After 'checkout --orphan', your HEAD will point at an unborn branch,
    and the next commit will start a new history without any prior commit.
    To help create such a new history that has contents totally different
    from the original branch, the command empties the index and removes
    all tracked files from the working tree.  The command refuses to work
    if you have uncommitted changes, so that you won't lose them.
    Conclude the work in progress on your current branch first by first
    recording the changes in commits (or "git stash save") before
    re-running the command.

    After "checkout --orphan" you can immediately start preparing the
    files to be tracked in this new branch, without files unrelated to
    this branch getting in the way.  This is useful when you want to
    ... [I don't think any "no commmon paths" workflow makes sense to be
    done in the same repository, but you seem to do do so, so give readers
    such an example here].

    If on the other hand you want to start a new branch whose contents
    mostly match the original branch, you may need to start from an
    index and the working tree files from the original branch, by running
    "git checkout <original-branch-name> ."  after running this command.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] git checkout -b: unparent the new branch with -o
  2010-03-16 22:56 ` Junio C Hamano
@ 2010-03-17  1:10   ` Erick Mattos
  2010-03-17  4:13     ` Jonathan Nieder
  2010-03-17  5:21     ` Junio C Hamano
  0 siblings, 2 replies; 9+ messages in thread
From: Erick Mattos @ 2010-03-17  1:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Hi,

Junio, you are the leader.  And I really don't want to bother you with
my opinions.

I am just trying to make you satisfied so gitsters, I mean git users,
will have this feature as soon as possible.

2010/3/16 Junio C Hamano <gitster@pobox.com>:
>> After the 'checkout -o -b' the new branch is not saved until committed.
>> Before committing you should 'git rm -rf' anything which is not going to
>> take part in the new branch and change the work tree and index the way
>> you want it to be since they remain untouched as before checkout
>> command.
>
> This paragraph makes the patch incoherent.  It talks as if "no common
> paths" is the majority case, and everybody inconveniently has to perform
> an extra step that shouldn't be needed if the implementation were done
> right.  If "no common paths" is indeed the assumed primary target, why
> doesn't the implementation empty both index and files in the working tree
> so that users don't have to do so themselves?

I was NOT trying to scare with my message.  That paragraph was meant
to let people who would need to do something ("no common paths") know
what they will need to do.  I think it is good enough because "mostly
common paths" people will be happy too by knowing that everything is
unchanged as they want it to be.  So I haven't thought about scaring
at all.  I thought it was good indeed!  :-)

> My _only_ complaint was that your version that _only_ emptied the index
> without touching the working tree made things difficult for everybody,
> both "no common paths" people and "mostly common paths" people.

Just to clarify my point-of-view about the design:

I do prefer my first design mainly because it mimics the state of an
initial commit.  I think that is subjectively better.

You have been asking me to make one of the two possible work flow uses
you pictured as favored so things will be already set to them.  No
further commands to them.

I did it!  As a matter of fact the "mostly common paths" people were
favored as you have noticed your inclination to it before.

As I told you, I just want to make you happy so people that needs the
feature I am working on could have it as fast as possible.

And if one of the possible work flows have to be favored then I do
agree with you about "mostly common paths" as the best choice.

But the point is that the other group will need to do further commands
anyway so I would keep my previous design because of the resemblance
to an initial commit: work tree full and nothing added to the index.

But I mean it!  I really want to satisfy you.  So this was the last
time I talk about my preference.

Therefore let's find out what you want me to do so we can finish this
production cycle.  I don't want to bother you anymore.

> You need to at least qualify the above paragraph with something like "if
> you want to create an unrelated branch whose contents do not resemble the
> original branch at all, then you should ...".
>
> Better yet, try to advertise what you are giving your users in a positive
> way, instead of in a way that only scares users, perhaps like this:
>
>    After 'checkout --orphan', your HEAD will point at an unborn branch,
>    and the next commit will start a new history without any prior commit.
>    To help create such a new history that has contents mostly the same as
>    that of the original branch, the command does not touch the index nor
>    the working tree, and "checkout --orphan" immediately followed by
>    "commit -a" would record a tree very similar to what you had in the
>    original branch.  This is useful when you want to ... [insert a
>    summary of "going open source" example from my previous message if you
>    want here].
>
>    If on the other hand you want to start a new branch whose contents do
>    not resemble the original branch at all, you may want to start from an
>    empty index and the working tree, with "git rm -rf ." immediately
>    after running this command.
>
> The same comment applies to the documentation part.

I was trying to be concise on my message.  I realize you want it more explained.

What about that:

After the 'checkout -o -b' you are in an new unborn branch ready to be
committed.  The next commit will start a new history without any
ancestry.  If this new branch was made to start from scratch, not
resembling the previous one, then you should use 'git rm -rf' to get
an empty work tree and index.  Otherwise with a 'git commit -a' you
will have a tree exactly as in the previous branch.  So just set
things as you want it to be and commit the new unparented branch.

> By the way, I wouldn't mind if you believe "no common paths" is the
> majority case; if that is the case, then the code and behaviour would be
> different, and the presentation would say something like this:

I agree with you in choosing "mostly common paths" as the target since
you have decided to target one.

Before I send another patch version could you please tell me your
position about my new explaining text up there.  I will wait for your
reply before sending a new patch version.

Best regards

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] git checkout -b: unparent the new branch with -o
  2010-03-17  1:10   ` Erick Mattos
@ 2010-03-17  4:13     ` Jonathan Nieder
  2010-03-17  5:23       ` Junio C Hamano
  2010-03-17 18:55       ` Erick Mattos
  2010-03-17  5:21     ` Junio C Hamano
  1 sibling, 2 replies; 9+ messages in thread
From: Jonathan Nieder @ 2010-03-17  4:13 UTC (permalink / raw)
  To: Erick Mattos; +Cc: Junio C Hamano, git

Hi,

Erick Mattos wrote:

> I am just trying to make you satisfied so gitsters, I mean git users,
> will have this feature as soon as possible.

Well, hopefully everyone wants it to make sense, too. :)

> I do prefer my first design mainly because it mimics the state of an
> initial commit.  I think that is subjectively better.
> 
> You have been asking me to make one of the two possible work flow uses
> you pictured as favored so things will be already set to them.  No
> further commands to them.
> 
> I did it!  As a matter of fact the "mostly common paths" people were
> favored as you have noticed your inclination to it before.

I guess I am confused because I am not sure what you are trying to do:

 A. on one hand, you might want a command to use as a building block.
    In practice, people would use scripts or refer to known recipes to
    make use of this building block in one of a few known combinations
    with other commands.

 B. on the other hand, you might be trying to make it easier to get
    some particular task done.

Junio was discussing the case B.  Whoever has the itch is in a good
position to say what interface would be convenient.  Usually one command
invocation can be enough to accomplish most of what is needed on its
own.  There were two examples of such commands he gave:

 1.                                                    * [public]
                                                        \
     * --- * --- * [private]   ===>    * --- * --- * --- * [private]

   for the “we cannot publish the whole history” use,

and

 2.                                                 * [doc]

    * --- * --- * [master]  ===>  * --- * --- * --- * [master]

   for the “starting unrelated development but restrictive disk quotas
   mean I have to use the same working directory” use.

In these examples (which are just examples for illustration of what a
well supported use case looks like), the content in the index and work
tree after the command is run is tailored to what is expected to be
needed.

I suspect you are aiming for case A instead.  For scripts and special
case recipes, it might be a good idea to have a command to use as an
ingredient in tasks like (1) and (2) above.  The recipe people
currently use is usually something like the following:

  git symbolic-ref HEAD refs/heads/newbranch
  rm .git/index

but that indeed is not perfect: it does not check for a dirty index
in case 1, it does not keep track of what files were not registered
in the index so as not to delete them in case 2, and so on.

Also one might object to the knowledge of repository layout required;
gitrepository-layout(5) is probably not the first place a person would
look in trying to figure out how to carry out this task.  That misses
the point, though, in my opinion, since

 git symbolic-ref HEAD refs/heads/newbranch
 git rm --cached '*'

accomplishes the same thing.  Anyway, if your goal is to create
plumbing, I would suggest modifying a plumbing command instead of
‘git checkout’.  

Thank you for your efforts.  As hinted above, I would not mind seeing
improvement in this area at all.  Anyway, I hope this has provided some
food for thought (if not, don’t mind me; please carry on).

Kind regards,
Jonathan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] git checkout -b: unparent the new branch with -o
  2010-03-17  1:10   ` Erick Mattos
  2010-03-17  4:13     ` Jonathan Nieder
@ 2010-03-17  5:21     ` Junio C Hamano
  1 sibling, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2010-03-17  5:21 UTC (permalink / raw)
  To: Erick Mattos; +Cc: git

Erick Mattos <erick.mattos@gmail.com> writes:

> I am just trying to make you satisfied so gitsters, I mean git users,
> will have this feature as soon as possible.

Don't try to satisfy _me_ personally.  It is not likely that I am going to
use "checkout --orphan" myself.  But I would not reject a new feature that
does make sense to some people, even if it is not something I would use.
I am here to help people like you help others (and to prevent people from
harming others).

I however am going to have to answer when people complain "why was this
senseless new feature added to the system?  what it does makes no sense
and does not help me."

"Nuke index but not working tree" is not something I think I can defend
and explain as sensible to these people, as I do not think it makes sense
myself.  So when Ispot a design that logically does not make sense to me,
I would say so and ask clarifications.  A major part of the maintainer's
job is to ask questions and say "no".

> I do prefer my first design mainly because it mimics the state of an
> initial commit.  I think that is subjectively better.

You keep saying that, but I think it is misguided.  And I do not think
there is anything subjective there.

If you are starting from scratch, you would:

    $ git init newrepo
    $ cd newrepo

and that is how the state before the initial commit begins with.  You
might then do this to prepare for the commit:

    $ tar xf ~/junk/frotz-2.43.tar.gz
    $ git add .

Or perhaps you would work the other way around:

    $ tar xf ~/junk/frotz-2.43.tar.gz
    $ cd frotz-2.43
    $ git init
    $ git add .

Whichever way you work, notice that you wouldn't have any rubbish in the
working tree unrelated to the "frotz" project, when the tool (in this
case, "git init") prepares the repository with a dangling HEAD and the
working tree "before the initial commit".  You either have emptiness (to
which you can untar into), or you already have files that you would want
to have in the branch and no other cruft.

If you did "nuke index, leaving files in the work tree around", the result
does not resemble "state before the initial commit" at all.  The leftover
files will get in the way.

The leftover worktree files will not get in the way ONLY if the user wants
to record a tree that is similar to the original branch, but even in that
case they have to do "git add ."; keeping the index intact would help them
even better.

After realizing all that, do you still think "nuke only the index" is
subjectively better?

> I did it!

Sure, I am saying that then you should advertise the result as such,
without being negative.

>> Better yet, try to advertise what you are giving your users in a positive
>> way, instead of in a way that only scares users, perhaps like this:
>>
>>    After 'checkout --orphan', your HEAD will point at an unborn branch,
>>    and the next commit will start a new history without any prior commit.
>>    To help create such a new history that has contents mostly the same as
>>    that of the original branch, the command does not touch the index nor
>>    the working tree, and "checkout --orphan" immediately followed by
>>    "commit -a" would record a tree very similar to what you had in the
>>    original branch.  This is useful when you want to ... [insert a
>>    summary of "going open source" example from my previous message if you
>>    want here].
>>
>>    If on the other hand you want to start a new branch whose contents do
>>    not resemble the original branch at all, you may want to start from an
>>    empty index and the working tree, with "git rm -rf ." immediately
>>    after running this command.
>>
>> The same comment applies to the documentation part.
>
> I was trying to be concise on my message.  I realize you want it more explained.

Concise is good.  Negative is not.

> After the 'checkout -o -b' you are in an new unborn branch ready to be
> committed.  The next commit will start a new history without any
> ancestry.  If this new branch was made to start from scratch, not
> resembling the previous one, then you should use 'git rm -rf' to get
> an empty work tree and index.  Otherwise with a 'git commit -a' you
> will have a tree exactly as in the previous branch.  So just set
> things as you want it to be and commit the new unparented branch.

I wouldn't start the description with

    if you want 'no common paths', then it would be more cumbersome than
    just this single command

if the primary workflow your chose to support with your implementation is
'mostly common paths'.

Look at the example I gave you more carefully.  The primary use case we
intend to support is described first.  Also it is written in much more
inviting tone, in order to help readers understand the motivation behind
the feature.  IOW, "Ah, that is something I may want to do in some cases,
and the new feature indeed sounds useful." is what we want to hear from
the readers (the log message for reviewers, and the documentation for the
end users) after they read the explanation.  The second paragraph then
mentions the less common use case for completeness.  To the readers who
understand why the behaviour of the command makes sense for its primary
use case (which is described first), it would be easier to accept that
they have to run an extra command (by the way, it is "'git rm -rf .' from
the top-level of the working tree; do not forget the dot at the end) to
clean up the working tree to a prestine state, because they would
understand the reason why the clearing is not done by default.

The same comment applies to the documentation part of the patch.  Don't be
negative.  Positively explain why what you added is useful, and help the
users understand why they might want to use it and in what situation.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] git checkout -b: unparent the new branch with -o
  2010-03-17  4:13     ` Jonathan Nieder
@ 2010-03-17  5:23       ` Junio C Hamano
  2010-03-17  6:40         ` Jonathan Nieder
  2010-03-17 18:55       ` Erick Mattos
  1 sibling, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2010-03-17  5:23 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Erick Mattos, Junio C Hamano, git

Jonathan Nieder <jrnieder@gmail.com> writes:

> Junio was discussing the case B.

Well, not really.  Even as an ingredient, "nuke index, leaving files in
the work tree around" is the most difficult-to-use mode of operation.
Either "try to run 'git rm -f .' from the toplevel and only if it succeeds
point HEAD to an unborn branch" (aka "remove both"), or "point HEAD to an
unborn branch without doing anything else" (aka "keep both") would be an
ingredient that is far easier to use.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] git checkout -b: unparent the new branch with -o
  2010-03-17  5:23       ` Junio C Hamano
@ 2010-03-17  6:40         ` Jonathan Nieder
  2010-03-17 17:17           ` Junio C Hamano
  0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Nieder @ 2010-03-17  6:40 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Erick Mattos, git

Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
> 
> > Junio was discussing the case B.
> 
> Well, not really.  Even as an ingredient, "nuke index, leaving files in
> the work tree around" is the most difficult-to-use mode of operation.
> Either "try to run 'git rm -f .' from the toplevel and only if it succeeds
> point HEAD to an unborn branch" (aka "remove both"), or "point HEAD to an
> unborn branch without doing anything else" (aka "keep both") would be an
> ingredient that is far easier to use.

Okay, fair enough.  From the point of view of plumbing, what is there
left to do that

	git rm -f . &&
	git symbolic-ref HEAD refs/heads/new

or

	git symbolic-ref HEAD refs/heads/new

or

	git rm --cached . &&
	git symbolic-ref HEAD refs/heads/new

does not take care of?

I guess I should have said that I would be happier to see something
tailored to a use case or a class of use cases.

I haven’t needed it for a while, but once upon a time I was making
isolated branches like crazy for some abuse of git as a compression
tool.

Jonathan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] git checkout -b: unparent the new branch with -o
  2010-03-17  6:40         ` Jonathan Nieder
@ 2010-03-17 17:17           ` Junio C Hamano
  0 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2010-03-17 17:17 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Erick Mattos, git

Jonathan Nieder <jrnieder@gmail.com> writes:

> Okay, fair enough.  From the point of view of plumbing, what is there
> left to do that
>
> 	git rm -f . &&
> 	git symbolic-ref HEAD refs/heads/new
>
> or
>
> 	git symbolic-ref HEAD refs/heads/new
>
> or
>
> 	git rm --cached . &&
> 	git symbolic-ref HEAD refs/heads/new
>
> does not take care of?

If we have the "just detach, don't touch index nor working tree", which
happens to be the cheapest one in the middle (except that it probably
wants to verify that "new" does not exist yet), the calling script of the
Porcelain suite can use it in conjunction with various forms of "git rm"
without incurring any additional overhead (other than a fork-and-exec),
and I think that would be sufficient.

You could add

	git ls-files |
        while read path
        do
        	case $(choose-keep-drop-nuke "$path") in
                keep) ;;
                drop) git rm --cached -f "$path" ;;
                nuke) git rm -f "$path" ;;
        	esac
	done
	git symbolic-ref HEAD refs/heads/new

and have the caller supply a callback that intelligently choose what to
keep and what to drop, if you want to be really fancy, but at that level
of complexity, I think it is something the Porcelain writer using the
plumbing would want to write himself as part of the Porcelain program.

We might want to add "git branch --switch <branchname>" that is roughly
like this:

    ref="refs/heads/$branch"
    git check-ref-format "$ref" || die "malformed"
    if git rev-parse -q --verify "$ref" >/dev/null
    then
    	# exists
        exec git checkout "$branch"
    else
	# create
	exec git symbolic-ref HEAD "$ref"
    fi

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] git checkout -b: unparent the new branch with -o
  2010-03-17  4:13     ` Jonathan Nieder
  2010-03-17  5:23       ` Junio C Hamano
@ 2010-03-17 18:55       ` Erick Mattos
  1 sibling, 0 replies; 9+ messages in thread
From: Erick Mattos @ 2010-03-17 18:55 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Junio C Hamano, git

2010/3/17 Jonathan Nieder <jrnieder@gmail.com>:
> ...
>
> Thank you for your efforts.  As hinted above, I would not mind seeing
> improvement in this area at all.  Anyway, I hope this has provided some
> food for thought (if not, don’t mind me; please carry on).
>
> Kind regards,
> Jonathan

Thanks for your kindness.

We are almost at the end of this new option creation cycle.  We are
now building the appropriated explaining messages.

This improvement is indeed targeted to let end users create orphan
branches.  I don't see a reason for changing focus because I see this
need as eventual really.

Kind regards

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-03-17 18:56 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-16 18:19 [PATCH v3] git checkout -b: unparent the new branch with -o Erick Mattos
2010-03-16 22:56 ` Junio C Hamano
2010-03-17  1:10   ` Erick Mattos
2010-03-17  4:13     ` Jonathan Nieder
2010-03-17  5:23       ` Junio C Hamano
2010-03-17  6:40         ` Jonathan Nieder
2010-03-17 17:17           ` Junio C Hamano
2010-03-17 18:55       ` Erick Mattos
2010-03-17  5:21     ` Junio C Hamano

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.