Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-12-03 Thread Mark Levedahl

On 12/02/2014 12:30 PM, Junio C Hamano wrote:

Duy Nguyen pclo...@gmail.com writes:


FWIW git-branch usually can show the original branch of detached head
(must not always). I don't think we have a plumbing equivalent for it
though. People can tail -1 $GIT_DIR/logs/HEAD| sed .. but that seems
hacky.

@{-1}, i.e. the last branch I checked out?


I do like read-only ref concept where we can keep ref name
(especially tags) in HEAD until the next commit. But it didn't go
anywhere

Remind me.  That sounds somewhat interesting.


I think these ideas support solutions more complicated than the 
problem trying to be solved. Consider a use case: multiple algorithms, 
each a different branch in one repository, any of which can be used to 
analyze the same kinds of data. We also have multiple data sets, each a 
separate branch in a other repository. For development / test / analysis 
it is necessary to have multiple checked out pairs (algorithm + data) on 
the same machine to allow comparison / debugging in place of different 
combinations. Assume one algorithm, multiple data sets are checked out 
and being worked on.


With new-workdir, or Duy's approach with --ignore-other-checkouts, all 
are checked out normally in git, git-branch, git-status, git log all 
work normally. If a change needs to be made that affects the branch in 
more than one checked out repository, once done the other copies are out 
of date. It does not matter which instance is modified, once committed 
the change is already visible in all others, and git reset --hard in 
all the others completes the process. This is not difficult to 
understand, requires no new code, no special methods.


Consider the alternatives:
a) Use separate complete repositories + work trees: now the new branch 
needs to be broadcast to all using fetch or pull, and as the change 
might have been an amend, fetch + reset --hard may be required. This is 
not simpler to implement in practice, nor do I find it easier to 
explain. Note also that if using push, it is possible to force push into 
the current branch of the other copies, with receive.denyCurrentBranch = 
false, resulting in exactly the same situation as above using 
new-workdir (checked out code not matching the ref).


b) Use Duy's approach without --ignore-other-checkouts. First, you have 
to find the copy that is not on a detached HEAD, detach the HEAD their, 
then go back to the copy where the problem is found, attach the HEAD in 
that one, and make the change. Then go back and do git reset --hard 
$branch in the others.


I just don't see how these alternatives are in the end any simpler to 
use or explain.



Mark
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-12-03 Thread Duy Nguyen
On Wed, Dec 3, 2014 at 12:30 AM, Junio C Hamano gits...@pobox.com wrote:
 I do like read-only ref concept where we can keep ref name
 (especially tags) in HEAD until the next commit. But it didn't go
 anywhere

 Remind me.  That sounds somewhat interesting.

Couldn't find anything in my mail archive. But the idea is simple:

 - we delay detaching HEAD until we need to update the associated ref
at commit/reset time
 - currently refs/tags/* are read-only. we generalize it to allow this
'read-only' attribute on some refs/heads/* as well. Because we can't
really add attributes to refs, config var could be used.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-12-03 Thread Junio C Hamano
Duy Nguyen pclo...@gmail.com writes:

 On Wed, Dec 3, 2014 at 12:30 AM, Junio C Hamano gits...@pobox.com wrote:
 I do like read-only ref concept where we can keep ref name
 (especially tags) in HEAD until the next commit. But it didn't go
 anywhere

 Remind me.  That sounds somewhat interesting.

 Couldn't find anything in my mail archive. But the idea is simple:

  - we delay detaching HEAD until we need to update the associated ref
 at commit/reset time
  - currently refs/tags/* are read-only. we generalize it to allow this
 'read-only' attribute on some refs/heads/* as well. Because we can't
 really add attributes to refs, config var could be used.

It could be some annotation in HEAD instead, e.g.

$ cat .git/HEAD
ref: refs/heads/frotz
options: read-only
$ exit

and it may make more sense as this read-only-ness is closely tied to
the state of HEAD, i.e. whatever operation that manipulates the
HEAD, it needs to be very much aware of the read-only-ness, and it
is much less likely to go out of sync, compared to a solution where
you store this bit to anywhere else, e.g. config.


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-12-02 Thread Duy Nguyen
On Tue, Dec 2, 2014 at 12:39 AM, Junio C Hamano gits...@pobox.com wrote:
 Sorry, what is a hic?

Off topic. It's the sound (in Vietnamese) when you inhale through your
nose, e.g. like when you cry.. I know there's an equivalent in
English, just can't remember it now.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-12-02 Thread Duy Nguyen
On Tue, Dec 2, 2014 at 12:04 PM, Mark Levedahl mleved...@gmail.com wrote:
 On 12/01/2014 12:39 PM, Junio C Hamano wrote:

 Sorry, what is a hic? If this were an existing feature like
 git-new-workdir, even though it is from contrib, making it impossible to do
 something that used to be possible, even if that something is what mere
 mortals would never want to to to avoid risking confusion, would be a
 regression that needs an escape hatch. But this is a new feature. I am not
 sure why you need to make this overridable in the first place. Those who
 want to have multiple checkouts of the same commit can just detach HEAD at
 the same commit in multiple working trees, as the first thing they need to
 do would be to run git reset --hard $branch to synchronize the HEAD and
 the working tree state to work in the other out-of-sync repositories either
 case anyway.


 Yes, detached HEADS allow multiple checkouts, but now the user needs another
 system to record what $branch was for each checked out tree or needs to
 resort to forensics using various git-branch / git-log invocations to find
 the most-likely value. So, I do not find detached HEADS useful in general,
 and specifically not for this case. Duy's latest addition
 ('--ignore-other-worktrees') would, so far as I see, allow this feature to
 replace git-new-workdir in my uses, but without the addition it cannot.

I'm ok either way. So I'll let you and Junio (and maybe others) sort
this out. No objection means --ignore-other-worktrees is in.

FWIW git-branch usually can show the original branch of detached head
(must not always). I don't think we have a plumbing equivalent for it
though. People can tail -1 $GIT_DIR/logs/HEAD| sed .. but that seems
hacky. I do like read-only ref concept where we can keep ref name
(especially tags) in HEAD until the next commit. But it didn't go
anywhere
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-12-02 Thread Junio C Hamano
Duy Nguyen pclo...@gmail.com writes:

 FWIW git-branch usually can show the original branch of detached head
 (must not always). I don't think we have a plumbing equivalent for it
 though. People can tail -1 $GIT_DIR/logs/HEAD| sed .. but that seems
 hacky.

@{-1}, i.e. the last branch I checked out?

 I do like read-only ref concept where we can keep ref name
 (especially tags) in HEAD until the next commit. But it didn't go
 anywhere

Remind me.  That sounds somewhat interesting.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-12-01 Thread Duy Nguyen
On Sun, Nov 30, 2014 at 12:18:40PM -0500, Mark Levedahl wrote:
 On 11/30/2014 03:24 AM, Nguyễn Thái Ngọc Duy wrote:
  One branch obviously can't be checked out at two places (but detached
  heads are ok). Give the user a choice in this case: --detach, -b
  new-branch, switch branch in the other checkout first or simply 'cd'
  and continue to work there.
 
 
 This seems too restrictive and is not obvious to me: I currently use 
 git-new-workdir to have multiple checkouts of the same branch, with no 
 ill effect. While those who do not understand what is going on 
 underneath might be confused by one checkout suddenly showing 
 uncommitted diffs, I don't accept that as a reason to outright prevent 
 such use. I suggest, at the very least, that this behavior be overridden 
 by a --force flag?

Prevention is a strong word. It's more about safety for the mere
mortals. It's certainly possible to do something like this patch
(--force can't be reused, it already carries some other meaning).
Should I add this one in the next (hic) reroll?

-- 8 --
Subject: [PATCH] checkout: add --ignore-other-wortrees

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-checkout.txt |  6 ++
 builtin/checkout.c | 19 +++
 t/t2025-checkout-to.sh |  7 +++
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 0c13825..71d9e4e 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -232,6 +232,12 @@ section of linkgit:git-add[1] to learn how to operate the 
`--patch` mode.
specific files such as HEAD, index... See MULTIPLE WORKING
TREES section for more information.
 
+--ignore-other-worktrees::
+   `git checkout` refuses when the wanted ref is already checked out
+   by another worktree. This option makes it check the
+   ref out anyway. In other words, the ref is held by more than one
+   worktree.
+
 branch::
Branch to checkout; if it refers to a branch (i.e., a name that,
when prepended with refs/heads/, is a valid ref), then that
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 953b763..8b2bf20 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -37,6 +37,7 @@ struct checkout_opts {
int writeout_stage;
int overwrite_ignore;
int ignore_skipworktree;
+   int ignore_other_worktrees;
 
const char *new_branch;
const char *new_branch_force;
@@ -1079,11 +1080,12 @@ static void check_linked_checkouts(struct branch_info 
*new)
 static int parse_branchname_arg(int argc, const char **argv,
int dwim_new_local_branch_ok,
struct branch_info *new,
-   struct tree **source_tree,
-   unsigned char rev[20],
-   const char **new_branch,
-   int force_detach)
+   struct checkout_opts *opts,
+   unsigned char rev[20])
 {
+   struct tree **source_tree = opts-source_tree;
+   const char **new_branch = opts-new_branch;
+   int force_detach = opts-force_detach;
int argcount = 0;
unsigned char branch_rev[20];
const char *arg;
@@ -1209,7 +1211,8 @@ static int parse_branchname_arg(int argc, const char 
**argv,
int flag;
char *head_ref = resolve_refdup(HEAD, 0, sha1, flag);
if (head_ref 
-   (!(flag  REF_ISSYMREF) || strcmp(head_ref, new-path)))
+   (!(flag  REF_ISSYMREF) || strcmp(head_ref, new-path)) 
+   !opts-ignore_other_worktrees)
check_linked_checkouts(new);
free(head_ref);
}
@@ -1340,6 +1343,8 @@ int cmd_checkout(int argc, const char **argv, const char 
*prefix)
N_(second guess 'git checkout 
no-such-branch')),
OPT_FILENAME(0, to, opts.new_worktree,
   N_(check a branch out in a separate working 
directory)),
+   OPT_BOOL(0, ignore-other-worktrees, 
opts.ignore_other_worktrees,
+N_(do not check if another worktree is holding the 
given ref)),
OPT_END(),
};
 
@@ -1420,9 +1425,7 @@ int cmd_checkout(int argc, const char **argv, const char 
*prefix)
opts.track == BRANCH_TRACK_UNSPECIFIED 
!opts.new_branch;
int n = parse_branchname_arg(argc, argv, dwim_ok,
-new, opts.source_tree,
-rev, opts.new_branch,
-opts.force_detach);
+new, opts, rev);
argv += n;
argc -= n;
}

Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-12-01 Thread Junio C Hamano
Duy Nguyen pclo...@gmail.com writes:

 On Sun, Nov 30, 2014 at 12:18:40PM -0500, Mark Levedahl wrote:
 On 11/30/2014 03:24 AM, Nguyễn Thái Ngọc Duy wrote:
  One branch obviously can't be checked out at two places (but detached
  heads are ok). Give the user a choice in this case: --detach, -b
  new-branch, switch branch in the other checkout first or simply 'cd'
  and continue to work there.
 
 
 This seems too restrictive and is not obvious to me: I currently use 
 git-new-workdir to have multiple checkouts of the same branch, with no 
 ill effect. While those who do not understand what is going on 
 underneath might be confused by one checkout suddenly showing 
 uncommitted diffs, I don't accept that as a reason to outright prevent 
 such use. I suggest, at the very least, that this behavior be overridden 
 by a --force flag?

 Prevention is a strong word. It's more about safety for the mere
 mortals. It's certainly possible to do something like this patch
 (--force can't be reused, it already carries some other meaning).
 Should I add this one in the next (hic) reroll?

Sorry, what is a hic?

If this were an existing feature like git-new-workdir, even though
it is from contrib, making it impossible to do something that used
to be possible, even if that something is what mere mortals would
never want to to to avoid risking confusion, would be a regression
that needs an escape hatch.

But this is a new feature.  I am not sure why you need to make this
overridable in the first place.  Those who want to have multiple
checkouts of the same commit can just detach HEAD at the same commit
in multiple working trees, as the first thing they need to do would
be to run git reset --hard $branch to synchronize the HEAD and the
working tree state to work in the other out-of-sync repositories
either case anyway.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 24/34] checkout: reject if the branch is already checked out elsewhere

2014-11-30 Thread Mark Levedahl

On 11/30/2014 03:24 AM, Nguyễn Thái Ngọc Duy wrote:

One branch obviously can't be checked out at two places (but detached
heads are ok). Give the user a choice in this case: --detach, -b
new-branch, switch branch in the other checkout first or simply 'cd'
and continue to work there.



This seems too restrictive and is not obvious to me: I currently use 
git-new-workdir to have multiple checkouts of the same branch, with no 
ill effect. While those who do not understand what is going on 
underneath might be confused by one checkout suddenly showing 
uncommitted diffs, I don't accept that as a reason to outright prevent 
such use. I suggest, at the very least, that this behavior be overridden 
by a --force flag?


Mark

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html