Skip to content

Commit

Permalink
Merge branch 'sp/reflog'
Browse files Browse the repository at this point in the history
* sp/reflog:
  fetch.c: do not pass uninitialized lock to unlock_ref().
  Test that git-branch -l works.
  Verify git-commit provides a reflog message.
  Enable ref log creation in git checkout -b.
  Create/delete branch ref logs.
  Include ref log detail in commit, reset, etc.
  Change order of -m option to update-ref.
  Correct force_write bug in refs.c
  Change 'master@noon' syntax to 'master@{noon}'.
  Log ref updates made by fetch.
  Force writing ref if it doesn't exist.
  Added logs/ directory to repository layout.
  General ref log reading improvements.
  Fix ref log parsing so it works properly.
  Support 'master@2 hours ago' syntax
  Log ref updates to logs/refs/<ref>
  Convert update-ref to use ref_lock API.
  Improve abstraction of ref lock/write.
  • Loading branch information
Junio C Hamano committed Jun 4, 2006
2 parents 731651f + 99bd0f5 commit f0679f4
Show file tree
Hide file tree
Showing 26 changed files with 755 additions and 242 deletions.
8 changes: 8 additions & 0 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ core.preferSymlinkRefs::
This is sometimes needed to work with old scripts that
expect HEAD to be a symbolic link.

core.logAllRefUpdates::
If true, `git-update-ref` will append a line to
"$GIT_DIR/logs/<ref>" listing the new SHA1 and the date/time
of the update. If the file does not exist it will be
created automatically. This information can be used to
determine what commit was the tip of a branch "2 days ago".
This value is false by default (no logging).

core.repositoryFormatVersion::
Internal variable identifying the repository format and layout
version.
Expand Down
10 changes: 8 additions & 2 deletions Documentation/git-branch.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git-branch' [-r]
'git-branch' [-f] <branchname> [<start-point>]
'git-branch' [-l] [-f] <branchname> [<start-point>]
'git-branch' (-d | -D) <branchname>...

DESCRIPTION
Expand All @@ -23,7 +23,8 @@ If no <start-point> is given, the branch will be created with a head
equal to that of the currently checked out branch.

With a `-d` or `-D` option, `<branchname>` will be deleted. You may
specify more than one branch for deletion.
specify more than one branch for deletion. If the branch currently
has a ref log then the ref log will also be deleted.


OPTIONS
Expand All @@ -34,6 +35,11 @@ OPTIONS
-D::
Delete a branch irrespective of its index status.

-l::
Create the branch's ref log. This activates recording of
all changes to made the branch ref, enabling use of date
based sha1 expressions such as "<branchname>@{yesterday}".

-f::
Force the creation of a new branch even if it means deleting
a branch that already exists with the same name.
Expand Down
7 changes: 6 additions & 1 deletion Documentation/git-checkout.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ git-checkout - Checkout and switch to a branch
SYNOPSIS
--------
[verse]
'git-checkout' [-f] [-b <new_branch>] [-m] [<branch>]
'git-checkout' [-f] [-b <new_branch> [-l]] [-m] [<branch>]
'git-checkout' [-m] [<branch>] <paths>...

DESCRIPTION
Expand Down Expand Up @@ -40,6 +40,11 @@ OPTIONS
by gitlink:git-check-ref-format[1]. Some of these checks
may restrict the characters allowed in a branch name.

-l::
Create the new branch's ref log. This activates recording of
all changes to made the branch ref, enabling use of date
based sha1 expressions such as "<branchname>@{yesterday}".

-m::
If you have local modifications to one or more files that
are different between the current branch and the branch to
Expand Down
7 changes: 7 additions & 0 deletions Documentation/git-rev-parse.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ syntax.
happen to have both heads/master and tags/master, you can
explicitly say 'heads/master' to tell git which one you mean.

* A suffix '@' followed by a date specification enclosed in a brace
pair (e.g. '\{yesterday\}', '\{1 month 2 weeks 3 days 1 hour 1
second ago\}' or '\{1979-02-26 18:30:00\}') to specify the value
of the ref at a prior point in time. This suffix may only be
used immediately following a ref name and the ref must have an
existing log ($GIT_DIR/logs/<ref>).

* A suffix '{caret}' to a revision parameter means the first parent of
that commit object. '{caret}<n>' means the <n>th parent (i.e.
'rev{caret}'
Expand Down
28 changes: 27 additions & 1 deletion Documentation/git-update-ref.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ git-update-ref - update the object name stored in a ref safely

SYNOPSIS
--------
'git-update-ref' <ref> <newvalue> [<oldvalue>]
'git-update-ref' [-m <reason>] <ref> <newvalue> [<oldvalue>]

DESCRIPTION
-----------
Expand Down Expand Up @@ -49,6 +49,32 @@ for reading but not for writing (so we'll never write through a
ref symlink to some other tree, if you have copied a whole
archive by creating a symlink tree).

Logging Updates
---------------
If config parameter "core.logAllRefUpdates" is true or the file
"$GIT_DIR/logs/<ref>" exists then `git-update-ref` will append
a line to the log file "$GIT_DIR/logs/<ref>" (dereferencing all
symbolic refs before creating the log name) describing the change
in ref value. Log lines are formatted as:

. oldsha1 SP newsha1 SP committer LF
+
Where "oldsha1" is the 40 character hexadecimal value previously
stored in <ref>, "newsha1" is the 40 character hexadecimal value of
<newvalue> and "committer" is the committer's name, email address
and date in the standard GIT committer ident format.

Optionally with -m:

. oldsha1 SP newsha1 SP committer TAB message LF
+
Where all fields are as described above and "message" is the
value supplied to the -m option.

An update will fail (without changing <ref>) if the current user is
unable to create a new log file, append to the existing log file
or does not have committer information available.

Author
------
Written by Linus Torvalds <torvalds@osdl.org>.
Expand Down
11 changes: 11 additions & 0 deletions Documentation/repository-layout.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,14 @@ remotes::
Stores shorthands to be used to give URL and default
refnames to interact with remote repository to `git
fetch`, `git pull` and `git push` commands.

logs::
Records of changes made to refs are stored in this
directory. See the documentation on git-update-ref
for more information.

logs/refs/heads/`name`::
Records all changes made to the branch tip named `name`.

logs/refs/tags/`name`::
Records all changes made to the tag named `name`.
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ extern void rollback_index_file(struct cache_file *);
extern int trust_executable_bit;
extern int assume_unchanged;
extern int prefer_symlink_refs;
extern int log_all_ref_updates;
extern int warn_ambiguous_refs;
extern int diff_rename_limit_default;
extern int shared_repository;
Expand Down
5 changes: 5 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ int git_default_config(const char *var, const char *value)
return 0;
}

if (!strcmp(var, "core.logallrefupdates")) {
log_all_ref_updates = git_config_bool(var, value);
return 0;
}

if (!strcmp(var, "core.warnambiguousrefs")) {
warn_ambiguous_refs = git_config_bool(var, value);
return 0;
Expand Down
1 change: 1 addition & 0 deletions environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ char git_default_name[MAX_GITNAME];
int trust_executable_bit = 1;
int assume_unchanged = 0;
int prefer_symlink_refs = 0;
int log_all_ref_updates = 0;
int warn_ambiguous_refs = 1;
int repository_format_version = 0;
char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
Expand Down
45 changes: 37 additions & 8 deletions fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "refs.h"

const char *write_ref = NULL;
const char *write_ref_log_details = NULL;

int get_tree = 0;
int get_history = 0;
Expand Down Expand Up @@ -202,23 +203,51 @@ static int mark_complete(const char *path, const unsigned char *sha1)

int pull(char *target)
{
struct ref_lock *lock = NULL;
unsigned char sha1[20];
char *msg;
int ret;

save_commit_buffer = 0;
track_object_refs = 0;
if (write_ref) {
lock = lock_ref_sha1(write_ref, NULL, 0);
if (!lock) {
error("Can't lock ref %s", write_ref);
return -1;
}
}

if (!get_recover)
for_each_ref(mark_complete);

if (interpret_target(target, sha1))
return error("Could not interpret %s as something to pull",
target);
if (process(lookup_unknown_object(sha1)))
if (interpret_target(target, sha1)) {
error("Could not interpret %s as something to pull", target);
if (lock)
unlock_ref(lock);
return -1;
if (loop())
}
if (process(lookup_unknown_object(sha1))) {
if (lock)
unlock_ref(lock);
return -1;

if (write_ref)
write_ref_sha1_unlocked(write_ref, sha1);
}
if (loop()) {
if (lock)
unlock_ref(lock);
return -1;
}

if (write_ref) {
if (write_ref_log_details) {
msg = xmalloc(strlen(write_ref_log_details) + 12);
sprintf(msg, "fetch from %s", write_ref_log_details);
} else
msg = NULL;
ret = write_ref_sha1(lock, sha1, msg ? msg : "fetch (unknown)");
if (msg)
free(msg);
return ret;
}
return 0;
}
3 changes: 3 additions & 0 deletions fetch.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ extern int fetch_ref(char *ref, unsigned char *sha1);
/* If set, the ref filename to write the target value to. */
extern const char *write_ref;

/* If set additional text will appear in the ref log. */
extern const char *write_ref_log_details;

/* Set to fetch the target tree. */
extern int get_tree;

Expand Down
2 changes: 1 addition & 1 deletion git-am.sh
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ do
parent=$(git-rev-parse --verify HEAD) &&
commit=$(git-commit-tree $tree -p $parent <"$dotest/final-commit") &&
echo Committed: $commit &&
git-update-ref HEAD $commit $parent ||
git-update-ref -m "am: $SUBJECT" HEAD $commit $parent ||
stop_here $this

if test -x "$GIT_DIR"/hooks/post-applypatch
Expand Down
2 changes: 1 addition & 1 deletion git-applypatch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ echo Wrote tree $tree
parent=$(git-rev-parse --verify HEAD) &&
commit=$(git-commit-tree $tree -p $parent <"$final") || exit 1
echo Committed: $commit
git-update-ref HEAD $commit $parent || exit
git-update-ref -m "applypatch: $SUBJECT" HEAD $commit $parent || exit

if test -x "$GIT_DIR"/hooks/post-applypatch
then
Expand Down
14 changes: 12 additions & 2 deletions git-branch.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

USAGE='[(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r'
USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r'
LONG_USAGE='If no arguments, show available branches and mark current branch with a star.
If one argument, create a new branch <branchname> based off of current HEAD.
If two arguments, create a new branch <branchname> based off of <start-point>.'
Expand Down Expand Up @@ -42,6 +42,7 @@ If you are sure you want to delete it, run 'git branch -D $branch_name'."
esac
;;
esac
rm -f "$GIT_DIR/logs/refs/heads/$branch_name"
rm -f "$GIT_DIR/refs/heads/$branch_name"
echo "Deleted branch $branch_name."
done
Expand All @@ -55,6 +56,7 @@ ls_remote_branches () {
}

force=
create_log=
while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac
do
case "$1" in
Expand All @@ -69,6 +71,9 @@ do
-f)
force="$1"
;;
-l)
create_log="yes"
;;
--)
shift
break
Expand Down Expand Up @@ -117,4 +122,9 @@ then
die "cannot force-update the current branch."
fi
fi
git update-ref "refs/heads/$branchname" $rev
if test "$create_log" = 'yes'
then
mkdir -p $(dirname "$GIT_DIR/logs/refs/heads/$branchname")
touch "$GIT_DIR/logs/refs/heads/$branchname"
fi
git update-ref -m "branch: Created from $head" "refs/heads/$branchname" $rev
19 changes: 15 additions & 4 deletions git-checkout.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ SUBDIRECTORY_OK=Sometimes
. git-sh-setup

old=$(git-rev-parse HEAD)
old_name=HEAD
new=
new_name=
force=
branch=
newbranch=
newbranch_log=
merge=
while [ "$#" != "0" ]; do
arg="$1"
Expand All @@ -24,6 +27,9 @@ while [ "$#" != "0" ]; do
git-check-ref-format "heads/$newbranch" ||
die "git checkout: we do not like '$newbranch' as a branch name."
;;
"-l")
newbranch_log=1
;;
"-f")
force=1
;;
Expand All @@ -44,16 +50,19 @@ while [ "$#" != "0" ]; do
exit 1
fi
new="$rev"
new_name="$arg^0"
if [ -f "$GIT_DIR/refs/heads/$arg" ]; then
branch="$arg"
fi
elif rev=$(git-rev-parse --verify "$arg^{tree}" 2>/dev/null)
then
# checking out selected paths from a tree-ish.
new="$rev"
new_name="$arg^{tree}"
branch=
else
new=
new_name=
branch=
set x "$arg" "$@"
shift
Expand Down Expand Up @@ -114,7 +123,7 @@ then
cd "$cdup"
fi

[ -z "$new" ] && new=$old
[ -z "$new" ] && new=$old && new_name="$old_name"

# If we don't have an old branch that we're switching to,
# and we don't have a new branch name for the target we
Expand Down Expand Up @@ -187,9 +196,11 @@ fi
#
if [ "$?" -eq 0 ]; then
if [ "$newbranch" ]; then
leading=`expr "refs/heads/$newbranch" : '\(.*\)/'` &&
mkdir -p "$GIT_DIR/$leading" &&
echo $new >"$GIT_DIR/refs/heads/$newbranch" || exit
if [ "$newbranch_log" ]; then
mkdir -p $(dirname "$GIT_DIR/logs/refs/heads/$newbranch")
touch "$GIT_DIR/logs/refs/heads/$newbranch"
fi
git-update-ref -m "checkout: Created from $new_name" "refs/heads/$newbranch" $new || exit
branch="$newbranch"
fi
[ "$branch" ] &&
Expand Down
3 changes: 2 additions & 1 deletion git-commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,8 @@ then
rm -f "$TMP_INDEX"
fi &&
commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) &&
git-update-ref HEAD $commit $current &&
rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
git-update-ref -m "commit: $rlogm" HEAD $commit $current &&
rm -f -- "$GIT_DIR/MERGE_HEAD" &&
if test -f "$NEXT_INDEX"
then
Expand Down
2 changes: 1 addition & 1 deletion git-reset.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ then
else
rm -f "$GIT_DIR/ORIG_HEAD"
fi
git-update-ref HEAD "$rev"
git-update-ref -m "reset $reset_type $@" HEAD "$rev"

case "$reset_type" in
--hard )
Expand Down
Loading

0 comments on commit f0679f4

Please sign in to comment.