Skip to content

Commit 5e6f003

Browse files
mhaggergitster
authored andcommitted
reflog_expire(): ignore --updateref for symbolic references
If we are expiring reflog entries for a symbolic reference, then how should --updateref be handled if the newest reflog entry is expired? Option 1: Update the referred-to reference. (This is what the current code does.) This doesn't make sense, because the referred-to reference has its own reflog, which hasn't been rewritten. Option 2: Update the symbolic reference itself (as in, REF_NODEREF). This would convert the symbolic reference into a non-symbolic reference (e.g., detaching HEAD), which is surely not what a user would expect. Option 3: Error out. This is plausible, but it would make the following usage impossible: git reflog expire ... --updateref --all Option 4: Ignore --updateref for symbolic references. We choose to implement option 4. Note: another problem in this code will be fixed in a moment. Signed-off-by: Michael Haggerty <[email protected]> Reviewed-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fe2a181 commit 5e6f003

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

Documentation/git-reflog.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ Options for `expire`
8888

8989
--updateref::
9090
Update the reference to the value of the top reflog entry (i.e.
91-
<ref>@\{0\}) if the previous top entry was pruned.
91+
<ref>@\{0\}) if the previous top entry was pruned. (This
92+
option is ignored for symbolic references.)
9293

9394
--rewrite::
9495
If a reflog entry's predecessor is pruned, adjust its "old"

refs.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4029,6 +4029,7 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
40294029
struct ref_lock *lock;
40304030
char *log_file;
40314031
int status = 0;
4032+
int type;
40324033

40334034
memset(&cb, 0, sizeof(cb));
40344035
cb.flags = flags;
@@ -4040,7 +4041,7 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
40404041
* reference itself, plus we might need to update the
40414042
* reference if --updateref was specified:
40424043
*/
4043-
lock = lock_ref_sha1_basic(refname, sha1, NULL, 0, NULL);
4044+
lock = lock_ref_sha1_basic(refname, sha1, NULL, 0, &type);
40444045
if (!lock)
40454046
return error("cannot lock ref '%s'", refname);
40464047
if (!reflog_exists(refname)) {
@@ -4077,10 +4078,18 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
40774078
(*cleanup_fn)(cb.policy_cb);
40784079

40794080
if (!(flags & EXPIRE_REFLOGS_DRY_RUN)) {
4081+
/*
4082+
* It doesn't make sense to adjust a reference pointed
4083+
* to by a symbolic ref based on expiring entries in
4084+
* the symbolic reference's reflog.
4085+
*/
4086+
int update = (flags & EXPIRE_REFLOGS_UPDATE_REF) &&
4087+
!(type & REF_ISSYMREF);
4088+
40804089
if (close_lock_file(&reflog_lock)) {
40814090
status |= error("couldn't write %s: %s", log_file,
40824091
strerror(errno));
4083-
} else if ((flags & EXPIRE_REFLOGS_UPDATE_REF) &&
4092+
} else if (update &&
40844093
(write_in_full(lock->lock_fd,
40854094
sha1_to_hex(cb.last_kept_sha1), 40) != 40 ||
40864095
write_str_in_full(lock->lock_fd, "\n") != 1 ||
@@ -4091,7 +4100,7 @@ int reflog_expire(const char *refname, const unsigned char *sha1,
40914100
} else if (commit_lock_file(&reflog_lock)) {
40924101
status |= error("unable to commit reflog '%s' (%s)",
40934102
log_file, strerror(errno));
4094-
} else if ((flags & EXPIRE_REFLOGS_UPDATE_REF) && commit_ref(lock)) {
4103+
} else if (update && commit_ref(lock)) {
40954104
status |= error("couldn't set %s", lock->ref_name);
40964105
}
40974106
}

0 commit comments

Comments
 (0)