* [PATCH] [PARSECVS] add an install target to Makefile
From: Martin Atukunda @ 2006-05-19 11:34 UTC (permalink / raw)
To: git
---
573c3afa5674024df0fd5722404f215c54977699
Makefile | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
573c3afa5674024df0fd5722404f215c54977699
diff --git a/Makefile b/Makefile
index 4ca6ffd..50fa551 100644
--- a/Makefile
+++ b/Makefile
@@ -24,3 +24,5 @@ y.tab.h: gram.c
clean:
rm -f $(OBJS) y.tab.h gram.c lex.c parsecvs
+install:
+ cp parsecvs edit-change-log ${HOME}/bin
--
1.3.3.gff62
^ permalink raw reply related
* Re: [PATCH 0/5] More ref logging
From: Sean @ 2006-05-19 11:16 UTC (permalink / raw)
To: Shawn Pearce; +Cc: junkio, git
In-Reply-To: <20060519091456.GH22257@spearce.org>
On Fri, 19 May 2006 05:14:56 -0400
Shawn Pearce <spearce@spearce.org> wrote:
> * [PATCH 5/5] Enable ref log creation in git checkout -b.
>
> Fix git checkout -b to behave like git branch.
It seems that the ref log is a new way of tagging commits with some
extra meta data. Conceptually this seems very close to what git tags
already do. So... what about using regular git tags rather than
creating a ref log? All the regular git-rev-list tools could be
used to query the tags and prune would delete them automatically etc.
Just a thought, feel free to ignore it :o)
Sean
^ permalink raw reply
* [PATCH] Builtin git-init-db
From: Timo Hirvonen @ 2006-05-19 10:03 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
Basically this just renames init-db.c to builtin-init-db.c and makes
some strings const.
Signed-off-by: Timo Hirvonen <tihirvon@gmail.com>
---
ea0920d755efa314e2be014e2a1eccda89d8f850
Makefile | 13 ++++++-------
init-db.c => builtin-init-db.c | 12 +++++++-----
builtin.h | 1 +
git.c | 1 +
4 files changed, 15 insertions(+), 12 deletions(-)
rename init-db.c => builtin-init-db.c (96%)
ea0920d755efa314e2be014e2a1eccda89d8f850
diff --git a/Makefile b/Makefile
index 2149fb8..a4e9643 100644
--- a/Makefile
+++ b/Makefile
@@ -154,7 +154,7 @@ PROGRAMS = \
git-convert-objects$X git-diff-files$X \
git-diff-index$X git-diff-stages$X \
git-diff-tree$X git-fetch-pack$X git-fsck-objects$X \
- git-hash-object$X git-index-pack$X git-init-db$X git-local-fetch$X \
+ git-hash-object$X git-index-pack$X git-local-fetch$X \
git-ls-files$X git-ls-tree$X git-mailinfo$X git-merge-base$X \
git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
git-peek-remote$X git-prune-packed$X git-read-tree$X \
@@ -170,7 +170,8 @@ PROGRAMS = \
BUILT_INS = git-log$X git-whatchanged$X git-show$X \
git-count-objects$X git-diff$X git-push$X \
- git-grep$X git-rev-list$X git-check-ref-format$X
+ git-grep$X git-rev-list$X git-check-ref-format$X \
+ git-init-db$X
# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -218,7 +219,8 @@ LIB_OBJS = \
BUILTIN_OBJS = \
builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
- builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o
+ builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o \
+ builtin-init-db.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
@@ -473,6 +475,7 @@ strip: $(PROGRAMS) git$X
git$X: git.c common-cmds.h $(BUILTIN_OBJS) $(GITLIBS)
$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
+ -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' \
$(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
@@ -565,10 +568,6 @@ git-http-push$X: revision.o http.o http-
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
-init-db.o: init-db.c
- $(CC) -c $(ALL_CFLAGS) \
- -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c
-
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
$(DIFF_OBJS): diffcore.h
diff --git a/init-db.c b/builtin-init-db.c
similarity index 96%
rename from init-db.c
rename to builtin-init-db.c
index ff29496..2a1384c 100644
--- a/init-db.c
+++ b/builtin-init-db.c
@@ -4,6 +4,7 @@
* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
+#include "builtin.h"
#ifndef DEFAULT_GIT_TEMPLATE_DIR
#define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates/"
@@ -116,7 +117,7 @@ static void copy_templates_1(char *path,
}
}
-static void copy_templates(const char *git_dir, int len, char *template_dir)
+static void copy_templates(const char *git_dir, int len, const char *template_dir)
{
char path[PATH_MAX];
char template_path[PATH_MAX];
@@ -163,7 +164,7 @@ static void copy_templates(const char *g
closedir(dir);
}
-static void create_default_files(const char *git_dir, char *template_path)
+static void create_default_files(const char *git_dir, const char *template_path)
{
unsigned len = strlen(git_dir);
static char path[PATH_MAX];
@@ -234,15 +235,16 @@ static const char init_db_usage[] =
* On the other hand, it might just make lookup slower and messier. You
* be the judge. The default case is to have one DB per managed directory.
*/
-int main(int argc, char **argv)
+int cmd_init_db(int argc, const char **argv, char **envp)
{
const char *git_dir;
const char *sha1_dir;
- char *path, *template_dir = NULL;
+ const char *template_dir = NULL;
+ char *path;
int len, i;
for (i = 1; i < argc; i++, argv++) {
- char *arg = argv[1];
+ const char *arg = argv[1];
if (!strncmp(arg, "--template=", 11))
template_dir = arg+11;
else if (!strcmp(arg, "--shared"))
diff --git a/builtin.h b/builtin.h
index ff559de..6054126 100644
--- a/builtin.h
+++ b/builtin.h
@@ -26,5 +26,6 @@ extern int cmd_push(int argc, const char
extern int cmd_grep(int argc, const char **argv, char **envp);
extern int cmd_rev_list(int argc, const char **argv, char **envp);
extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
+extern int cmd_init_db(int argc, const char **argv, char **envp);
#endif
diff --git a/git.c b/git.c
index d0650bb..3216d31 100644
--- a/git.c
+++ b/git.c
@@ -51,6 +51,7 @@ static void handle_internal_command(int
{ "diff", cmd_diff },
{ "grep", cmd_grep },
{ "rev-list", cmd_rev_list },
+ { "init-db", cmd_init_db },
{ "check-ref-format", cmd_check_ref_format }
};
int i;
--
1.3.3.gff62-dirty
^ permalink raw reply related
* Re: [PATCH] Implement git-quiltimport (take 2)
From: Eric W. Biederman @ 2006-05-19 9:55 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy7x09qet.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
>> For Andrews tree before I play anymore with technical solutions I
>> need to talk to Andrew and see if we can improve the situation
>> upstream. Possibly with a quilt-audit script that finds problem
>> patches.
>
> Yes, that sounds very sensible.
Anyway I had a first pass conversation with Andrew and it looks like
he will start addressing the problem patches there. So things
should be resolvable.
The final piece on my agenda for getting the proper authors from
the -mm tree is coping with Andrew's git patches. They have enough
information to determine the Author but they are really several
different patches. Ideally I will be able recognize they are
performing a pull from a git repository and get the same results.
Otherwise some other trick will be necessary.
Eric
^ permalink raw reply
* Re: [RFD] Git glossary: 'branch' and 'head' description
From: Shawn Pearce @ 2006-05-19 9:21 UTC (permalink / raw)
To: David Kågedal; +Cc: git
In-Reply-To: <87y7wyv72m.fsf@morpheus.hq.vtech>
David K?gedal <davidk@lysator.liu.se> wrote:
> I noticed that some of this seems to be changing slightly with the
> introduction of branch logs, but I don't know how those are supposed
> to be used yet.
$ git commit -a
$ git pull . some/other-tag
# go to lunch
$ git pull . some/bad-stuff
$ git commit -a
# go home
$ test...
# realize this is all bad
$ git reset --hard "master@{yesterday}"
:-)
Its really only useful for recording the history of your ref's state,
so you can 'undo' a bad merge that you might have done a few days
ago but not realized was bad until now.
--
Shawn.
^ permalink raw reply
* [PATCH 5/5] Enable ref log creation in git checkout -b.
From: Shawn Pearce @ 2006-05-19 9:17 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
Switch git checkout -b to use git-update-ref rather than echo and
a shell I/O redirection. This is more in line with typical GIT
commands and allows -b to be logged according to the normal ref
logging rules.
Added -l option to allow users to create the ref log at the same
time as creating a branch.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
Documentation/git-checkout.txt | 7 ++++++-
git-checkout.sh | 19 +++++++++++++++----
2 files changed, 21 insertions(+), 5 deletions(-)
46409624159100ad958c3168b13e384168c12713
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 0951289..0643943 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -8,7 +8,7 @@ git-checkout - Checkout and switch to a
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
@@ -37,6 +37,11 @@ OPTIONS
-b::
Create a new branch and start it at <branch>.
+-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
diff --git a/git-checkout.sh b/git-checkout.sh
index a11c939..360aabf 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -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"
@@ -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
;;
@@ -44,6 +50,7 @@ while [ "$#" != "0" ]; do
exit 1
fi
new="$rev"
+ new_name="$arg^0"
if [ -f "$GIT_DIR/refs/heads/$arg" ]; then
branch="$arg"
fi
@@ -51,9 +58,11 @@ while [ "$#" != "0" ]; do
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
@@ -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
@@ -187,9 +196,11 @@ # be based on them, since we re-set the
#
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/$branchname")
+ touch "$GIT_DIR/logs/refs/heads/$branchname"
+ fi
+ git-update-ref -m "checkout: Created from $new_name" "refs/heads/$newbranch" $new || exit
branch="$newbranch"
fi
[ "$branch" ] &&
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 4/5] Create/delete branch ref logs.
From: Shawn Pearce @ 2006-05-19 9:16 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
When crating a new branch offer '-l' as a way for the user to
quickly enable ref logging for the new branch.
When deleting a branch also delete its ref log.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
This was discussed on #git earlier today and was thought to be a
useful feature. :-)
Documentation/git-branch.txt | 10 ++++++++--
git-branch.sh | 12 +++++++++++-
2 files changed, 19 insertions(+), 3 deletions(-)
e4fb59c8b73009e3bcae71bfb7edd7de2c648117
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 72fb2f8..a7bec3c 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -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
@@ -23,7 +23,8 @@ If no <start-point> is given, the branch
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
@@ -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.
diff --git a/git-branch.sh b/git-branch.sh
index d1e3730..e0501ec 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -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>.'
@@ -42,6 +42,7 @@ If you are sure you want to delete it, r
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
@@ -55,6 +56,7 @@ ls_remote_branches () {
}
force=
+create_log=
while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac
do
case "$1" in
@@ -69,6 +71,9 @@ do
-f)
force="$1"
;;
+ -l)
+ create_log="yes"
+ ;;
--)
shift
break
@@ -117,4 +122,9 @@ then
die "cannot force-update the current branch."
fi
fi
+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
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 3/5] Include ref log detail in commit, reset, etc.
From: Shawn Pearce @ 2006-05-19 9:16 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
When updating a ref at the direction of the user include a reason why
head was changed as part of the ref log (assuming it was enabled).
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
git-am.sh | 2 +-
git-applypatch.sh | 2 +-
git-branch.sh | 2 +-
git-commit.sh | 3 ++-
git-reset.sh | 2 +-
5 files changed, 6 insertions(+), 5 deletions(-)
2a83d6835922e222caadf03b25ebc72e773291ff
diff --git a/git-am.sh b/git-am.sh
index 97ec2d0..4232e27 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -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
diff --git a/git-applypatch.sh b/git-applypatch.sh
index 12cab1e..e4b0947 100755
--- a/git-applypatch.sh
+++ b/git-applypatch.sh
@@ -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
diff --git a/git-branch.sh b/git-branch.sh
index 134e68c..d1e3730 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -117,4 +117,4 @@ then
die "cannot force-update the current branch."
fi
fi
-git update-ref "refs/heads/$branchname" $rev
+git update-ref -m "branch: Created from $head" "refs/heads/$branchname" $rev
diff --git a/git-commit.sh b/git-commit.sh
index 6ef1a9d..a4b0a90 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -676,7 +676,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
diff --git a/git-reset.sh b/git-reset.sh
index 0ee3e3e..296f3b7 100755
--- a/git-reset.sh
+++ b/git-reset.sh
@@ -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 )
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 2/5] Change order of -m option to update-ref.
From: Shawn Pearce @ 2006-05-19 9:15 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
The actual position doesn't matter but most people prefer to see
options appear before the arguments.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
Documentation/git-update-ref.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
75d5d46e9d911ab657af3c2eef9b585ac6a36b18
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index dfbd886..e062030 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -7,7 +7,7 @@ git-update-ref - update the object name
SYNOPSIS
--------
-'git-update-ref' <ref> <newvalue> [<oldvalue>] [-m <reason>]
+'git-update-ref' [-m <reason>] <ref> <newvalue> [<oldvalue>]
DESCRIPTION
-----------
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 1/5] Correct force_write bug in refs.c
From: Shawn Pearce @ 2006-05-19 9:15 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
My earlier attempt at forcing a write for non-existant refs worked;
it forced a write for pretty much all refs. This corrects the
condition to only force a write for refs which don't exist yet.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
refs.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
5ee16115982c52fa9b8fa15c14b234608a8b935d
diff --git a/refs.c b/refs.c
index d3ddc82..eeb1196 100644
--- a/refs.c
+++ b/refs.c
@@ -305,7 +305,7 @@ static struct ref_lock* lock_ref_sha1_ba
lock->ref_file = strdup(path);
lock->lock_file = strdup(mkpath("%s.lock", lock->ref_file));
lock->log_file = strdup(git_path("logs/%s", lock->ref_file + plen));
- lock->force_write = !lstat(lock->ref_file, &st) || errno == ENOENT;
+ lock->force_write = lstat(lock->ref_file, &st) && errno == ENOENT;
if (safe_create_leading_directories(lock->lock_file))
die("unable to create directory for %s", lock->lock_file);
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 0/5] More ref logging
From: Shawn Pearce @ 2006-05-19 9:14 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
These are on top of the other five I just sent:
* [PATCH 1/5] Correct force_write bug in refs.c
Yea there was a bug in the last bug fix. Now we
really don't write the ref unless we need to.
* [PATCH 2/5] Change order of -m option to update-ref.
Minor documentation nit noticed by Junio.
* [PATCH 3/5] Include ref log detail in commit, reset, etc.
Enhance some core tools to use the new '-m' switch with
update-ref. Trivial but requires the new update-ref.
* [PATCH 4/5] Create/delete branch ref logs.
This was discussed on #git earlier this morning.
Automatically create the ref log if -l is given when creating
a branch and delete the log when deleting the branch.
* [PATCH 5/5] Enable ref log creation in git checkout -b.
Fix git checkout -b to behave like git branch.
--
Shawn.
^ permalink raw reply
* Re: [PATCH 4/5] Log ref updates made by fetch.
From: Shawn Pearce @ 2006-05-19 8:03 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vodxuih2d.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> Shawn Pearce <spearce@spearce.org> writes:
>
> > diff --git a/refs.c b/refs.c
> > index 31cf276..d3ddc82 100644
> > --- a/refs.c
> > +++ b/refs.c
> > @@ -142,6 +142,8 @@ static int do_for_each_ref(const char *b
> > namelen = strlen(de->d_name);
> > if (namelen > 255)
> > continue;
> > + if (namelen>5 && !strcmp(de->d_name+namelen-5,".lock"))
> > + continue;
> > memcpy(path + baselen, de->d_name, namelen+1);
> > if (stat(git_path("%s", path), &st) < 0)
> > continue;
>
> Now this got me worried. Until now I did not realize that we
> are clobbering refnames that ends with ".lock" if another ref
> with the name without ".locK" is updated. Because we do not
> forbid a name that ends with ".lock" to be used as a refname,
> this is an accident waiting to happen.
>
> Not your fault, though. It was like this ever since the initial
> version of refs.c was accepted by Linus.
>
> We could do one of two things: officially forbid any refname
> that ends with ".lock", or fix the lockfile naming convention.
>
> Nobody should be relying on what the actual lockfile-to-be-
> renamed-to-become-the-real-file is called. I suspect we would
> want to fix refs.c::ref_lock_file_name() to use a name that
> would never be used as a refname.
>
> We could make it begin with ".", so the lock file for the master
> ".git/refs/heads/master" would become ".git/refs/heads/.master",
> for example. That way, we cannot clobber a valid unrelated ref
> (".master" is not a valid ref name), and as an added bonus, you
> do not even have to have the above hunk.
Not a bad idea. I found this bug because fetch.c was trying to
work on the bob.lock while it was fetching "heads/bob". Which
didn't make sense to me, so I put this skip thing in...
I'd want to get all of the "lockers" move to using the common
lock code before changing the lock name to ".master" (for example)
but yes that's a good idea.
--
Shawn.
^ permalink raw reply
* Re: [PATCH 4/5] Log ref updates made by fetch.
From: Junio C Hamano @ 2006-05-19 7:56 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <20060519072926.GE22257@spearce.org>
Shawn Pearce <spearce@spearce.org> writes:
> diff --git a/refs.c b/refs.c
> index 31cf276..d3ddc82 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -142,6 +142,8 @@ static int do_for_each_ref(const char *b
> namelen = strlen(de->d_name);
> if (namelen > 255)
> continue;
> + if (namelen>5 && !strcmp(de->d_name+namelen-5,".lock"))
> + continue;
> memcpy(path + baselen, de->d_name, namelen+1);
> if (stat(git_path("%s", path), &st) < 0)
> continue;
Now this got me worried. Until now I did not realize that we
are clobbering refnames that ends with ".lock" if another ref
with the name without ".locK" is updated. Because we do not
forbid a name that ends with ".lock" to be used as a refname,
this is an accident waiting to happen.
Not your fault, though. It was like this ever since the initial
version of refs.c was accepted by Linus.
We could do one of two things: officially forbid any refname
that ends with ".lock", or fix the lockfile naming convention.
Nobody should be relying on what the actual lockfile-to-be-
renamed-to-become-the-real-file is called. I suspect we would
want to fix refs.c::ref_lock_file_name() to use a name that
would never be used as a refname.
We could make it begin with ".", so the lock file for the master
".git/refs/heads/master" would become ".git/refs/heads/.master",
for example. That way, we cannot clobber a valid unrelated ref
(".master" is not a valid ref name), and as an added bonus, you
do not even have to have the above hunk.
Hmm?
^ permalink raw reply
* Re: [RFD] Git glossary: 'branch' and 'head' description
From: David Kågedal @ 2006-05-19 6:53 UTC (permalink / raw)
To: git
In-Reply-To: <e4f1ta$e07$1@sea.gmane.org>
Jakub Narebski <jnareb@gmail.com> writes:
> In #git channel somebody asked about 'branches' and 'heads' and was referred
> to the glossary. I had taken then a look at appropriate glossary entries.
>
> In 'Documentation/glossary.txt' we have:
> ----
> branch::
> A non-cyclical graph of revisions, i.e. the complete history of
> a particular revision, which is called the branch head. The
> branch heads are stored in `$GIT_DIR/refs/heads/`.
[...]
> It is just me or the glossary entry for `branch` is unnecessary
> complicated?
>
> Let's take a look at other definitions:
>
> In software engineering, 'branch' is a separate line of development, which
> among others allows development on a project to diverge in two directions,
> such as a stable and a development version. (WikiPedia:Branch)
>
> In the CVS team development environment, a separate line of development
> where changes can be isolated. When a programmer changes files on
> a branch, those changes do not appear on the main trunk
> or other branches. (cvs.info)
>
> So from the user's point of view, 'branch' is simply _named line of
> development_. Refer to topic and tracking branches.
But the definition of 'branch' in git is quite different from the
definition in CVS or many other systems. It CVS, each revision
(commit) belongs to a branch, and the branch is a linear sequence of
revisions, not a full DAG. In git, a commit doesn't really "belong"
in any specific branch.
So, while it makes sense to describe branches as "lines of
development" in general terms, it is also important to note the
specific meaning of 'branch' in the context of git; i.e. as the
history of a single head commit.
I noticed that some of this seems to be changing slightly with the
introduction of branch logs, but I don't know how those are supposed
to be used yet.
--
David Kågedal
^ permalink raw reply
* [PATCH 5/5] Change 'master@noon' syntax to 'master@{noon}'.
From: Shawn Pearce @ 2006-05-19 7:29 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
Its ambiguous to parse "master@2006-05-17 18:30:foo" when foo is
meant as a file name and ":30" is meant as 30 minutes past 6 pm.
Therefore all date specifications in a sha1 expression must now
appear within brackets and the ':' splitter used for the path name
in a sha1 expression ignores ':' appearing within brackets.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
Documentation/git-rev-parse.txt | 11 ++++----
sha1_name.c | 27 ++++++++++++-------
t/t1400-update-ref.sh | 55 ++++++++++++++++++++++++++++-----------
3 files changed, 62 insertions(+), 31 deletions(-)
eea4ae092b92129ef09e9caf6f6f2b523cd193cb
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index df308c3..b894694 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -124,11 +124,12 @@ 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 such as 'yesterday'
- (24 hours ago) or '1 month 2 weeks 3 days 1 hour 1 second ago'
- 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 '@' 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.
diff --git a/sha1_name.c b/sha1_name.c
index 4376cb3..fbbde1c 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -249,7 +249,7 @@ static int get_sha1_basic(const char *st
static const char *warning = "warning: refname '%.*s' is ambiguous.\n";
const char **p, *pathname;
char *real_path = NULL;
- int refs_found = 0, at_mark;
+ int refs_found = 0, am;
unsigned long at_time = (unsigned long)-1;
unsigned char *this_result;
unsigned char sha1_from_ref[20];
@@ -257,16 +257,16 @@ static int get_sha1_basic(const char *st
if (len == 40 && !get_sha1_hex(str, sha1))
return 0;
- /* At a given period of time? "@2 hours ago" */
- for (at_mark = 1; at_mark < len; at_mark++) {
- if (str[at_mark] == '@') {
- int date_len = len - at_mark - 1;
+ /* At a given period of time? "@{2 hours ago}" */
+ for (am = 1; am < len - 1; am++) {
+ if (str[am] == '@' && str[am+1] == '{' && str[len-1] == '}') {
+ int date_len = len - am - 3;
char *date_spec = xmalloc(date_len + 1);
- strncpy(date_spec, str + at_mark + 1, date_len);
+ strncpy(date_spec, str + am + 2, date_len);
date_spec[date_len] = 0;
at_time = approxidate(date_spec);
free(date_spec);
- len = at_mark;
+ len = am;
break;
}
}
@@ -482,7 +482,7 @@ static int get_sha1_1(const char *name,
*/
int get_sha1(const char *name, unsigned char *sha1)
{
- int ret;
+ int ret, bracket_depth;
unsigned unused;
int namelen = strlen(name);
const char *cp;
@@ -528,8 +528,15 @@ int get_sha1(const char *name, unsigned
}
return -1;
}
- cp = strchr(name, ':');
- if (cp) {
+ for (cp = name, bracket_depth = 0; *cp; cp++) {
+ if (*cp == '{')
+ bracket_depth++;
+ else if (bracket_depth && *cp == '}')
+ bracket_depth--;
+ else if (!bracket_depth && *cp == ':')
+ break;
+ }
+ if (*cp == ':') {
unsigned char tree_sha1[20];
if (!get_sha1_1(name, cp-name, tree_sha1))
return get_tree_entry(tree_sha1, cp+1, sha1,
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 7858d86..f6b076b 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -125,52 +125,75 @@ ed="Thu, 26 May 2005 18:32:00 -0500"
gd="Thu, 26 May 2005 18:33:00 -0500"
ld="Thu, 26 May 2005 18:43:00 -0500"
test_expect_success \
- 'Query "master@May 25 2005" (before history)' \
+ 'Query "master@{May 25 2005}" (before history)' \
'rm -f o e
- git-rev-parse --verify "master@May 25 2005" >o 2>e &&
+ git-rev-parse --verify "master@{May 25 2005}" >o 2>e &&
test $C = $(cat o) &&
test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
test_expect_success \
- "Query master@2005-05-25 (before history)" \
+ "Query master@{2005-05-25} (before history)" \
'rm -f o e
- git-rev-parse --verify master@2005-05-25 >o 2>e &&
+ git-rev-parse --verify master@{2005-05-25} >o 2>e &&
test $C = $(cat o) &&
echo test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
test_expect_success \
- 'Query "master@May 26 2005 23:31:59" (1 second before history)' \
+ 'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \
'rm -f o e
- git-rev-parse --verify "master@May 26 2005 23:31:59" >o 2>e &&
+ git-rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e &&
test $C = $(cat o) &&
test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
test_expect_success \
- 'Query "master@May 26 2005 23:32:00" (exactly history start)' \
+ 'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \
'rm -f o e
- git-rev-parse --verify "master@May 26 2005 23:32:00" >o 2>e &&
+ git-rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e &&
test $A = $(cat o) &&
test "" = "$(cat e)"'
test_expect_success \
- 'Query "master@2005-05-26 23:33:01" (middle of history with gap)' \
+ 'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' \
'rm -f o e
- git-rev-parse --verify "master@2005-05-26 23:33:01" >o 2>e &&
+ git-rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e &&
test $B = $(cat o) &&
test "warning: Log .git/logs/$m has gap after $gd." = "$(cat e)"'
test_expect_success \
- 'Query "master@2005-05-26 23:33:01" (middle of history)' \
+ 'Query "master@{2005-05-26 23:38:00}" (middle of history)' \
'rm -f o e
- git-rev-parse --verify "master@2005-05-26 23:38:00" >o 2>e &&
+ git-rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e &&
test $Z = $(cat o) &&
test "" = "$(cat e)"'
test_expect_success \
- 'Query "master@2005-05-26 23:43:00" (exact end of history)' \
+ 'Query "master@{2005-05-26 23:43:00}" (exact end of history)' \
'rm -f o e
- git-rev-parse --verify "master@2005-05-26 23:43:00" >o 2>e &&
+ git-rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e &&
test $E = $(cat o) &&
test "" = "$(cat e)"'
test_expect_success \
- 'Query "master@2005-05-28" (past end of history)' \
+ 'Query "master@{2005-05-28}" (past end of history)' \
'rm -f o e
- git-rev-parse --verify "master@2005-05-28" >o 2>e &&
+ git-rev-parse --verify "master@{2005-05-28}" >o 2>e &&
test $D = $(cat o) &&
test "warning: Log .git/logs/$m unexpectedly ended on $ld." = "$(cat e)"'
+
+rm -f .git/$m .git/logs/$m expect
+
+test_expect_success \
+ 'creating initial files' \
+ 'cp ../../COPYING COPYING &&
+ git-add COPYING &&
+ GIT_COMMITTER_DATE="2005-05-26 23:30" git-commit -m add -a &&
+ cp ../../Makefile COPYING &&
+ GIT_COMMITTER_DATE="2005-05-26 23:41" git-commit -m change -a'
+
+test_expect_success \
+ 'git-cat-file blob master:COPYING (expect Makefile)' \
+ 'git-cat-file blob master:COPYING | diff - ../../Makefile'
+test_expect_success \
+ 'git-cat-file blob master@{2005-05-26 23:30}:COPYING (expect COPYING)' \
+ 'git-cat-file blob "master@{2005-05-26 23:30}:COPYING" \
+ | diff - ../../COPYING'
+test_expect_success \
+ 'git-cat-file blob master@{2005-05-26 23:42}:COPYING (expect Makefile)' \
+ 'git-cat-file blob "master@{2005-05-26 23:42}:COPYING" \
+ | diff - ../../Makefile'
+
test_done
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 4/5] Log ref updates made by fetch.
From: Shawn Pearce @ 2006-05-19 7:29 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
If a ref is changed by http-fetch, local-fetch or ssh-fetch
record the change and the remote URL/name in the log for the ref.
This requires loading the config file to check logAllRefUpdates.
Also fixed a bug in the ref lock generation; the log file name was
not being produced right due to a bad prefix length.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
fetch.c | 17 +++++++++++++++--
fetch.h | 3 +++
http-fetch.c | 2 ++
local-fetch.c | 2 ++
refs.c | 5 +++--
ssh-fetch.c | 2 ++
6 files changed, 27 insertions(+), 4 deletions(-)
b929e2a5a8f80c8635cf3c54a6d766902cf87434
diff --git a/fetch.c b/fetch.c
index 8bdaacb..fd57684 100644
--- a/fetch.c
+++ b/fetch.c
@@ -8,6 +8,7 @@ #include "blob.h"
#include "refs.h"
const char *write_ref = NULL;
+const char *write_ref_log_details = NULL;
const unsigned char *current_ref = NULL;
@@ -206,13 +207,17 @@ int pull(char *target)
{
struct ref_lock *lock;
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, current_ref, 1);
- if (!lock)
+ if (!lock) {
+ error("Can't lock ref %s", write_ref);
return -1;
+ }
}
if (!get_recover) {
@@ -234,7 +239,15 @@ int pull(char *target)
}
if (write_ref) {
- return write_ref_sha1(lock, sha1, "git fetch");
+ 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;
}
diff --git a/fetch.h b/fetch.h
index 9837a3d..0011548 100644
--- a/fetch.h
+++ b/fetch.h
@@ -25,6 +25,9 @@ extern int fetch_ref(char *ref, unsigned
/* 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;
+
/* If set, the hash that the current value of write_ref must be. */
extern const unsigned char *current_ref;
diff --git a/http-fetch.c b/http-fetch.c
index 861644b..cc7bd1f 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -1223,6 +1223,7 @@ int main(int argc, char **argv)
int rc = 0;
setup_git_directory();
+ git_config(git_default_config);
while (arg < argc && argv[arg][0] == '-') {
if (argv[arg][1] == 't') {
@@ -1249,6 +1250,7 @@ int main(int argc, char **argv)
}
commit_id = argv[arg];
url = argv[arg + 1];
+ write_ref_log_details = url;
http_init();
diff --git a/local-fetch.c b/local-fetch.c
index fa9e697..ffa4887 100644
--- a/local-fetch.c
+++ b/local-fetch.c
@@ -208,6 +208,7 @@ int main(int argc, char **argv)
int arg = 1;
setup_git_directory();
+ git_config(git_default_config);
while (arg < argc && argv[arg][0] == '-') {
if (argv[arg][1] == 't')
@@ -239,6 +240,7 @@ int main(int argc, char **argv)
usage(local_pull_usage);
commit_id = argv[arg];
path = argv[arg + 1];
+ write_ref_log_details = path;
if (pull(commit_id))
return 1;
diff --git a/refs.c b/refs.c
index 31cf276..d3ddc82 100644
--- a/refs.c
+++ b/refs.c
@@ -142,6 +142,8 @@ static int do_for_each_ref(const char *b
namelen = strlen(de->d_name);
if (namelen > 255)
continue;
+ if (namelen>5 && !strcmp(de->d_name+namelen-5,".lock"))
+ continue;
memcpy(path + baselen, de->d_name, namelen+1);
if (stat(git_path("%s", path), &st) < 0)
continue;
@@ -296,7 +298,6 @@ static struct ref_lock* lock_ref_sha1_ba
plen = strlen(path) - plen;
path = resolve_ref(path, lock->old_sha1, mustexist);
if (!path) {
- error("Can't read ref %s", path);
unlock_ref(lock);
return NULL;
}
@@ -326,7 +327,7 @@ struct ref_lock* lock_ref_sha1(const cha
if (check_ref_format(ref))
return NULL;
return lock_ref_sha1_basic(git_path("refs/%s", ref),
- strlen(ref), old_sha1, mustexist);
+ 5 + strlen(ref), old_sha1, mustexist);
}
struct ref_lock* lock_any_ref_for_update(const char *ref,
diff --git a/ssh-fetch.c b/ssh-fetch.c
index 4eb9e04..e3067b8 100644
--- a/ssh-fetch.c
+++ b/ssh-fetch.c
@@ -132,6 +132,7 @@ int main(int argc, char **argv)
if (!prog) prog = "git-ssh-upload";
setup_git_directory();
+ git_config(git_default_config);
while (arg < argc && argv[arg][0] == '-') {
if (argv[arg][1] == 't') {
@@ -158,6 +159,7 @@ int main(int argc, char **argv)
}
commit_id = argv[arg];
url = argv[arg + 1];
+ write_ref_log_details = url;
if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))
return 1;
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 3/5] Force writing ref if it doesn't exist.
From: Shawn Pearce @ 2006-05-19 7:29 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
Normally we try to skip writing a ref if its value hasn't changed
but in the special case that the ref doesn't exist but the new
value is going to be 0{40} then force writing the ref anyway.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
refs.c | 4 +++-
refs.h | 1 +
2 files changed, 4 insertions(+), 1 deletions(-)
13f3c9a2b8959da1947e21c32e58d81d32a83f3e
diff --git a/refs.c b/refs.c
index 9d37a02..31cf276 100644
--- a/refs.c
+++ b/refs.c
@@ -288,6 +288,7 @@ static struct ref_lock* lock_ref_sha1_ba
const unsigned char *old_sha1, int mustexist)
{
struct ref_lock *lock;
+ struct stat st;
lock = xcalloc(1, sizeof(struct ref_lock));
lock->lock_fd = -1;
@@ -303,6 +304,7 @@ static struct ref_lock* lock_ref_sha1_ba
lock->ref_file = strdup(path);
lock->lock_file = strdup(mkpath("%s.lock", lock->ref_file));
lock->log_file = strdup(git_path("logs/%s", lock->ref_file + plen));
+ lock->force_write = !lstat(lock->ref_file, &st) || errno == ENOENT;
if (safe_create_leading_directories(lock->lock_file))
die("unable to create directory for %s", lock->lock_file);
@@ -405,7 +407,7 @@ int write_ref_sha1(struct ref_lock *lock
if (!lock)
return -1;
- if (!memcmp(lock->old_sha1, sha1, 20)) {
+ if (!lock->force_write && !memcmp(lock->old_sha1, sha1, 20)) {
unlock_ref(lock);
return 0;
}
diff --git a/refs.h b/refs.h
index 2c854de..6c946ea 100644
--- a/refs.h
+++ b/refs.h
@@ -7,6 +7,7 @@ struct ref_lock {
char *log_file;
unsigned char old_sha1[20];
int lock_fd;
+ int force_write;
};
/*
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 2/5] Added logs/ directory to repository layout.
From: Shawn Pearce @ 2006-05-19 7:28 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
Documentation/repository-layout.txt | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
27faccbeae368625d4a11788e5cedc7b3dc23f54
diff --git a/Documentation/repository-layout.txt b/Documentation/repository-layout.txt
index 98fbe7d..b52dfdc 100644
--- a/Documentation/repository-layout.txt
+++ b/Documentation/repository-layout.txt
@@ -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.3.2.g7278
^ permalink raw reply related
* [PATCH 1/5] General ref log reading improvements.
From: Shawn Pearce @ 2006-05-19 7:28 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
Corrected the log starting time displayed in the error message
(as it was always showing the epoch due to a bad input to strtoul).
Improved the log parser so we only scan backwards towards the
'\n' from the end of the prior log; during this scan the last '>'
is remembered to improve performance (rather than scanning forward
to it).
If the log record matched is the last log record in the file only
use its new sha1 value if the date matches exactly; otherwise we
leave the passed in sha1 alone as it already contains the current
value of the ref. This way lookups of dates later than the log
end to stick with the current ref value in case the ref was updated
without logging.
If it looks like someone changed the ref without logging it and we
are going to return the sha1 which should have been valid during
the missing period then warn the user that there might be log data
missing and thus their query result may not be accurate. The check
isn't perfect as its just based on comparing the old and new sha1
values between the two log records but its better than not checking
at all.
Implemented test cases based on git-rev-parse for most of the
boundary conditions.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
refs.c | 54 +++++++++++++++++++++++++++++++----------
t/t1400-update-ref.sh | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+), 14 deletions(-)
mode change 100644 => 100755 t/t1400-update-ref.sh
54717d099405378da50cd3d4715c1e5d6d793d68
diff --git a/refs.c b/refs.c
index ae9825d..9d37a02 100644
--- a/refs.c
+++ b/refs.c
@@ -432,11 +432,12 @@ int write_ref_sha1(struct ref_lock *lock
int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
{
- const char *logfile, *logdata, *logend, *rec, *c;
+ const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
char *tz_c;
int logfd, tz;
struct stat st;
unsigned long date;
+ unsigned char logged_sha1[20];
logfile = git_path("logs/%s", ref);
logfd = open(logfile, O_RDONLY, 0);
@@ -448,32 +449,57 @@ int read_ref_at(const char *ref, unsigne
logdata = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0);
close(logfd);
+ lastrec = NULL;
rec = logend = logdata + st.st_size;
while (logdata < rec) {
if (logdata < rec && *(rec-1) == '\n')
rec--;
- while (logdata < rec && *(rec-1) != '\n')
+ lastgt = NULL;
+ while (logdata < rec && *(rec-1) != '\n') {
rec--;
- c = rec;
- while (c < logend && *c != '>' && *c != '\n')
- c++;
- if (c == logend || *c == '\n')
+ if (*rec == '>')
+ lastgt = rec;
+ }
+ if (!lastgt)
die("Log %s is corrupt.", logfile);
- date = strtoul(c + 1, NULL, 10);
+ date = strtoul(lastgt + 1, &tz_c, 10);
if (date <= at_time) {
- if (get_sha1_hex(rec + 41, sha1))
- die("Log %s is corrupt.", logfile);
+ if (lastrec) {
+ if (get_sha1_hex(lastrec, logged_sha1))
+ die("Log %s is corrupt.", logfile);
+ if (get_sha1_hex(rec + 41, sha1))
+ die("Log %s is corrupt.", logfile);
+ if (memcmp(logged_sha1, sha1, 20)) {
+ tz = strtoul(tz_c, NULL, 10);
+ fprintf(stderr,
+ "warning: Log %s has gap after %s.\n",
+ logfile, show_rfc2822_date(date, tz));
+ }
+ } else if (date == at_time) {
+ if (get_sha1_hex(rec + 41, sha1))
+ die("Log %s is corrupt.", logfile);
+ } else {
+ if (get_sha1_hex(rec + 41, logged_sha1))
+ die("Log %s is corrupt.", logfile);
+ if (memcmp(logged_sha1, sha1, 20)) {
+ tz = strtoul(tz_c, NULL, 10);
+ fprintf(stderr,
+ "warning: Log %s unexpectedly ended on %s.\n",
+ logfile, show_rfc2822_date(date, tz));
+ }
+ }
munmap((void*)logdata, st.st_size);
return 0;
}
+ lastrec = rec;
}
- c = logdata;
- while (c < logend && *c != '>' && *c != '\n')
- c++;
- if (c == logend || *c == '\n')
+ rec = logdata;
+ while (rec < logend && *rec != '>' && *rec != '\n')
+ rec++;
+ if (rec == logend || *rec == '\n')
die("Log %s is corrupt.", logfile);
- date = strtoul(c, &tz_c, 10);
+ date = strtoul(rec + 1, &tz_c, 10);
tz = strtoul(tz_c, NULL, 10);
if (get_sha1_hex(logdata, sha1))
die("Log %s is corrupt.", logfile);
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
old mode 100644
new mode 100755
index f338c53..7858d86
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -9,6 +9,10 @@ test_description='Test git-update-ref an
Z=0000000000000000000000000000000000000000
A=1111111111111111111111111111111111111111
B=2222222222222222222222222222222222222222
+C=3333333333333333333333333333333333333333
+D=4444444444444444444444444444444444444444
+E=5555555555555555555555555555555555555555
+F=6666666666666666666666666666666666666666
m=refs/heads/master
test_expect_success \
@@ -109,4 +113,64 @@ test_expect_success \
'diff expect .git/logs/$m'
rm -f .git/$m .git/logs/$m expect
+git-update-ref $m $D
+cat >.git/logs/$m <<EOF
+$C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500
+$A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500
+$F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500
+$Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500
+EOF
+
+ed="Thu, 26 May 2005 18:32:00 -0500"
+gd="Thu, 26 May 2005 18:33:00 -0500"
+ld="Thu, 26 May 2005 18:43:00 -0500"
+test_expect_success \
+ 'Query "master@May 25 2005" (before history)' \
+ 'rm -f o e
+ git-rev-parse --verify "master@May 25 2005" >o 2>e &&
+ test $C = $(cat o) &&
+ test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
+test_expect_success \
+ "Query master@2005-05-25 (before history)" \
+ 'rm -f o e
+ git-rev-parse --verify master@2005-05-25 >o 2>e &&
+ test $C = $(cat o) &&
+ echo test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
+test_expect_success \
+ 'Query "master@May 26 2005 23:31:59" (1 second before history)' \
+ 'rm -f o e
+ git-rev-parse --verify "master@May 26 2005 23:31:59" >o 2>e &&
+ test $C = $(cat o) &&
+ test "warning: Log .git/logs/$m only goes back to $ed." = "$(cat e)"'
+test_expect_success \
+ 'Query "master@May 26 2005 23:32:00" (exactly history start)' \
+ 'rm -f o e
+ git-rev-parse --verify "master@May 26 2005 23:32:00" >o 2>e &&
+ test $A = $(cat o) &&
+ test "" = "$(cat e)"'
+test_expect_success \
+ 'Query "master@2005-05-26 23:33:01" (middle of history with gap)' \
+ 'rm -f o e
+ git-rev-parse --verify "master@2005-05-26 23:33:01" >o 2>e &&
+ test $B = $(cat o) &&
+ test "warning: Log .git/logs/$m has gap after $gd." = "$(cat e)"'
+test_expect_success \
+ 'Query "master@2005-05-26 23:33:01" (middle of history)' \
+ 'rm -f o e
+ git-rev-parse --verify "master@2005-05-26 23:38:00" >o 2>e &&
+ test $Z = $(cat o) &&
+ test "" = "$(cat e)"'
+test_expect_success \
+ 'Query "master@2005-05-26 23:43:00" (exact end of history)' \
+ 'rm -f o e
+ git-rev-parse --verify "master@2005-05-26 23:43:00" >o 2>e &&
+ test $E = $(cat o) &&
+ test "" = "$(cat e)"'
+test_expect_success \
+ 'Query "master@2005-05-28" (past end of history)' \
+ 'rm -f o e
+ git-rev-parse --verify "master@2005-05-28" >o 2>e &&
+ test $D = $(cat o) &&
+ test "warning: Log .git/logs/$m unexpectedly ended on $ld." = "$(cat e)"'
+
test_done
--
1.3.2.g7278
^ permalink raw reply related
* [PATCH 0/5] Ref log updates
From: Shawn Pearce @ 2006-05-19 7:27 UTC (permalink / raw)
To: Junio Hamano; +Cc: git
The following series of patches applies on top of 'pu' and my prior
series of ref log related patches.
Most of these are bug fixes and test cases.
* [PATCH 1/5] General ref log reading improvements.
Performance improvements and minor bug fixes in the log
parser.
* [PATCH 2/5] Added logs/ directory to repository layout.
Minor documentation update that I missed in the last round.
* [PATCH 3/5] Force writing ref if it doesn't exist.
If a ref doesn't exist make sure we write it anyway.
I found a few cases were we weren't writing the ref; this
appears to have it fixed.
* [PATCH 4/5] Log ref updates made by fetch.
Fully enable ref logging for the *-fetch family of tools.
* [PATCH 5/5] Change 'master@noon' syntax to 'master@{noon}'.
Support parsing ':' in date strings correctly, especially
in the face of 'master@2005-06-12 16:12:foo'.
--
Shawn.
^ permalink raw reply
* FIXED: [WARNING] Please be careful when using "git add" from "next" branch
From: Junio C Hamano @ 2006-05-19 6:28 UTC (permalink / raw)
To: git; +Cc: linux-kernel
In-Reply-To: <7vsln74sv7.fsf_-_@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> There is still a small breakage in the built-in "git add" on the
> "next" branch that ends up creating nonsense tree objects.
This was fixed this morning, in case I scared people.
^ permalink raw reply
* Re: [PATCH] Allow pickaxe and diff-filter options to be used by git log.
From: Junio C Hamano @ 2006-05-19 6:05 UTC (permalink / raw)
To: Sean; +Cc: git
In-Reply-To: <BAYC1-PASMTP092CB0667E05EA20FBA30EAEA70@CEZ.ICE>
Sean <seanlkml@sympatico.ca> writes:
> Well, I was looking at the use of diff-filter and -S as a way
> to prune uninteresting commits from the log rather than as an
> desire to see the patch information.
Fair enough.
> It's pretty natural to add -p or --stat along with the above
> options if that is what the user wants. If you make those implied
> by using --diff-filter or -S is there a way for the user to say,
> no patch and no stat?
Well, I was sneaking in a hidden feature with that tweak.
Regardless of the diff-filter/-S issues, with that alternative
patch, you could do:
$ git log -r
It lets you do a wonderful thing with surprisingly small number
of keystrokes ;-).
^ permalink raw reply
* Re: [PATCH] Allow pickaxe and diff-filter options to be used by git log.
From: Sean @ 2006-05-19 5:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbqtuk1uw.fsf@assigned-by-dhcp.cox.net>
On Thu, 18 May 2006 22:41:43 -0700
Junio C Hamano <junkio@cox.net> wrote:
> To me, if the user explicitly says --diff-filter or -S, it seems
> more natural to interpret that the user wanted _some_ sort of
> diff. Now, there are people who say raw format is anti-human,
> which I consider is a valid view, but I think it is better than
> NO_OUTPUT in that case.
>
> I wonder if doing something like this instead makes more sense
> perhaps?
Well, I was looking at the use of diff-filter and -S as a way
to prune uninteresting commits from the log rather than as an
desire to see the patch information.
It's pretty natural to add -p or --stat along with the above
options if that is what the user wants. If you make those implied
by using --diff-filter or -S is there a way for the user to say,
no patch and no stat?
Sean
^ permalink raw reply
* Re: [PATCH] built-in tar-tree and remote tar-tree
From: Junio C Hamano @ 2006-05-19 5:50 UTC (permalink / raw)
To: git
In-Reply-To: <7vodxulnqx.fsf_-_@assigned-by-dhcp.cox.net>
Sorry for sending a crapoid that does not even compile. I ran
format-patch while on a wrong branch.
Tonight's "pu" will have a fixed up one for people who are
interested to play with.
^ permalink raw reply
* Re: [PATCH] Allow pickaxe and diff-filter options to be used by git log.
From: Junio C Hamano @ 2006-05-19 5:41 UTC (permalink / raw)
To: Sean; +Cc: git
In-Reply-To: <BAYC1-PASMTP096010F052E9BF78B5FD4AAEA70@CEZ.ICE>
Sean <seanlkml@sympatico.ca> writes:
> + if (rev->always_show_header) {
> + if (rev->diffopt.pickaxe || rev->diffopt.filter) {
I understand and agree to the change up to this part, but I do
not necessarily agree with what follows:
> + rev->always_show_header = 0;
> + if (rev->diffopt.output_format == DIFF_FORMAT_RAW)
> + rev->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT;
To me, if the user explicitly says --diff-filter or -S, it seems
more natural to interpret that the user wanted _some_ sort of
diff. Now, there are people who say raw format is anti-human,
which I consider is a valid view, but I think it is better than
NO_OUTPUT in that case.
I wonder if doing something like this instead makes more sense
perhaps?
-- >8 --
diff --git a/builtin-log.c b/builtin-log.c
index 69f2911..e68bfad 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -23,6 +23,35 @@ static int cmd_log_wc(int argc, const ch
if (argc > 1)
die("unrecognized argument: %s", argv[1]);
+ if (rev->always_show_header) {
+ /* Log command is primarily about the message for human
+ * consumption, but if the user asks for any diff, it
+ * is human unfriendly to give the raw diff.
+ *
+ * Show command is the same way, but there the default is
+ * always give patch output, so this does not trigger.
+ */
+ if (rev->diffopt.output_format == DIFF_FORMAT_RAW) {
+ if (rev->diffopt.pickaxe)
+ rev->diffopt.output_format = DIFF_FORMAT_PATCH;
+ else {
+ rev->diffopt.output_format = DIFF_FORMAT_DIFFSTAT;
+ rev->diffopt.summary = 1;
+ }
+ }
+
+ /* If the user is limiting the commits to the ones
+ * that have particular classes of diff, we should not
+ * show the log message for irrelevant ones.
+ *
+ * git show --diff-filter=R -M --all can be used to view
+ * the branch tips that renames something. I do not know
+ * how useful that is, though.
+ */
+ if (rev->diffopt.pickaxe || rev->diffopt.filter)
+ rev->always_show_header = 0;
+ }
+
prepare_revision_walk(rev);
setup_pager();
while ((commit = get_revision(rev)) != NULL) {
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox