Re: [PATCH v3 1/2] refs: add a new function set_worktree_head_symref

2016-04-08 Thread Eric Sunshine
On Fri, Apr 8, 2016 at 2:37 AM, Kazuki Yamaguchi  wrote:
> On Thu, Apr 07, 2016 at 05:20:10PM -0400, Eric Sunshine wrote:
>> On Sun, Mar 27, 2016 at 10:37 AM, Kazuki Yamaguchi  wrote:
>> > +int set_worktree_head_symref(const char *gitdir, const char *target)
>> > +{
>> > +   static struct lock_file head_lock;
>> > +   struct ref_lock *lock;
>> > +   struct strbuf err = STRBUF_INIT;
>> > +   struct strbuf head_path = STRBUF_INIT;
>> > +   const char *head_rel;
>> > +   int ret;
>> > +
>> > +   strbuf_addf(_path, "%s/HEAD", absolute_path(gitdir));
>> > +   if (hold_lock_file_for_update(_lock, head_path.buf,
>> > + LOCK_NO_DEREF) < 0) {
>> > +   error("%s", err.buf);
>>
>> 'err' has not been populated at this point, so I suspect that this
>> error message is likely to be rather uninformative.
>
> Yes, unable_to_lock_message() is missing. Thank you for pointing it out.

You're welcome. As this patch is already in Junio's "next" branch, if
you post a fix, it should be incremental atop "ky/branch-m-worktree",
rather than as a re-roll of this series.
--
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 v3 1/2] refs: add a new function set_worktree_head_symref

2016-04-08 Thread Kazuki Yamaguchi
On Thu, Apr 07, 2016 at 05:20:10PM -0400, Eric Sunshine wrote:
> On Sun, Mar 27, 2016 at 10:37 AM, Kazuki Yamaguchi  wrote:
> > Add a new function set_worktree_head_symref, to update HEAD symref for
> > the specified worktree.
> >
> > To update HEAD of a linked working tree,
> > create_symref("worktrees/$work_tree/HEAD", "refs/heads/$branch", msg)
> > could be used. However when it comes to updating HEAD of the main
> > working tree, it is unusable because it uses $GIT_DIR for
> > worktree-specific symrefs (HEAD).
> >
> > The new function takes git_dir (real directory) as an argument, and
> > updates HEAD of the working tree. This function will be used when
> > renaming a branch.
> >
> > Signed-off-by: Kazuki Yamaguchi 
> > ---
> > diff --git a/refs/files-backend.c b/refs/files-backend.c
> > @@ -2894,6 +2894,41 @@ int create_symref(const char *refname, const char 
> > *target, const char *logmsg)
> > +int set_worktree_head_symref(const char *gitdir, const char *target)
> > +{
> > +   static struct lock_file head_lock;
> > +   struct ref_lock *lock;
> > +   struct strbuf err = STRBUF_INIT;
> > +   struct strbuf head_path = STRBUF_INIT;
> > +   const char *head_rel;
> > +   int ret;
> > +
> > +   strbuf_addf(_path, "%s/HEAD", absolute_path(gitdir));
> > +   if (hold_lock_file_for_update(_lock, head_path.buf,
> > + LOCK_NO_DEREF) < 0) {
> > +   error("%s", err.buf);
> 
> 'err' has not been populated at this point, so I suspect that this
> error message is likely to be rather uninformative.

Yes, unable_to_lock_message() is missing. Thank you for pointing it out.

> 
> > +   strbuf_release();
> > +   strbuf_release(_path);
> > +   return -1;
> > +   }
> > +
> > +   /* head_rel will be "HEAD" for the main tree, "worktrees/wt/HEAD" 
> > for
> > +  linked trees */
> > +   head_rel = remove_leading_path(head_path.buf,
> > +  absolute_path(get_git_common_dir()));
> > +   /* to make use of create_symref_locked(), initialize ref_lock */
> > +   lock = xcalloc(1, sizeof(struct ref_lock));
> > +   lock->lk = _lock;
> > +   lock->ref_name = xstrdup(head_rel);
> > +   lock->orig_ref_name = xstrdup(head_rel);
> > +
> > +   ret = create_symref_locked(lock, head_rel, target, NULL);
> > +
> > +   unlock_ref(lock); /* will free lock */
> > +   strbuf_release(_path);
> > +   return ret;
> > +}
> > +
--
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 v3 1/2] refs: add a new function set_worktree_head_symref

2016-04-07 Thread Eric Sunshine
On Sun, Mar 27, 2016 at 10:37 AM, Kazuki Yamaguchi  wrote:
> Add a new function set_worktree_head_symref, to update HEAD symref for
> the specified worktree.
>
> To update HEAD of a linked working tree,
> create_symref("worktrees/$work_tree/HEAD", "refs/heads/$branch", msg)
> could be used. However when it comes to updating HEAD of the main
> working tree, it is unusable because it uses $GIT_DIR for
> worktree-specific symrefs (HEAD).
>
> The new function takes git_dir (real directory) as an argument, and
> updates HEAD of the working tree. This function will be used when
> renaming a branch.
>
> Signed-off-by: Kazuki Yamaguchi 
> ---
> diff --git a/refs/files-backend.c b/refs/files-backend.c
> @@ -2894,6 +2894,41 @@ int create_symref(const char *refname, const char 
> *target, const char *logmsg)
> +int set_worktree_head_symref(const char *gitdir, const char *target)
> +{
> +   static struct lock_file head_lock;
> +   struct ref_lock *lock;
> +   struct strbuf err = STRBUF_INIT;
> +   struct strbuf head_path = STRBUF_INIT;
> +   const char *head_rel;
> +   int ret;
> +
> +   strbuf_addf(_path, "%s/HEAD", absolute_path(gitdir));
> +   if (hold_lock_file_for_update(_lock, head_path.buf,
> + LOCK_NO_DEREF) < 0) {
> +   error("%s", err.buf);

'err' has not been populated at this point, so I suspect that this
error message is likely to be rather uninformative.

> +   strbuf_release();
> +   strbuf_release(_path);
> +   return -1;
> +   }
> +
> +   /* head_rel will be "HEAD" for the main tree, "worktrees/wt/HEAD" for
> +  linked trees */
> +   head_rel = remove_leading_path(head_path.buf,
> +  absolute_path(get_git_common_dir()));
> +   /* to make use of create_symref_locked(), initialize ref_lock */
> +   lock = xcalloc(1, sizeof(struct ref_lock));
> +   lock->lk = _lock;
> +   lock->ref_name = xstrdup(head_rel);
> +   lock->orig_ref_name = xstrdup(head_rel);
> +
> +   ret = create_symref_locked(lock, head_rel, target, NULL);
> +
> +   unlock_ref(lock); /* will free lock */
> +   strbuf_release(_path);
> +   return ret;
> +}
> +
--
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 v3 1/2] refs: add a new function set_worktree_head_symref

2016-03-28 Thread David Turner
On Mon, 2016-03-28 at 10:48 -0700, Junio C Hamano wrote:
> Kazuki Yamaguchi  writes:
> 
> > Add a new function set_worktree_head_symref, to update HEAD symref
> > for
> > the specified worktree.
> > 
> > To update HEAD of a linked working tree,
> > create_symref("worktrees/$work_tree/HEAD", "refs/heads/$branch",
> > msg)
> > could be used. However when it comes to updating HEAD of the main
> > working tree, it is unusable because it uses $GIT_DIR for
> > worktree-specific symrefs (HEAD).
> > 
> > The new function takes git_dir (real directory) as an argument, and
> > updates HEAD of the working tree. This function will be used when
> > renaming a branch.
> > 
> > Signed-off-by: Kazuki Yamaguchi 
> > ---
> 
> I suspect that this helper function should be in the common layer
> (refs.c) to be redirected to specific backend(s).
> 
> David & Michael, what do you think?

HEAD is a per-worktree ref, so it's always handled by the files
backend.  So this looks fine to me.

> > +/*
> > + * Update HEAD of the specified gitdir.
> > + * Similar to create_symref("relative-git-dir/HEAD", target,
> > NULL), but this is
> > + * able to update the main working tree's HEAD wherever $GIT_DIR
> > points to.


nit: "able to update the main working tree's HEAD regardless of where
GIT_DIR points to" would be clearer.

--
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 v3 1/2] refs: add a new function set_worktree_head_symref

2016-03-28 Thread Junio C Hamano
Kazuki Yamaguchi  writes:

> Add a new function set_worktree_head_symref, to update HEAD symref for
> the specified worktree.
>
> To update HEAD of a linked working tree,
> create_symref("worktrees/$work_tree/HEAD", "refs/heads/$branch", msg)
> could be used. However when it comes to updating HEAD of the main
> working tree, it is unusable because it uses $GIT_DIR for
> worktree-specific symrefs (HEAD).
>
> The new function takes git_dir (real directory) as an argument, and
> updates HEAD of the working tree. This function will be used when
> renaming a branch.
>
> Signed-off-by: Kazuki Yamaguchi 
> ---

I suspect that this helper function should be in the common layer
(refs.c) to be redirected to specific backend(s).

David & Michael, what do you think?

>  refs.h   |  8 
>  refs/files-backend.c | 35 +++
>  2 files changed, 43 insertions(+)
>
> diff --git a/refs.h b/refs.h
> index 2f3decb432cf..f11154cf5faf 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -306,6 +306,14 @@ extern int rename_ref(const char *oldref, const char 
> *newref, const char *logmsg
>  
>  extern int create_symref(const char *refname, const char *target, const char 
> *logmsg);
>  
> +/*
> + * Update HEAD of the specified gitdir.
> + * Similar to create_symref("relative-git-dir/HEAD", target, NULL), but this 
> is
> + * able to update the main working tree's HEAD wherever $GIT_DIR points to.
> + * Return 0 if successful, non-zero otherwise.
> + * */
> +extern int set_worktree_head_symref(const char *gitdir, const char *target);
> +
>  enum action_on_err {
>   UPDATE_REFS_MSG_ON_ERR,
>   UPDATE_REFS_DIE_ON_ERR,
> diff --git a/refs/files-backend.c b/refs/files-backend.c
> index 81f68f846b69..ec237efec35d 100644
> --- a/refs/files-backend.c
> +++ b/refs/files-backend.c
> @@ -2894,6 +2894,41 @@ int create_symref(const char *refname, const char 
> *target, const char *logmsg)
>   return ret;
>  }
>  
> +int set_worktree_head_symref(const char *gitdir, const char *target)
> +{
> + static struct lock_file head_lock;
> + struct ref_lock *lock;
> + struct strbuf err = STRBUF_INIT;
> + struct strbuf head_path = STRBUF_INIT;
> + const char *head_rel;
> + int ret;
> +
> + strbuf_addf(_path, "%s/HEAD", absolute_path(gitdir));
> + if (hold_lock_file_for_update(_lock, head_path.buf,
> +   LOCK_NO_DEREF) < 0) {
> + error("%s", err.buf);
> + strbuf_release();
> + strbuf_release(_path);
> + return -1;
> + }
> +
> + /* head_rel will be "HEAD" for the main tree, "worktrees/wt/HEAD" for
> +linked trees */
> + head_rel = remove_leading_path(head_path.buf,
> +absolute_path(get_git_common_dir()));
> + /* to make use of create_symref_locked(), initialize ref_lock */
> + lock = xcalloc(1, sizeof(struct ref_lock));
> + lock->lk = _lock;
> + lock->ref_name = xstrdup(head_rel);
> + lock->orig_ref_name = xstrdup(head_rel);
> +
> + ret = create_symref_locked(lock, head_rel, target, NULL);
> +
> + unlock_ref(lock); /* will free lock */
> + strbuf_release(_path);
> + return ret;
> +}
> +
>  int reflog_exists(const char *refname)
>  {
>   struct stat st;
--
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


[PATCH v3 1/2] refs: add a new function set_worktree_head_symref

2016-03-27 Thread Kazuki Yamaguchi
Add a new function set_worktree_head_symref, to update HEAD symref for
the specified worktree.

To update HEAD of a linked working tree,
create_symref("worktrees/$work_tree/HEAD", "refs/heads/$branch", msg)
could be used. However when it comes to updating HEAD of the main
working tree, it is unusable because it uses $GIT_DIR for
worktree-specific symrefs (HEAD).

The new function takes git_dir (real directory) as an argument, and
updates HEAD of the working tree. This function will be used when
renaming a branch.

Signed-off-by: Kazuki Yamaguchi 
---
 refs.h   |  8 
 refs/files-backend.c | 35 +++
 2 files changed, 43 insertions(+)

diff --git a/refs.h b/refs.h
index 2f3decb432cf..f11154cf5faf 100644
--- a/refs.h
+++ b/refs.h
@@ -306,6 +306,14 @@ extern int rename_ref(const char *oldref, const char 
*newref, const char *logmsg
 
 extern int create_symref(const char *refname, const char *target, const char 
*logmsg);
 
+/*
+ * Update HEAD of the specified gitdir.
+ * Similar to create_symref("relative-git-dir/HEAD", target, NULL), but this is
+ * able to update the main working tree's HEAD wherever $GIT_DIR points to.
+ * Return 0 if successful, non-zero otherwise.
+ * */
+extern int set_worktree_head_symref(const char *gitdir, const char *target);
+
 enum action_on_err {
UPDATE_REFS_MSG_ON_ERR,
UPDATE_REFS_DIE_ON_ERR,
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 81f68f846b69..ec237efec35d 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2894,6 +2894,41 @@ int create_symref(const char *refname, const char 
*target, const char *logmsg)
return ret;
 }
 
+int set_worktree_head_symref(const char *gitdir, const char *target)
+{
+   static struct lock_file head_lock;
+   struct ref_lock *lock;
+   struct strbuf err = STRBUF_INIT;
+   struct strbuf head_path = STRBUF_INIT;
+   const char *head_rel;
+   int ret;
+
+   strbuf_addf(_path, "%s/HEAD", absolute_path(gitdir));
+   if (hold_lock_file_for_update(_lock, head_path.buf,
+ LOCK_NO_DEREF) < 0) {
+   error("%s", err.buf);
+   strbuf_release();
+   strbuf_release(_path);
+   return -1;
+   }
+
+   /* head_rel will be "HEAD" for the main tree, "worktrees/wt/HEAD" for
+  linked trees */
+   head_rel = remove_leading_path(head_path.buf,
+  absolute_path(get_git_common_dir()));
+   /* to make use of create_symref_locked(), initialize ref_lock */
+   lock = xcalloc(1, sizeof(struct ref_lock));
+   lock->lk = _lock;
+   lock->ref_name = xstrdup(head_rel);
+   lock->orig_ref_name = xstrdup(head_rel);
+
+   ret = create_symref_locked(lock, head_rel, target, NULL);
+
+   unlock_ref(lock); /* will free lock */
+   strbuf_release(_path);
+   return ret;
+}
+
 int reflog_exists(const char *refname)
 {
struct stat st;
-- 
2.8.0.rc4.21.g05df949

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