git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Shawn Pearce <spearce@spearce.org>
To: Junio C Hamano <junkio@cox.net>
Cc: git@vger.kernel.org
Subject: Re: Tracking branch history
Date: Sat, 13 May 2006 03:17:53 -0400	[thread overview]
Message-ID: <20060513071753.GA21998@spearce.org> (raw)
In-Reply-To: <7vody2v7yr.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox.net> wrote:
> Shawn Pearce <spearce@spearce.org> writes:
> 
> > git-udpate-ref.  So just have it append the ref's history to a file:
> >
> > 	.git/log/refs/heads/$branch
> >
> > where the history records are stored as:
> >
> > 	40 byte commit-ish SHA1
> > 	<SP>
> > 	<committer>
> > 	<LF>
> >
> > e.g.:
> >
> > 	cbb6d91d95e523c2b6a6b52577c4be28d18ace83 Shawn O. Pearce <spearce@spearce.org> 1137039378 -0500
> > 	ae8c74e96a1e02bbfb7f1a9669b77d6f8ee6c3cf Shawn O. Pearce <spearce@spearce.org> 1136921470 -0500
> >
> 
> Because the question we often would want to ask is "two days ago
> my tip worked but today it does not", recording the timestamp
> makes sense, but I do not know what the point is for the name
> and e-mail.  If it is in your local repository (i.e. the program
> that updates the tip ref is not receive-pack which is invoked by
> your pushing into a remote repo), it will always be you.  And in
> the receive-pack case, the information is not available to begin
> with (you may have a UNIX UID but that is about it).

Agreed.  Prototype patch below.

While writing this I discovered at least two chunks of GIT which
don't use git-update-ref: fetch.c and upload-pack.c.  fetch.c uses
the APIs in refs.c but upload-pack.c doesn't.  I spent a couple of
hours trying to convert update-ref.c to use the APIs in refs.c so
I could just put the logging change there, but that turned out to
be more difficult than expected for a simple prototype so it all
went out the window.

-- >-
Log ref updates to logs/refs/<refname>

If .git/logs/refs/<refname> exists then append a line to it whenever
git-update-ref <refname> is executed.  Each log line contains the
following information:

  40 byte tree-ish SHA1
  <SP>
  date/time
  <LF>

where date/time is the current date, time and timezone in the
standard GIT date format.  If the caller is unable to append to
the log file and the log file exists then git-update-ref will fail
without updating <refname>.

---

 Documentation/git-update-ref.txt |   15 ++++++++++++++
 update-ref.c                     |   41 +++++++++++++++++++++++++++++++++++---
 2 files changed, 53 insertions(+), 3 deletions(-)

8f1ccd3b0eda9d54eca37af178113c91174e81ca
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index 475237f..d314786 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -49,6 +49,21 @@ for reading but not for writing (so we'l
 ref symlink to some other tree, if you have copied a whole
 archive by creating a symlink tree).
 
+Logging Updates
+---------------
+If "$GIT_DIR/logs/<ref>" (possibly dereferencing symbolic refs)
+exists then `git-update-ref` will append a line to the log file
+describing the change in ref value.  Log lines are formatted as:
+
+    . sha1 SP date LF
++
+Where "sha1" is the 40 character hexadecimal value of <newvalue>
+and "date" is the current date/time and timezone in the standard
+GIT date format.
+
+An update will fail (without changing <ref>) if the log file
+exists but the current user is unable to append to the file.
+
 Author
 ------
 Written by Linus Torvalds <torvalds@osdl.org>.
diff --git a/update-ref.c b/update-ref.c
index fd48742..bffe5f9 100644
--- a/update-ref.c
+++ b/update-ref.c
@@ -20,9 +20,9 @@ int main(int argc, char **argv)
 {
 	char *hex;
 	const char *refname, *value, *oldval, *path;
-	char *lockpath;
+	char *lockpath, *logpath;
 	unsigned char sha1[20], oldsha1[20], currsha1[20];
-	int fd, written;
+	int fd, logfd, written, pfxlen;
 
 	setup_git_directory();
 	git_config(git_default_config);
@@ -38,7 +38,9 @@ int main(int argc, char **argv)
 	if (oldval && get_sha1(oldval, oldsha1))
 		die("%s: not a valid old SHA1", oldval);
 
-	path = resolve_ref(git_path("%s", refname), currsha1, !!oldval);
+	path = git_path("%s", refname);
+	pfxlen = strlen(path) - strlen(refname);
+	path = resolve_ref(path, currsha1, !!oldval);
 	if (!path)
 		die("No such ref: %s", refname);
 
@@ -50,6 +52,17 @@ int main(int argc, char **argv)
 			exit(0);
 	}
 	path = strdup(path);
+
+	/*
+	 * If logging is required make sure we can append to the log.
+	 */
+	logpath = strdup(git_path("logs/%s", path + pfxlen));
+	logfd = open(logpath, O_APPEND | O_WRONLY, 0);
+	if (logfd < 0 && errno != ENOENT)
+		die("Unable to append to log %s", logpath);
+	if (logfd >= 0)
+		setup_ident();
+
 	lockpath = mkpath("%s.lock", path);
 	if (safe_create_leading_directories(lockpath) < 0)
 		die("Unable to create all of %s", lockpath);
@@ -75,6 +88,28 @@ int main(int argc, char **argv)
 	}
 
 	/*
+	 * Write to the log, if it was opened.
+	 */
+	if (logfd >= 0) {
+		char now[50];
+		char logrec[100];
+		unsigned len;
+
+		datestamp(now, sizeof(now));
+		len = snprintf(logrec, sizeof(logrec), "%s %s\n", sha1_to_hex(sha1), now);
+		if (len >= sizeof(logrec)) {
+			unlink(lockpath);
+			die("Internal error formatting log record.");
+		}
+		written = write(logfd, logrec, len);
+		if (written != len) {
+			unlink(lockpath);
+			die("Unable to append to %s", logpath);
+		}
+		close(logfd);
+	}
+
+	/*
 	 * Finally, replace the old ref with the new one
 	 */
 	if (rename(lockpath, path) < 0) {
-- 
1.3.2.g7278

  reply	other threads:[~2006-05-13  7:18 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-12 23:18 Tracking branch history Daniel Barkalow
2006-05-12 23:45 ` Linus Torvalds
2006-05-13  0:03   ` Linus Torvalds
2006-05-13  4:27     ` Daniel Barkalow
2006-05-13  3:40   ` Shawn Pearce
2006-05-13  4:38     ` Linus Torvalds
2006-05-13  4:56     ` Junio C Hamano
2006-05-13  7:17       ` Shawn Pearce [this message]
2006-05-13  7:43         ` Shawn Pearce
2006-05-13 15:20           ` Linus Torvalds
2006-05-13 16:43             ` Junio C Hamano
2006-05-13 18:18               ` Shawn Pearce
2006-05-14 23:14                 ` Junio C Hamano
2006-05-15  3:15                   ` Shawn Pearce
2006-05-15  5:58                     ` Shawn Pearce
2006-05-15  6:27                       ` Junio C Hamano
2006-05-15  6:38                         ` Shawn Pearce
2006-05-15  9:53                           ` Shawn Pearce
2006-05-13 15:11         ` Linus Torvalds
2006-05-13 12:53 ` Elrond
2006-05-14 23:16   ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060513071753.GA21998@spearce.org \
    --to=spearce@spearce.org \
    --cc=git@vger.kernel.org \
    --cc=junkio@cox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).