Skip to content

Commit 39ee4c6

Browse files
kyleamgitster
authored andcommitted
branch: record creation of renamed branch in HEAD's log
Renaming the current branch adds an event to the current branch's log and to HEAD's log. However, the logged entries differ. The entry in the branch's log represents the entire renaming operation (the old and new hash are identical), whereas the entry in HEAD's log represents the deletion only (the new sha1 is null). Extend replace_each_worktree_head_symref(), whose only caller is branch_rename(), to take a reflog message argument. This allows the creation of the new ref to be recorded in HEAD's log. As a result, the renaming event is represented by two entries (a deletion and a creation entry) in HEAD's log. It's a bit unfortunate that the branch's log and HEAD's log now represent the renaming event in different ways. Given that the renaming operation is not atomic, the two-entry form is a more accurate representation of the operation and is more useful for debugging purposes if a failure occurs between the deletion and creation events. It would make sense to move the branch's log to the two-entry form, but this would involve changes to how the rename is carried out and to how the update flags and reflogs are processed for deletions, so it may not be worth the effort. Based-on-patch-by: Jeff King <[email protected]> Signed-off-by: Kyle Meyer <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 893dbf5 commit 39ee4c6

File tree

6 files changed

+15
-10
lines changed

6 files changed

+15
-10
lines changed

branch.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,8 @@ void die_if_checked_out(const char *branch, int ignore_current_worktree)
345345
branch, wt->path);
346346
}
347347

348-
int replace_each_worktree_head_symref(const char *oldref, const char *newref)
348+
int replace_each_worktree_head_symref(const char *oldref, const char *newref,
349+
const char *logmsg)
349350
{
350351
int ret = 0;
351352
struct worktree **worktrees = get_worktrees(0);
@@ -358,7 +359,7 @@ int replace_each_worktree_head_symref(const char *oldref, const char *newref)
358359
continue;
359360

360361
if (set_worktree_head_symref(get_worktree_git_dir(worktrees[i]),
361-
newref)) {
362+
newref, logmsg)) {
362363
ret = -1;
363364
error(_("HEAD of working tree %s is not updated"),
364365
worktrees[i]->path);

branch.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ extern void die_if_checked_out(const char *branch, int ignore_current_worktree);
7171
* This will be used when renaming a branch. Returns 0 if successful, non-zero
7272
* otherwise.
7373
*/
74-
extern int replace_each_worktree_head_symref(const char *oldref, const char *newref);
74+
extern int replace_each_worktree_head_symref(const char *oldref, const char *newref,
75+
const char *logmsg);
7576

7677
#endif

builtin/branch.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,14 +579,15 @@ static void rename_branch(const char *oldname, const char *newname, int force)
579579

580580
if (rename_ref(oldref.buf, newref.buf, logmsg.buf))
581581
die(_("Branch rename failed"));
582-
strbuf_release(&logmsg);
583582

584583
if (recovery)
585584
warning(_("Renamed a misnamed branch '%s' away"), oldref.buf + 11);
586585

587-
if (replace_each_worktree_head_symref(oldref.buf, newref.buf))
586+
if (replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf))
588587
die(_("Branch renamed to %s, but HEAD is not updated!"), newname);
589588

589+
strbuf_release(&logmsg);
590+
590591
strbuf_addf(&oldsection, "branch.%s", oldref.buf + 11);
591592
strbuf_release(&oldref);
592593
strbuf_addf(&newsection, "branch.%s", newref.buf + 11);

refs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ int create_symref(const char *refname, const char *target, const char *logmsg);
334334
* $GIT_DIR points to.
335335
* Return 0 if successful, non-zero otherwise.
336336
* */
337-
int set_worktree_head_symref(const char *gitdir, const char *target);
337+
int set_worktree_head_symref(const char *gitdir, const char *target,
338+
const char *logmsg);
338339

339340
enum action_on_err {
340341
UPDATE_REFS_MSG_ON_ERR,

refs/files-backend.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,7 +3055,7 @@ static int files_create_symref(struct ref_store *ref_store,
30553055
return ret;
30563056
}
30573057

3058-
int set_worktree_head_symref(const char *gitdir, const char *target)
3058+
int set_worktree_head_symref(const char *gitdir, const char *target, const char *logmsg)
30593059
{
30603060
static struct lock_file head_lock;
30613061
struct ref_lock *lock;
@@ -3083,7 +3083,7 @@ int set_worktree_head_symref(const char *gitdir, const char *target)
30833083
lock->lk = &head_lock;
30843084
lock->ref_name = xstrdup(head_rel);
30853085

3086-
ret = create_symref_locked(lock, head_rel, target, NULL);
3086+
ret = create_symref_locked(lock, head_rel, target, logmsg);
30873087

30883088
unlock_ref(lock); /* will free lock */
30893089
strbuf_release(&head_path);

t/t3200-branch.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,10 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
139139
test $(git rev-parse --abbrev-ref HEAD) = bam
140140
'
141141

142-
test_expect_success 'git branch -M baz bam should add entry to .git/logs/HEAD' '
142+
test_expect_success 'git branch -M baz bam should add entries to .git/logs/HEAD' '
143143
msg="Branch: renamed refs/heads/baz to refs/heads/bam" &&
144-
grep " 0\{40\}.*$msg$" .git/logs/HEAD
144+
grep " 0\{40\}.*$msg$" .git/logs/HEAD &&
145+
grep "^0\{40\}.*$msg$" .git/logs/HEAD
145146
'
146147

147148
test_expect_success 'git branch -M baz bam should succeed when baz is checked out as linked working tree' '

0 commit comments

Comments
 (0)