Skip to content

Commit

Permalink
sequencer: truncate lockfile and ref to NAME_MAX
Browse files Browse the repository at this point in the history
Some commits may have unusually long subject lines, which can cause git
error out.
Currently the sequencer and lockfile assumes these to be less than
NAME_MAX which is the maximum length of a filename (on Linux).

When reproduced one is met by the error message:
$ git rebase --continue
error: cannot lock ref 'refs/rewritten/SANITIZED-SUBJECT': Unable to
create '.git/refs/rewritten/SANITIZED-SUBJECT.lock': File name too long
- where SANITIZED-SUBJECT is very long

Affected repos can only be salvaged through filter-branch etc.

Signed-off-by: Mark Ruvald Pedersen <[email protected]>
  • Loading branch information
Mark Ruvald Pedersen committed Aug 9, 2023
1 parent a82fb66 commit b0758b8
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 2 deletions.
4 changes: 4 additions & 0 deletions git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,10 @@ char *gitdirname(char *);
#define PATH_MAX 4096
#endif

#ifndef NAME_MAX
#define NAME_MAX 255
#endif

typedef uintmax_t timestamp_t;
#define PRItime PRIuMAX
#define parse_timestamp strtoumax
Expand Down
10 changes: 8 additions & 2 deletions sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@

#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"

#define GIT_MAX_LABEL_LENGTH ((NAME_MAX) - (LOCK_SUFFIX_LEN))

#define GIT_MIN(a, b) ((a) < (b) ? (a) : (b))

static const char sign_off_header[] = "Signed-off-by: ";
static const char cherry_picked_prefix[] = "(cherry picked from commit ";

Expand Down Expand Up @@ -3701,11 +3705,12 @@ static int do_label(struct repository *r, const char *name, int len)
struct strbuf msg = STRBUF_INIT;
int ret = 0;
struct object_id head_oid;
int len_trunc = GIT_MIN(len, GIT_MAX_LABEL_LENGTH);

if (len == 1 && *name == '#')
return error(_("illegal label name: '%.*s'"), len, name);

strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name);
strbuf_addf(&ref_name, "refs/rewritten/%.*s", len_trunc, name);
strbuf_addf(&msg, "rebase (label) '%.*s'", len, name);

transaction = ref_store_transaction_begin(refs, &err);
Expand Down Expand Up @@ -3769,11 +3774,12 @@ static const char *reflog_message(struct replay_opts *opts,
static struct commit *lookup_label(struct repository *r, const char *label,
int len, struct strbuf *buf)
{
int len_trunc = GIT_MIN(len, GIT_MAX_LABEL_LENGTH);
struct commit *commit;
struct object_id oid;

strbuf_reset(buf);
strbuf_addf(buf, "refs/rewritten/%.*s", len, label);
strbuf_addf(buf, "refs/rewritten/%.*s", len_trunc, label);
if (!read_ref(buf->buf, &oid)) {
commit = lookup_commit_object(r, &oid);
} else {
Expand Down

0 comments on commit b0758b8

Please sign in to comment.