Jeff King <peff@xxxxxxxx> writes: > Linus suggested resetting the timestamp after making the commit, to > clear the way for the next commit. But if we reset any cached value > _before_ making the commit, this has a few advantages: I guess our mails crossed ;-). > It does feel a little backwards to cache by default, and then try to > catch all the places that want to reset. Another way of thinking about > it would be to almost _never_ cache, but let a few callsites like (the > commit object creation) explicitly ask for a stable timestamp between > the author and committer. ... and the reflog? I would say that the approach taken by this version is perfectly sensible, if we don't look at it as a "cache" and instead look at it as a "snapshot" of the clock for the duration of the operation. "reset" is like "now we are starting another operation, so grab a snapshot please". The changes to both tagging and committing look sensible. Thanks. > -- >8 -- > Subject: reset cached ident date before creating objects > > When we compute the date to put in author/committer lines of > commits, or tagger lines of tags, we get the current date > once and then cache it for the rest of the program. This is > a good thing in some cases, like "git commit", because it > means we do not racily assign different times to the > author/committer fields of a single commit object. > > But as more programs start to make many commits in a single > process (e.g., the recently builtin "git am"), it means that > you'll get long strings of commits with identical committer > timestamps (whereas before, we invoked "git commit" many > times and got true timestamps). > > This patch addresses it by letting callers reset the cached > time, which means they'll get a fresh time on their next > call to git_committer_info() or git_author_info(). We do so > automatically before filling in the ident fields of commit > and tag objects. That retains the property that committers > and authors in a single object will match, but means that > separate objects we create should always get their own > fresh timestamps. > > There's no automated test, because it would be inherently > racy (it depends on whether the program takes multiple > seconds to run). But you can see the effect with something > like: > > # make a fake 100-patch series; use --first-parent > # so that we pretend merges are just more patches > top=$(git rev-parse HEAD) > bottom=$(git rev-list --first-parent -100 HEAD | tail -n 1) > git log --format=email --reverse --first-parent \ > --binary -m -p $bottom..$top >patch > > # now apply it; this presumably takes multiple seconds > git checkout --detach $bottom > git am <patch > > # now count the number of distinct committer times; > # prior to this patch, there would only be one, but > # now we'd typically see several. > git log --format=%ct $bottom.. | sort -u > > Suggested-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> > Signed-off-by: Jeff King <peff@xxxxxxxx> > --- > builtin/tag.c | 1 + > cache.h | 1 + > commit.c | 1 + > ident.c | 5 +++++ > 4 files changed, 8 insertions(+) > > diff --git a/builtin/tag.c b/builtin/tag.c > index 50e4ae5..3025e7f 100644 > --- a/builtin/tag.c > +++ b/builtin/tag.c > @@ -225,6 +225,7 @@ static void create_tag(const unsigned char *object, const char *tag, > if (type <= OBJ_NONE) > die(_("bad object type.")); > > + reset_ident_date(); > header_len = snprintf(header_buf, sizeof(header_buf), > "object %s\n" > "type %s\n" > diff --git a/cache.h b/cache.h > index b5f76a4..31e65f9 100644 > --- a/cache.h > +++ b/cache.h > @@ -1269,6 +1269,7 @@ extern const char *ident_default_email(void); > extern const char *git_editor(void); > extern const char *git_pager(int stdout_is_tty); > extern int git_ident_config(const char *, const char *, void *); > +extern void reset_ident_date(void); > > struct ident_split { > const char *name_begin; > diff --git a/commit.c b/commit.c > index 71a360d..7ddbffe 100644 > --- a/commit.c > +++ b/commit.c > @@ -1548,6 +1548,7 @@ int commit_tree_extended(const char *msg, size_t msg_len, > } > > /* Person/date information */ > + reset_ident_date(); > if (!author) > author = git_author_info(IDENT_STRICT); > strbuf_addf(&buffer, "author %s\n", author); > diff --git a/ident.c b/ident.c > index 139c528..e20a772 100644 > --- a/ident.c > +++ b/ident.c > @@ -184,6 +184,11 @@ static const char *ident_default_date(void) > return git_default_date.buf; > } > > +void reset_ident_date(void) > +{ > + strbuf_reset(&git_default_date); > +} > + > static int crud(unsigned char c) > { > return c <= 32 || -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html