Staging
v0.5.1
https://github.com/git/git
Revision 46774a81f9d6ca4d230d33757afe9dd07bfe398b authored by Junio C Hamano on 29 October 2005, 21:35:11 UTC, committed by Junio C Hamano on 29 October 2005, 21:35:11 UTC
Done in 0.99.9
==============

Ports
~~~~~

* Cygwin port [HPA].

* OpenBSD build [Merlyn and others].

Fixes
~~~~~

* clone request over git native protocol from a repository with
  too many refs did not work; this has been fixed.

* git-daemon got safer for kernel.org use [HPA].

* Extended SHA1 parser was not enforcing uniqueness for
  abbreviated SHA1; this has been fixed.

* http transport does not barf on funny characters in URL.

* The ref naming restrictions have been formalized and the
  coreish refuses to create funny refs; we still need to audit
  importers.  See git-check-ref-format(1).

New Features and Commands
~~~~~~~~~~~~~~~~~~~~~~~~~

* .git/config file as a per-repository configuration mechanism,
  and some commands understand it [Linus].  See
  git(7).

* The core.filemode configuration item can be used to make us a
  bit more FAT friendly.  See git(7).

* The extended SHA1 notation acquired Peel-the-onion operator
  ^{type} and ^{}.  See git-rev-parse(1).

* SVN importer [Matthias].  See git-svnimport(1).

* .git/objects/[0-9a-f]{2} directories are created on demand,
  and removed when becomes empty after prune-packed [Linus].

* Filenames output from various commands without -z option are
  quoted when they embed funny characters (TAB and LF) using
  C-style quoting within double-quotes, to match the proposed
  GNU diff/patch notation [me, but many people contributed in
  the discussion].

* git-mv is expected to be a better replacement for git-rename.
  While the latter has two parameter restriction, it acts more
  like the regular 'mv' that can move multiple things to one
  destinatino directory [Josef Weidendorfer].

* git-checkout can take filenames to revert the changes to
  them.  See git-checkout(1)

* The new program git-am is a replacement for git-applymbox that
  has saner command line options and a bit easier to use when a
  patch does not apply cleanly.

* git-ls-remote can show unwrapped onions using ^{} notation, to
  help Cogito to track tags.

* git-merge-recursive backend can merge unrelated projects.

* git-clone over native transport leaves the result packed.

* git-http-fetch issues multiple requests in parallel when
  underlying cURL library supports it [Nick and Daniel].

* git-fetch-pack and git-upload-pack try harder to figure out
  better common commits [Johannes].

* git-read-tree -u removes a directory when it makes it empty.

* git-diff-* records abbreviated SHA1 names of original and
  resulting blob; this sometimes helps to apply otherwise an
  unapplicable patch by falling back to 3-way merge.

* git-format-patch now takes series of from..to rev ranges and
  with '-m --stdout', writes them out to the standard output.
  This can be piped to 'git-am' to implement cheaper
  cherry-picking.

* git-tag takes '-u' to specify the tag signer identity [Linus].

* git-rev-list can take optional pathspecs to skip commits that
  do not touch them (--dense) [Linus].

* Comes with new and improved gitk [Paulus and Linus].

Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 5773c9f
Raw File
Tip revision: 46774a81f9d6ca4d230d33757afe9dd07bfe398b authored by Junio C Hamano on 29 October 2005, 21:35:11 UTC
GIT 0.99.9
Tip revision: 46774a8
update-ref.c
#include "cache.h"
#include "refs.h"

static const char git_update_ref_usage[] = "git-update-ref <refname> <value> [<oldval>]";

static int re_verify(const char *path, unsigned char *oldsha1, unsigned char *currsha1)
{
	char buf[40];
	int fd = open(path, O_RDONLY), nr;
	if (fd < 0)
		return -1;
	nr = read(fd, buf, 40);
	close(fd);
	if (nr != 40 || get_sha1_hex(buf, currsha1) < 0)
		return -1;
	return memcmp(oldsha1, currsha1, 20) ? -1 : 0;
}

int main(int argc, char **argv)
{
	char *hex;
	const char *refname, *value, *oldval, *path, *lockpath;
	unsigned char sha1[20], oldsha1[20], currsha1[20];
	int fd, written;

	setup_git_directory();
	if (argc < 3 || argc > 4)
		usage(git_update_ref_usage);

	refname = argv[1];
	value = argv[2];
	oldval = argv[3];
	if (get_sha1(value, sha1) < 0)
		die("%s: not a valid SHA1", value);
	memset(oldsha1, 0, 20);
	if (oldval && get_sha1(oldval, oldsha1) < 0)
		die("%s: not a valid old SHA1", oldval);

	path = resolve_ref(git_path("%s", refname), currsha1, !!oldval);
	if (!path)
		die("No such ref: %s", refname);

	if (oldval) {
		if (memcmp(currsha1, oldsha1, 20))
			die("Ref %s changed to %s", refname, sha1_to_hex(currsha1));
		/* Nothing to do? */
		if (!memcmp(oldsha1, sha1, 20))
			exit(0);
	}
	path = strdup(path);
	lockpath = mkpath("%s.lock", path);

	fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666);
	if (fd < 0)
		die("Unable to create %s", lockpath);
	hex = sha1_to_hex(sha1);
	hex[40] = '\n';
	written = write(fd, hex, 41);
	close(fd);
	if (written != 41) {
		unlink(lockpath);
		die("Unable to write to %s", lockpath);
	}

	/*
	 * Re-read the ref after getting the lock to verify
	 */
	if (oldval && re_verify(path, oldsha1, currsha1) < 0) {
		unlink(lockpath);
		die("Ref lock failed");
	}

	/*
	 * Finally, replace the old ref with the new one
	 */
	if (rename(lockpath, path) < 0) {
		unlink(lockpath);
		die("Unable to create %s", path);
	}
	return 0;
}
back to top