* Re: just can't live without a user.name
From: Miklos Vajna @ 2008-12-20 0:08 UTC (permalink / raw)
To: jidanni; +Cc: nanako3, gitster, git
In-Reply-To: <87fxkjbvl3.fsf_-_@jidanni.org>
[-- Attachment #1: Type: text/plain, Size: 615 bytes --]
On Sat, Dec 20, 2008 at 07:20:56AM +0800, jidanni@jidanni.org wrote:
> Actually it's all git's fault for not working if user.name is null or
> unset.
Please don't turn this thread into a flame.
If I understand correctly, you said you hide your name because you can't
use your real name and using some limited ASCII replacement makes you
unhappy.
I said you can use utf-8 in the user.name field and showed you an
example about this.
Instead of replying to this, you just did not quote any parts of my
message, but started to talk about you don't want to show your real name
at all. What's the point of doing so?
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* [PATCH v2] fast-export: deal with tag objects that do not have a tagger
From: Johannes Schindelin @ 2008-12-20 0:00 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Miklos Vajna, git, scott
In-Reply-To: <7viqphf4ua.fsf@gitster.siamese.dyndns.org>
When no tagger was found (old Git produced tags like this),
no "tagger" line is printed (but this is incompatible with the current
git fast-import).
Alternatively, you can pass the option --fake-missing-tagger, forcing
fast-export to fake a tagger
Unspecified Tagger <no-tagger>
with a tag date of the beginning of (Unix) time in the case of a missing
tagger, so that fast-import is still able to import the result.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Documentation/git-fast-export.txt | 6 ++++++
builtin-fast-export.c | 21 ++++++++++++++++-----
t/t9301-fast-export.sh | 20 ++++++++++++++++++++
3 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt
index 99a1c31..0c9eb56 100644
--- a/Documentation/git-fast-export.txt
+++ b/Documentation/git-fast-export.txt
@@ -65,6 +65,12 @@ If the backend uses a similar \--import-marks file, this allows for
incremental bidirectional exporting of the repository by keeping the
marks the same across runs.
+--fake-missing-tagger::
+ Some old repositories have tags without a tagger. The
+ fast-import protocol was pretty strict about that, and did not
+ allow that. So fake a tagger to be able to fast-import the
+ output.
+
EXAMPLES
--------
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 7d5d57a..8386338 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -24,6 +24,7 @@ static const char *fast_export_usage[] = {
static int progress;
static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT;
+static int fake_missing_tagger;
static int parse_opt_signed_tag_mode(const struct option *opt,
const char *arg, int unset)
@@ -297,10 +298,17 @@ static void handle_tag(const char *name, struct tag *tag)
message_size = strlen(message);
}
tagger = memmem(buf, message ? message - buf : size, "\ntagger ", 8);
- if (!tagger)
- die ("No tagger for tag %s", sha1_to_hex(tag->object.sha1));
- tagger++;
- tagger_end = strchrnul(tagger, '\n');
+ if (!tagger) {
+ if (fake_missing_tagger)
+ tagger = "tagger Unspecified Tagger "
+ "<unspecified-tagger> 0 +0000";
+ else
+ tagger = "";
+ tagger_end = tagger + strlen(tagger);
+ } else {
+ tagger++;
+ tagger_end = strchrnul(tagger, '\n');
+ }
/* handle signed tags */
if (message) {
@@ -326,9 +334,10 @@ static void handle_tag(const char *name, struct tag *tag)
if (!prefixcmp(name, "refs/tags/"))
name += 10;
- printf("tag %s\nfrom :%d\n%.*s\ndata %d\n%.*s\n",
+ printf("tag %s\nfrom :%d\n%.*s%sdata %d\n%.*s\n",
name, get_object_mark(tag->tagged),
(int)(tagger_end - tagger), tagger,
+ tagger == tagger_end ? "" : "\n",
(int)message_size, (int)message_size, message ? message : "");
}
@@ -483,6 +492,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
"Dump marks to this file"),
OPT_STRING(0, "import-marks", &import_filename, "FILE",
"Import marks from this file"),
+ OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger,
+ "Fake a tagger when tags lack one"),
OPT_END()
};
diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh
index 2057435..9985721 100755
--- a/t/t9301-fast-export.sh
+++ b/t/t9301-fast-export.sh
@@ -239,4 +239,24 @@ test_expect_success 'fast-export | fast-import when master is tagged' '
'
+cat > tag-content << EOF
+object $(git rev-parse HEAD)
+type commit
+tag rosten
+EOF
+
+test_expect_success 'cope with tagger-less tags' '
+
+ TAG=$(git hash-object -t tag -w tag-content) &&
+ git update-ref refs/tags/sonnenschein $TAG &&
+ git fast-export -C -C --signed-tags=strip --all > output &&
+ test $(grep -c "^tag " output) = 4 &&
+ ! grep "Unspecified Tagger" output &&
+ git fast-export -C -C --signed-tags=strip --all \
+ --fake-missing-tagger > output &&
+ test $(grep -c "^tag " output) = 4 &&
+ grep "Unspecified Tagger" output
+
+'
+
test_done
--
1.6.1.rc3.412.ga72b
^ permalink raw reply related
* Re: Odd merge behaviour involving reverts
From: Junio C Hamano @ 2008-12-19 23:51 UTC (permalink / raw)
To: Nanako Shiraishi; +Cc: Linus Torvalds, Alan, git
In-Reply-To: <20081220081238.6117@nanako3.lavabit.com>
Nanako Shiraishi <nanako3@lavabit.com> writes:
> Quoting Junio C Hamano <gitster@pobox.com>:
>
>> Nanako Shiraishi <nanako3@lavabit.com> writes:
>>
>>> I think your explanation will help people if we make it part of the
>>> documentation. Especially because two different cases need two
>>> different recovery methods, and people need to learn which is which.
>>
>> Sure. It needs copyediting to make it readable standalone by not
>> mentioning "your misunderstanding", inlining "earlier Linus's suggestion",
>> etc., though.
>>
>> Patches welcome ;-)
>
> Okay, I'll send one later.
Thanks.
^ permalink raw reply
* [PATCH 4/4] Add an expensive test for git-notes
From: Johannes Schindelin @ 2008-12-19 23:37 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0812192347261.30769@pacific.mpi-cbg.de>
git-notes have the potential of being pretty expensive, so test with
a lot of commits. A lot. So to make things cheaper, you have to
opt-in explicitely, by setting the environment variable
GIT_NOTES_TIMING_TESTS.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
I would appreciate other people running the tests, and maybe
profiling the code.
However, I will not be really online the next two weeks, so if you
feel like working on this series, go ahead.
Merry Christmas.
t/t3302-notes-index-expensive.sh | 98 ++++++++++++++++++++++++++++++++++++++
1 files changed, 98 insertions(+), 0 deletions(-)
create mode 100755 t/t3302-notes-index-expensive.sh
diff --git a/t/t3302-notes-index-expensive.sh b/t/t3302-notes-index-expensive.sh
new file mode 100755
index 0000000..00d27bf
--- /dev/null
+++ b/t/t3302-notes-index-expensive.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Johannes E. Schindelin
+#
+
+test_description='Test commit notes index (expensive!)'
+
+. ./test-lib.sh
+
+test -z "$GIT_NOTES_TIMING_TESTS" && {
+ say Skipping timing tests
+ test_done
+ exit
+}
+
+create_repo () {
+ number_of_commits=$1
+ nr=0
+ parent=
+ test -d .git || {
+ git init &&
+ tree=$(git write-tree) &&
+ while [ $nr -lt $number_of_commits ]; do
+ test_tick &&
+ commit=$(echo $nr | git commit-tree $tree $parent) ||
+ return
+ parent="-p $commit"
+ nr=$(($nr+1))
+ done &&
+ git update-ref refs/heads/master $commit &&
+ {
+ export GIT_INDEX_FILE=.git/temp;
+ git rev-list HEAD | cat -n | sed "s/^[ ][ ]*/ /g" |
+ while read nr sha1; do
+ blob=$(echo note $nr | git hash-object -w --stdin) &&
+ echo $sha1 | sed "s/^/0644 $blob 0 /"
+ done | git update-index --index-info &&
+ tree=$(git write-tree) &&
+ test_tick &&
+ commit=$(echo notes | git commit-tree $tree) &&
+ git update-ref refs/notes/commits $commit
+ } &&
+ git config core.notesRef refs/notes/commits
+ }
+}
+
+test_notes () {
+ count=$1 &&
+ git config core.notesRef refs/notes/commits &&
+ git log | grep "^ " > output &&
+ i=1 &&
+ while [ $i -le $count ]; do
+ echo " $(($count-$i))" &&
+ echo " note $i" &&
+ i=$(($i+1));
+ done > expect &&
+ git diff expect output
+}
+
+cat > time_notes << \EOF
+ mode=$1
+ i=1
+ while [ $i -lt $2 ]; do
+ case $1 in
+ no-notes)
+ export GIT_NOTES_REF=non-existing
+ ;;
+ notes)
+ unset GIT_NOTES_REF
+ ;;
+ esac
+ git log >/dev/null
+ i=$(($i+1))
+ done
+EOF
+
+time_notes () {
+ for mode in no-notes notes
+ do
+ echo $mode
+ /usr/bin/time sh ../time_notes $mode $1
+ done
+}
+
+for count in 10 100 1000 10000; do
+
+ mkdir $count
+ (cd $count;
+
+ test_expect_success "setup $count" "create_repo $count"
+
+ test_expect_success 'notes work' "test_notes $count"
+
+ test_expect_success 'notes timing' "time_notes 100"
+ )
+done
+
+test_done
--
1.6.1.rc3.368.g63acc
^ permalink raw reply related
* [PATCH 3/4] Speed up git notes lookup
From: Johannes Schindelin @ 2008-12-19 23:35 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0812192347261.30769@pacific.mpi-cbg.de>
To avoid looking up each and every commit in the notes ref's tree
object, which is very expensive, speed things up by slurping the tree
object's contents into a hash_map.
The idea fo the hashmap singleton is from David Reiss, initial
benchmarking by Jeff King.
Note: the implementation allows for arbitrary entries in the notes
tree object, ignoring those that do not reference a valid object. This
allows you to annotate arbitrary branches, or objects.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
notes.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 102 insertions(+), 11 deletions(-)
diff --git a/notes.c b/notes.c
index 91ec77f..68bcb24 100644
--- a/notes.c
+++ b/notes.c
@@ -4,16 +4,112 @@
#include "refs.h"
#include "utf8.h"
#include "strbuf.h"
+#include "tree-walk.h"
+
+struct entry {
+ unsigned char commit_sha1[20];
+ unsigned char notes_sha1[20];
+};
+
+struct hash_map {
+ struct entry *entries;
+ off_t count, size;
+};
static int initialized;
+static struct hash_map hash_map;
+
+static int hash_index(struct hash_map *map, const unsigned char *sha1)
+{
+ int i = ((*(unsigned int *)sha1) % map->size);
+
+ for (;;) {
+ unsigned char *current = map->entries[i].commit_sha1;
+
+ if (!hashcmp(sha1, current))
+ return i;
+
+ if (is_null_sha1(current))
+ return -1 - i;
+
+ if (++i == map->size)
+ i = 0;
+ }
+}
+
+static void add_entry(const unsigned char *commit_sha1,
+ const unsigned char *notes_sha1)
+{
+ int index;
+
+ if (hash_map.count + 1 > hash_map.size >> 1) {
+ int i, old_size = hash_map.size;
+ struct entry *old = hash_map.entries;
+
+ hash_map.size = old_size ? old_size << 1 : 64;
+ hash_map.entries = (struct entry *)
+ xcalloc(sizeof(struct entry), hash_map.size);
+
+ for (i = 0; i < old_size; i++)
+ if (!is_null_sha1(old[i].commit_sha1)) {
+ index = -1 - hash_index(&hash_map,
+ old[i].commit_sha1);
+ memcpy(hash_map.entries + index, old + i,
+ sizeof(struct entry));
+ }
+ free(old);
+ }
+
+ index = hash_index(&hash_map, commit_sha1);
+ if (index < 0) {
+ index = -1 - index;
+ hash_map.count++;
+ }
+
+ hashcpy(hash_map.entries[index].commit_sha1, commit_sha1);
+ hashcpy(hash_map.entries[index].notes_sha1, notes_sha1);
+}
+
+static void initialize_hash_map(const char *notes_ref_name)
+{
+ unsigned char sha1[20], commit_sha1[20];
+ unsigned *mode;
+ struct tree_desc desc;
+ struct name_entry entry;
+ void *buf;
+
+ if (!notes_ref_name || read_ref(notes_ref_name, commit_sha1) ||
+ get_tree_entry(commit_sha1, "", sha1, mode))
+ return;
+
+ buf = fill_tree_descriptor(&desc, sha1);
+ if (!buf)
+ die ("Could not read %s for notes-index", sha1_to_hex(sha1));
+
+ while (tree_entry(&desc, &entry))
+ if (!get_sha1(entry.path, commit_sha1))
+ add_entry(commit_sha1, entry.sha1);
+ free(buf);
+}
+
+static unsigned char *lookup_notes(const unsigned char *commit_sha1)
+{
+ int index;
+
+ if (!hash_map.size)
+ return NULL;
+
+ index = hash_index(&hash_map, commit_sha1);
+ if (index < 0)
+ return NULL;
+ return hash_map.entries[index].notes_sha1;
+}
void get_commit_notes(const struct commit *commit, struct strbuf *sb,
const char *output_encoding)
{
static const char *utf8 = "utf-8";
- struct strbuf name = STRBUF_INIT;
- const char *hex;
- unsigned char sha1[20];
+ unsigned char *sha1;
char *msg;
unsigned long msgoffset, msglen;
enum object_type type;
@@ -24,17 +120,12 @@ void get_commit_notes(const struct commit *commit, struct strbuf *sb,
notes_ref_name = getenv(GIT_NOTES_REF_ENVIRONMENT);
else if (!notes_ref_name)
notes_ref_name = GIT_NOTES_DEFAULT_REF;
- if (notes_ref_name && read_ref(notes_ref_name, sha1))
- notes_ref_name = NULL;
+ initialize_hash_map(notes_ref_name);
initialized = 1;
}
- if (!notes_ref_name)
- return;
-
- strbuf_addf(&name, "%s:%s", notes_ref_name,
- sha1_to_hex(commit->object.sha1));
- if (get_sha1(name.buf, sha1))
+ sha1 = lookup_notes(commit->object.sha1);
+ if (!sha1)
return;
if (!(msg = read_sha1_file(sha1, &type, &msglen)) || !msglen ||
--
1.6.1.rc3.368.g63acc
^ permalink raw reply related
* [PATCH 2/4] Add a script to edit/inspect notes
From: Johannes Schindelin @ 2008-12-19 23:35 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0812192347261.30769@pacific.mpi-cbg.de>
The script 'git notes' allows you to edit and show commit notes, by
calling either
git notes show <commit>
or
git notes edit <commit>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
.gitignore | 1 +
Documentation/git-notes.txt | 46 ++++++++++++++++++++++++++++++
Makefile | 1 +
command-list.txt | 1 +
git-notes.sh | 65 +++++++++++++++++++++++++++++++++++++++++++
t/t3301-notes.sh | 65 +++++++++++++++++++++++++++++++++++++++++++
6 files changed, 179 insertions(+), 0 deletions(-)
create mode 100644 Documentation/git-notes.txt
create mode 100755 git-notes.sh
create mode 100755 t/t3301-notes.sh
diff --git a/.gitignore b/.gitignore
index 90bbb2a..8b90af1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,6 +83,7 @@ git-mktag
git-mktree
git-name-rev
git-mv
+git-notes
git-pack-redundant
git-pack-objects
git-pack-refs
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
new file mode 100644
index 0000000..3d93625
--- /dev/null
+++ b/Documentation/git-notes.txt
@@ -0,0 +1,46 @@
+git-notes(1)
+============
+
+NAME
+----
+git-notes - Add/inspect commit notes
+
+SYNOPSIS
+--------
+[verse]
+'git-notes' (edit | show) [commit]
+
+DESCRIPTION
+-----------
+This command allows you to add notes to commit messages, without
+changing the commit. To discern these notes from the message stored
+in the commit object, the notes are indented like the message, after
+an unindented line saying "Notes:".
+
+To disable commit notes, you have to set the config variable
+core.notesRef to the empty string. Alternatively, you can set it
+to a different ref, something like "refs/notes/bugzilla". This setting
+can be overridden by the environment variable "GIT_NOTES_REF".
+
+
+SUBCOMMANDS
+-----------
+
+edit::
+ Edit the notes for a given commit (defaults to HEAD).
+
+show::
+ Show the notes for a given commit (defaults to HEAD).
+
+
+Author
+------
+Written by Johannes Schindelin <johannes.schindelin@gmx.de>
+
+Documentation
+-------------
+Documentation by Johannes Schindelin
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Makefile b/Makefile
index 7871f52..4bdc86e 100644
--- a/Makefile
+++ b/Makefile
@@ -259,6 +259,7 @@ SCRIPT_SH += git-merge-octopus.sh
SCRIPT_SH += git-merge-one-file.sh
SCRIPT_SH += git-merge-resolve.sh
SCRIPT_SH += git-mergetool.sh
+SCRIPT_SH += git-notes.sh
SCRIPT_SH += git-parse-remote.sh
SCRIPT_SH += git-pull.sh
SCRIPT_SH += git-quiltimport.sh
diff --git a/command-list.txt b/command-list.txt
index 3583a33..2dc2c33 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -73,6 +73,7 @@ git-mktag plumbingmanipulators
git-mktree plumbingmanipulators
git-mv mainporcelain common
git-name-rev plumbinginterrogators
+git-notes mainporcelain
git-pack-objects plumbingmanipulators
git-pack-redundant plumbinginterrogators
git-pack-refs ancillarymanipulators
diff --git a/git-notes.sh b/git-notes.sh
new file mode 100755
index 0000000..bfdbaa8
--- /dev/null
+++ b/git-notes.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+USAGE="(edit | show) [commit]"
+. git-sh-setup
+
+test -n "$3" && usage
+
+test -z "$1" && usage
+ACTION="$1"; shift
+
+test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="$(git config core.notesref)"
+test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="refs/notes/commits"
+
+COMMIT=$(git rev-parse --verify --default HEAD "$@") ||
+die "Invalid commit: $@"
+
+MESSAGE="$GIT_DIR"/new-notes-$COMMIT
+trap '
+ test -f "$MESSAGE" && rm "$MESSAGE"
+' 0
+
+case "$ACTION" in
+edit)
+ GIT_NOTES_REF= git log -1 $COMMIT | sed "s/^/#/" > "$MESSAGE"
+
+ GIT_INDEX_FILE="$MESSAGE".idx
+ export GIT_INDEX_FILE
+
+ CURRENT_HEAD=$(git show-ref "$GIT_NOTES_REF" | cut -f 1 -d ' ')
+ if [ -z "$CURRENT_HEAD" ]; then
+ PARENT=
+ else
+ PARENT="-p $CURRENT_HEAD"
+ git read-tree "$GIT_NOTES_REF" || die "Could not read index"
+ git cat-file blob :$COMMIT >> "$MESSAGE" 2> /dev/null
+ fi
+
+ ${VISUAL:-${EDITOR:-vi}} "$MESSAGE"
+
+ grep -v ^# < "$MESSAGE" | git stripspace > "$MESSAGE".processed
+ mv "$MESSAGE".processed "$MESSAGE"
+ if [ -s "$MESSAGE" ]; then
+ BLOB=$(git hash-object -w "$MESSAGE") ||
+ die "Could not write into object database"
+ git update-index --add --cacheinfo 0644 $BLOB $COMMIT ||
+ die "Could not write index"
+ else
+ test -z "$CURRENT_HEAD" &&
+ die "Will not initialise with empty tree"
+ git update-index --force-remove $COMMIT ||
+ die "Could not update index"
+ fi
+
+ TREE=$(git write-tree) || die "Could not write tree"
+ NEW_HEAD=$(echo Annotate $COMMIT | git commit-tree $TREE $PARENT) ||
+ die "Could not annotate"
+ git update-ref -m "Annotate $COMMIT" \
+ "$GIT_NOTES_REF" $NEW_HEAD $CURRENT_HEAD
+;;
+show)
+ git show "$GIT_NOTES_REF":$COMMIT
+;;
+*)
+ usage
+esac
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
new file mode 100755
index 0000000..ba42c45
--- /dev/null
+++ b/t/t3301-notes.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Johannes E. Schindelin
+#
+
+test_description='Test commit notes'
+
+. ./test-lib.sh
+
+cat > fake_editor.sh << \EOF
+echo "$MSG" > "$1"
+echo "$MSG" >& 2
+EOF
+chmod a+x fake_editor.sh
+VISUAL=./fake_editor.sh
+export VISUAL
+
+test_expect_success 'cannot annotate non-existing HEAD' '
+ ! MSG=3 git notes edit
+'
+
+test_expect_success setup '
+ : > a1 &&
+ git add a1 &&
+ test_tick &&
+ git commit -m 1st &&
+ : > a2 &&
+ git add a2 &&
+ test_tick &&
+ git commit -m 2nd
+'
+
+test_expect_success 'need valid notes ref' '
+ ! MSG=1 GIT_NOTES_REF='/' git notes edit &&
+ ! MSG=2 GIT_NOTES_REF='/' git notes show
+'
+
+test_expect_success 'create notes' '
+ git config core.notesRef refs/notes/commits &&
+ MSG=b1 git notes edit &&
+ test ! -f .git/new-notes &&
+ test 1 = $(git ls-tree refs/notes/commits | wc -l) &&
+ test b1 = $(git notes show) &&
+ git show HEAD^ &&
+ ! git notes show HEAD^
+'
+
+cat > expect << EOF
+commit 268048bfb8a1fb38e703baceb8ab235421bf80c5
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:14:13 2005 -0700
+
+ 2nd
+
+Notes:
+ b1
+EOF
+
+test_expect_success 'show notes' '
+ ! (git cat-file commit HEAD | grep b1) &&
+ git log -1 > output &&
+ git diff expect output
+'
+
+test_done
--
1.6.1.rc3.368.g63acc
^ permalink raw reply related
* [PATCH 1/4] Introduce commit notes
From: Johannes Schindelin @ 2008-12-19 23:35 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0812192347261.30769@pacific.mpi-cbg.de>
Commit notes are blobs which are shown together with the commit
message. These blobs are taken from the notes ref, which you can
configure by the config variable core.notesRef, which in turn can
be overridden by the environment variable GIT_NOTES_REF.
The notes ref is a branch which contains "files" whose names are
the names of the corresponding commits (i.e. the SHA-1).
The rationale for putting this information into a ref is this: we
want to be able to fetch and possibly union-merge the notes,
maybe even look at the date when a note was introduced, and we
want to store them efficiently together with the other objects.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Documentation/config.txt | 15 ++++++++++
Makefile | 2 +
cache.h | 3 ++
commit.c | 1 +
config.c | 5 +++
environment.c | 1 +
notes.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++
notes.h | 7 +++++
pretty.c | 5 +++
9 files changed, 107 insertions(+), 0 deletions(-)
create mode 100644 notes.c
create mode 100644 notes.h
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 4089362..3248524 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -431,6 +431,21 @@ core.inithook::
linkgit:git-init[1]. The hook is called with the argument
"reinit" if an existing repository is re-initialized.
+core.notesRef::
+ When showing commit messages, also show notes which are stored in
+ the given ref. This ref is expected to contain paths of the form
+ ??/*, where the directory name consists of the first two
+ characters of the commit name, and the base name consists of
+ the remaining 38 characters.
++
+If such a path exists in the given ref, the referenced blob is read, and
+appended to the commit message, separated by a "Notes:" line. If the
+given ref itself does not exist, it is not an error, but means that no
+notes should be print.
++
+This setting defaults to "refs/notes/commits", and can be overridden by
+the `GIT_NOTES_REF` environment variable.
+
alias.*::
Command aliases for the linkgit:git[1] command wrapper - e.g.
after defining "alias.last = cat-file commit HEAD", the invocation
diff --git a/Makefile b/Makefile
index 5e293fe..7871f52 100644
--- a/Makefile
+++ b/Makefile
@@ -371,6 +371,7 @@ LIB_H += ll-merge.h
LIB_H += log-tree.h
LIB_H += mailmap.h
LIB_H += merge-recursive.h
+LIB_H += notes.h
LIB_H += object.h
LIB_H += pack.h
LIB_H += pack-refs.h
@@ -454,6 +455,7 @@ LIB_OBJS += match-trees.o
LIB_OBJS += merge-file.o
LIB_OBJS += merge-recursive.o
LIB_OBJS += name-hash.o
+LIB_OBJS += notes.o
LIB_OBJS += object.o
LIB_OBJS += pack-check.o
LIB_OBJS += pack-refs.o
diff --git a/cache.h b/cache.h
index b393c2d..30981de 100644
--- a/cache.h
+++ b/cache.h
@@ -375,6 +375,8 @@ static inline enum object_type object_type(unsigned int mode)
#define GITATTRIBUTES_FILE ".gitattributes"
#define INFOATTRIBUTES_FILE "info/attributes"
#define ATTRIBUTE_MACRO_PREFIX "[attr]"
+#define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF"
+#define GIT_NOTES_DEFAULT_REF "refs/notes/commits"
extern int is_bare_repository_cfg;
extern int is_bare_repository(void);
@@ -548,6 +550,7 @@ enum rebase_setup_type {
extern enum branch_track git_branch_track;
extern enum rebase_setup_type autorebase;
extern int keep_hard_links;
+extern char *notes_ref_name;
#define GIT_REPO_VERSION 0
extern int repository_format_version;
diff --git a/commit.c b/commit.c
index 00f4774..547b88f 100644
--- a/commit.c
+++ b/commit.c
@@ -5,6 +5,7 @@
#include "utf8.h"
#include "diff.h"
#include "revision.h"
+#include "notes.h"
int save_commit_buffer = 1;
diff --git a/config.c b/config.c
index 8ff2b4b..9ab9d21 100644
--- a/config.c
+++ b/config.c
@@ -469,6 +469,11 @@ static int git_default_core_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.notesref")) {
+ notes_ref_name = xstrdup(value);
+ return 0;
+ }
+
if (!strcmp(var, "core.pager"))
return git_config_string(&pager_program, var, value);
diff --git a/environment.c b/environment.c
index fc91809..5724ad2 100644
--- a/environment.c
+++ b/environment.c
@@ -46,6 +46,7 @@ int keep_hard_links = 0;
/* Parallel index stat data preload? */
int core_preload_index = 0;
+char *notes_ref_name;
/* This is set by setup_git_dir_gently() and/or git_default_config() */
char *git_work_tree_cfg;
diff --git a/notes.c b/notes.c
new file mode 100644
index 0000000..91ec77f
--- /dev/null
+++ b/notes.c
@@ -0,0 +1,68 @@
+#include "cache.h"
+#include "commit.h"
+#include "notes.h"
+#include "refs.h"
+#include "utf8.h"
+#include "strbuf.h"
+
+static int initialized;
+
+void get_commit_notes(const struct commit *commit, struct strbuf *sb,
+ const char *output_encoding)
+{
+ static const char *utf8 = "utf-8";
+ struct strbuf name = STRBUF_INIT;
+ const char *hex;
+ unsigned char sha1[20];
+ char *msg;
+ unsigned long msgoffset, msglen;
+ enum object_type type;
+
+ if (!initialized) {
+ const char *env = getenv(GIT_NOTES_REF_ENVIRONMENT);
+ if (env)
+ notes_ref_name = getenv(GIT_NOTES_REF_ENVIRONMENT);
+ else if (!notes_ref_name)
+ notes_ref_name = GIT_NOTES_DEFAULT_REF;
+ if (notes_ref_name && read_ref(notes_ref_name, sha1))
+ notes_ref_name = NULL;
+ initialized = 1;
+ }
+
+ if (!notes_ref_name)
+ return;
+
+ strbuf_addf(&name, "%s:%s", notes_ref_name,
+ sha1_to_hex(commit->object.sha1));
+ if (get_sha1(name.buf, sha1))
+ return;
+
+ if (!(msg = read_sha1_file(sha1, &type, &msglen)) || !msglen ||
+ type != OBJ_BLOB)
+ return;
+
+ if (output_encoding && *output_encoding &&
+ strcmp(utf8, output_encoding)) {
+ char *reencoded = reencode_string(msg, output_encoding, utf8);
+ if (reencoded) {
+ free(msg);
+ msg = reencoded;
+ msglen = strlen(msg);
+ }
+ }
+
+ /* we will end the annotation by a newline anyway */
+ if (msglen && msg[msglen - 1] == '\n')
+ msglen--;
+
+ strbuf_addstr(sb, "\nNotes:\n");
+
+ for (msgoffset = 0; msgoffset < msglen;) {
+ int linelen = strchrnul(msg, '\n') - msg;
+
+ strbuf_addstr(sb, " ");
+ strbuf_add(sb, msg + msgoffset, linelen);
+ msgoffset += linelen;
+ }
+ free(msg);
+}
diff --git a/notes.h b/notes.h
new file mode 100644
index 0000000..79d21b6
--- /dev/null
+++ b/notes.h
@@ -0,0 +1,7 @@
+#ifndef NOTES_H
+#define NOTES_H
+
+void get_commit_notes(const struct commit *commit, struct strbuf *sb,
+ const char *output_encoding);
+
+#endif
diff --git a/pretty.c b/pretty.c
index 5f9a0c7..c2bf451 100644
--- a/pretty.c
+++ b/pretty.c
@@ -6,6 +6,7 @@
#include "string-list.h"
#include "mailmap.h"
#include "log-tree.h"
+#include "notes.h"
static char *user_format;
@@ -911,5 +912,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
*/
if (fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
strbuf_addch(sb, '\n');
+
+ if (fmt != CMIT_FMT_ONELINE)
+ get_commit_notes(commit, sb, encoding);
+
free(reencoded);
}
--
1.6.1.rc3.368.g63acc
^ permalink raw reply related
* [PATCH 0/4] Notes reloaded
From: Johannes Schindelin @ 2008-12-19 23:34 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <20081216085108.GA3031@coredump.intra.peff.net>
Hi,
On Tue, 16 Dec 2008, Jeff King wrote:
> Johannes Schindelin's notes proposal (which is more or less
> the current proposal, but I think the on-disk notes index was not
> well liked):
> http://thread.gmane.org/gmane.comp.version-control.git/52598
I redid the benchmark (this time with a bit beefier machine), just
comparing no notes with David's/Peff's idea:
-- snip --
$ GIT_NOTES_TIMING_TESTS=1 sh t3302-notes-index-expensive.sh -i -v
Initialized empty Git repository in /home/gitte/git/t/trash directory.t3302-notes-index-expensive/.git/
* expecting success: create_repo 10
Initialized empty Git repository in /home/gitte/git/t/trash directory.t3302-notes-index-expensive/10/.git/
* ok 1: setup 10
* expecting success: test_notes 10
* ok 2: notes work
* expecting success: time_notes 100
no-notes
0.08user 0.10system 0:00.18elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+58926minor)pagefaults 0swaps
notes
0.14user 0.07system 0:00.54elapsed 38%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+60319minor)pagefaults 0swaps
* ok 3: notes timing
* expecting success: create_repo 100
Initialized empty Git repository in /home/gitte/git/t/trash directory.t3302-notes-index-expensive/100/.git/
* ok 1: setup 100
* expecting success: test_notes 100
* ok 2: notes work
* expecting success: time_notes 100
no-notes
0.23user 0.21system 0:00.45elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+68043minor)pagefaults 0swaps
notes
0.38user 0.21system 0:00.59elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+78829minor)pagefaults 0swaps
* ok 3: notes timing
* expecting success: create_repo 1000
Initialized empty Git repository in /home/gitte/git/t/trash directory.t3302-notes-index-expensive/1000/.git/
* ok 1: setup 1000
* expecting success: test_notes 1000
* ok 2: notes work
* expecting success: time_notes 100
no-notes
2.06user 0.95system 0:04.26elapsed 70%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+159115minor)pagefaults 0swaps
notes
2.83user 1.54system 0:04.38elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+267416minor)pagefaults 0swaps
* ok 3: notes timing
* expecting success: create_repo 10000
Initialized empty Git repository in /home/gitte/git/t/trash directory.t3302-notes-index-expensive/10000/.git/
* ok 1: setup 10000
* expecting success: test_notes 10000
* ok 2: notes work
* expecting success: time_notes 100
no-notes
20.46user 7.63system 0:28.30elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+1083378minor)pagefaults 0swaps
notes
28.78user 13.74system 0:42.85elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+2240296minor)pagefaults 0swaps
* ok 3: notes timing
* passed all 0 test(s)
-- snap --
Keep in mind that the tests run "git log" 99 times, and show the
accumulated time.
So it seems that an increase of roughly 40% in the user time, and roughly
70% in the system time is the price to have notes associated with every
single commit.
Note that in that very same repository, a single "git show" goes from
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata
0maxresident)k
0inputs+0outputs (0major+561minor)pagefaults 0swaps
to this:
0.03user 0.02system 0:00.04elapsed 113%CPU (0avgtext+0avgdata
0maxresident)k
0inputs+0outputs (0major+2294minor)pagefaults 0swaps
(In another run, it only used 90%CPU)
That's not too shabby, given that Git needs to unpack double the number of
objects in this test when using notes vs. no notes.
For comparison, the numbers back then were something like 10% in user time
with a penalty of an extraordinary magnitude everytime the notes are
updated: around 800%.
Note: all these numbers are worst-case numbers, i.e. every commit has one
note.
To be frank, I do not completely understand why the numbers are that high.
I would have understood an increase roughly 4 seconds for reading the
quite large tree 99 times, and then the same ~0.20 seconds back then.
Maybe I made a huge mistake when implementing the thing.
And BTW, my code does not yet handle the case when
refs/notes/commits:$commit is a tree instead of a blob. That is left as
an exercise to the reader.
Johannes Schindelin (4):
Introduce commit notes
Add a script to edit/inspect notes
Speed up git notes lookup
Add an expensive test for git-notes
.gitignore | 1 +
Documentation/config.txt | 15 ++++
Documentation/git-notes.txt | 46 +++++++++++
Makefile | 3 +
cache.h | 3 +
command-list.txt | 1 +
commit.c | 1 +
config.c | 5 +
environment.c | 1 +
git-notes.sh | 65 +++++++++++++++
notes.c | 159 ++++++++++++++++++++++++++++++++++++++
notes.h | 7 ++
pretty.c | 5 +
t/t3301-notes.sh | 65 +++++++++++++++
t/t3302-notes-index-expensive.sh | 98 +++++++++++++++++++++++
15 files changed, 475 insertions(+), 0 deletions(-)
create mode 100644 Documentation/git-notes.txt
create mode 100755 git-notes.sh
create mode 100644 notes.c
create mode 100644 notes.h
create mode 100755 t/t3301-notes.sh
create mode 100755 t/t3302-notes-index-expensive.sh
^ permalink raw reply
* just can't live without a user.name
From: jidanni @ 2008-12-19 23:20 UTC (permalink / raw)
To: vmiklos; +Cc: nanako3, gitster, git
In-Reply-To: <20081219223306.GH21154@genesis.frugalware.org>
Actually it's all git's fault for not working if user.name is null or
unset. Ask yourself, would email programs panic if all there was only
bob@example.org in a header?
> But we need a user.name for legal reasons.
But there should be a way to override it, in case those laws don't apply.
I want
Author: jidanni@jidanni.org
like my email address above. But the closest I can get is
Author: jidanni <jidanni@jidanni.org>
And then there are some programs that need
$ git config --global user.name $USER
just to get that, else the springs come loose:
$ git-format-patch -s
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: empty ident <jidanni@jidanni.org
> not allowed
^ permalink raw reply
* Re: Odd merge behaviour involving reverts
From: Nanako Shiraishi @ 2008-12-19 23:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, Alan, git
In-Reply-To: <7vljub7oko.fsf@gitster.siamese.dyndns.org>
Quoting Junio C Hamano <gitster@pobox.com>:
> Nanako Shiraishi <nanako3@lavabit.com> writes:
>
>> I think your explanation will help people if we make it part of the
>> documentation. Especially because two different cases need two
>> different recovery methods, and people need to learn which is which.
>
> Sure. It needs copyediting to make it readable standalone by not
> mentioning "your misunderstanding", inlining "earlier Linus's suggestion",
> etc., though.
>
> Patches welcome ;-)
Okay, I'll send one later.
Thanks.
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply
* Re: [PATCH] diff.c: fix pointer type warning
From: Junio C Hamano @ 2008-12-19 23:09 UTC (permalink / raw)
To: René Scharfe; +Cc: Mark Burton, Linus Torvalds, Git Mailing List
In-Reply-To: <494C1BE8.20607@lsrfire.ath.cx>
Thanks; I think I already have it in my tree from your yesterday's
e-mail. I just have been too busy to whip the other branches into shape
to push the results out.
^ permalink raw reply
* Re: [PATCH] Clarify git-format-patch --in-reply-to
From: Junio C Hamano @ 2008-12-19 23:07 UTC (permalink / raw)
To: Miklos Vajna; +Cc: Nanako Shiraishi, jidanni, gitster, git
In-Reply-To: <20081219222209.GG21154@genesis.frugalware.org>
Miklos Vajna <vmiklos@frugalware.org> writes:
> On Sat, Dec 20, 2008 at 06:51:35AM +0900, Nanako Shiraishi <nanako3@lavabit.com> wrote:
>> I understand that "Signed-off-by" is about code ownership and thought
>> that the official history prefers to have a real name instead of a
>> pseudonym. Perhaps you would want to say "Dan Jacobson
>> <jidanni@jidanni.org>" or something similar?
>
> I don't think it's a requirement, see 2b36b14 for example. Though yes,
> in general it's considered childish to hide behind a nickname, instead
> of using your real name. (ESR has a section about this in the "hacker
> howto".)
An earlier mistake does not justify adding new ones. Besides, I think
ALASCM once revealed his "real name" on the list.
^ permalink raw reply
* Re: Odd merge behaviour involving reverts
From: Junio C Hamano @ 2008-12-19 23:05 UTC (permalink / raw)
To: Nanako Shiraishi; +Cc: Linus Torvalds, Alan, git
In-Reply-To: <20081220064532.6117@nanako3.lavabit.com>
Nanako Shiraishi <nanako3@lavabit.com> writes:
> I think your explanation will help people if we make it part of the
> documentation. Especially because two different cases need two
> different recovery methods, and people need to learn which is which.
Sure. It needs copyediting to make it readable standalone by not
mentioning "your misunderstanding", inlining "earlier Linus's suggestion",
etc., though.
Patches welcome ;-)
^ permalink raw reply
* Very slow clone time over http
From: demerphq @ 2008-12-19 22:33 UTC (permalink / raw)
To: git
Hi,
I've been working on the migration of the perl5 repositories from
perforce to git, which is soon to be officially released.
We have set up a server with http/git/ssh access, and we had hoped
also rsync access.
However, it appears that clone using the rsync:// protocol is broken,
and now we are discovering that http cloning is extremely slow. I
reported our experiences with rsync in a previous mail, and now im
reporting the http performance issue.
When we strace the clone we observe (to quote our sysadmin):
"git seems to be stuck for 10 minutes after downloading"
"no output, strace shows it's having sex with the memory allocator"
"sex with memory allocator" ==> loads of memory allocation/dealoccation
A provisional release of the conversion is available at
http://dromedary.booking.com/perl.git
We are using git 1.6.0.5 on another more or less equivalent host, with
the same problems, and dromedary is using git version
1.6.0.4.724.ga0d3a. However we believe that the problem is actually on
the client side. The pack download itself appears to be quite fast,
however there is an extremely long pause (minutes) after which a HUGE
amount of essentially imcomprehensible output is generated about
walking packs or some such.
Timing a clone via http gets us number like:
real 7m42.459s
user 3m42.154s
sys 0m12.641s
Wheras using the git:// protocol gets us times like:
real 4m6.162s
user 0m43.595s
sys 0m4.852s
The client these numbers are from is git version 1.6.0.3.
So it take approximately twice the time via http as it does via git.
This seems somewhat strange. Is there anything we can do to improve
this? Repack? Anything like that?
A post about the github system suggests that this is not an isolated problem.
http://github.com/blog/92-http-cloning
if there is anything we can do to help resolve this issue please let us know.
cheers,
Yves
--
perl -Mre=debug -e "/just|another|perl|hacker/"
^ permalink raw reply
* Re: [PATCH] Clarify git-format-patch --in-reply-to
From: Miklos Vajna @ 2008-12-19 22:33 UTC (permalink / raw)
To: jidanni; +Cc: nanako3, gitster, git
In-Reply-To: <87k59vby27.fsf@jidanni.org>
[-- Attachment #1: Type: text/plain, Size: 778 bytes --]
On Sat, Dec 20, 2008 at 06:27:28AM +0800, jidanni@jidanni.org wrote:
> NS> I understand that "Signed-off-by" is about code ownership and
> NS> thought that the official history prefers to have a real name
> NS> instead of a pseudonym. Perhaps you would want to say "Dan
> NS> Jacobson <jidanni@jidanni.org>" or something similar?
>
> Thanks but I want to be http://zh.wikipedia.org/wiki/?????????
> (which is what all my ID cards say) and not any
> http://en.wikipedia.org/wiki/Jacobson , http://en.wikipedia.org/wiki/Jacobsen .
> I've completed a name-change operation, and prefer to use my post-op name.
Who said you can't use utf-8 chars in the author field?
See
http://repo.or.cz/w/git.git?a=commit;h=6b312253cb6e8b21e74882a3ae0972fac1290244
for example.
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH] Clarify git-format-patch --in-reply-to
From: Bernt Hansen @ 2008-12-19 22:01 UTC (permalink / raw)
To: jidanni; +Cc: gitster, git
In-Reply-To: <87k59wc73n.fsf@jidanni.org>
jidanni@jidanni.org writes:
> Signed-off-by: jidanni <jidanni@jidanni.org>
>
> diff --git a/git-format-patch.txt b/git-format-patch.txt
> index ee27eff..04958de 100644
> --- a/git-format-patch.txt
> +++ b/git-format-patch.txt
> @@ -130 +130,2 @@ include::diff-options.txt[]
> - provide a new patch series.
> + provide a new patch series. Generates coresponding References and
^^^^^^^^^^^^
Typo corresponding
> + In-Reply-To headers. Angle brackets around <Message-Id> are optional.
> --
> 1.5.6.5
^ permalink raw reply
* Re: [PATCH] Clarify git-format-patch --in-reply-to
From: jidanni @ 2008-12-19 22:27 UTC (permalink / raw)
To: nanako3; +Cc: gitster, git
In-Reply-To: <20081220065135.6117@nanako3.lavabit.com>
NS> I understand that "Signed-off-by" is about code ownership and
NS> thought that the official history prefers to have a real name
NS> instead of a pseudonym. Perhaps you would want to say "Dan
NS> Jacobson <jidanni@jidanni.org>" or something similar?
Thanks but I want to be http://zh.wikipedia.org/wiki/積丹尼
(which is what all my ID cards say) and not any
http://en.wikipedia.org/wiki/Jacobson , http://en.wikipedia.org/wiki/Jacobsen .
I've completed a name-change operation, and prefer to use my post-op name.
Childish? Bingo.
^ permalink raw reply
* Re: Git Notes idea.
From: Govind Salinas @ 2008-12-19 22:24 UTC (permalink / raw)
To: Jeff King; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <20081219212536.GA27168@coredump.intra.peff.net>
On Fri, Dec 19, 2008 at 3:25 PM, Jeff King <peff@peff.net> wrote:
> On Fri, Dec 19, 2008 at 11:38:55AM -0600, Govind Salinas wrote:
>
>> This is my concern with keeping a history of the notes pseudo-branch. Let
>> me restate what you are saying with an example
>>
>> 1) on branch A commit a
>> 2) add note a`
>> 3) on branch B commit b
>> 4) add note b`
>> 5) on branch B commit c
>> 6) add note c`
>> 7) delete branch A
>> 8) gc after a time such that a is pruned
>>
>> Now either I will always have a note a` as an object forever even though
>> the only commit that points to it is gone or I have to re-write the history of
>> the notes branch from the point that it was added.
>
> Yes, that's correct.
>
>> Given this problem, is it really such a good idea to keep the history?
>
> I think so. Otherwise how will you push and pull notes? You won't even
> know which one is the more recent tree, let alone handle any merges
> caused by editing notes in two places.
Couldn't you simply merge your tree and theirs even if there is no
history. You would have to find a way to handle merges in any event
since they could just as easily happen if you have a history.
>> On the other, other hand, pushing and pulling notes if a history is kept
>> will have to involve a lot of rebasing/merging.
>
> Depending on your workflow. It might just involve a lot of fast forwards
> if the note writer is in one place.
>
>> A possible solution is that notes are per-branch,
>>
>> refs/notes/heads/master
>> refs/notes/heads/foo/bar
>> refs/notes/remotes/baz/bang
>
> Sorry, I don't quite get it. You are asking for per-branch notes that
> keep history, or per-branch notes that don't keep history?
Both, at the end of my previous mail I said...
"So perhaps we could use the above layout with no history?"
But they are two separate fixes to 2 different problems.
> If the former, then you haven't solved the cruft accumulation problem.
> You can get obsolete notes in your note history by rebasing on a branch
> that is long-running (which is OK as long as you haven't published
> _those particular_ commits). Or are you proposing to rebase and cleanup
> the notes history every time you do a destructive operation?
Yes, it does not solve that problem. But it does solve things like
Dev1 and Dev2 both have branches A and topic branch B. and they
are in refs/notes/public (or refs/notes or something not branch specific).
Dev1 adds 100 notes to topic B, lets say half of them are obsolete due
to rebases or whatever. Dev2 pulls A and updates their notes
as well. Now Dev2 has acquired all the notes from Dev1 including the
obsolete ones. So you have 100 commits, 100 blobs and all the new
trees that go with them that the user was not interested in.
Run this across 1000 users and you have a lot of cruft.
Now, if instead we have a per-branch notes scheme, then you only get
the cruft from the branches you were interested in. If you remove the
history you could end up with no cruft because gc should handle it.
> If the latter, then I don't see how you've solved the push-pull and
> merge problem (which you need history for).
What git-fetch would have to do is say. This is a note. The remote
sha is not the same as mine, i will treat this as a force and fetch the
objects without checking history and then run a merge on the 2
commits. The notes merge could have its own strategy that checked
if an object exists before deciding to add a new item or delete a
removed one. Then the user would only have to intervene if the
notes where edited.
> But in either case, I think the solution is non-intuitive. If I annotate
> a commit, and then merge the commit from one branch to another,
> shouldn't the annotation stay?
Sure, either the merge command could run 2 merges, one for the
real branch and one for the notes pseudo branch or the user
could be required to do that manually. I would think that doing
it automatically would be good. Especially if you use a special
merge strategy.
> Really, I am not sure this is worth getting too concerned about. Since
> we are talking about cruft in the _history_ of the notes branch, it
> won't impact actual notes usage (which will always just deal with the
> most recent tree). So really we are talking about some uninteresting
> objects in the db, which wastes some space. In practice, I suspect this
> won't be that large because notes themselves are going to be relatively
> short and in many cases, repetitive (i.e., many annotations may have the
> same blob hash for several commits). And if it is a space problem, then
> the right solution is to periodically truncate the notes history by
> rewriting.
You are correct of course that it will just be wasted space. But I am
concerned that it could end up being a lot of wasted space. I mean, what
if every person who contributed to the kernel contributed note cruft. Users
have branches that they consider public, so they might go into the a public
note store if there is no per-branch store. Or errant users could use the
public store without understanding how they are affecting the central repo,
including the obsolete ones.
If you *really* don't think its something to be worried about then I am OK
with that since you have a lot more experience with this, but it sounds hairy
to me.
Thanks,
Govind.
^ permalink raw reply
* Re: [PATCH] Clarify git-format-patch --in-reply-to
From: Miklos Vajna @ 2008-12-19 22:22 UTC (permalink / raw)
To: Nanako Shiraishi; +Cc: jidanni, gitster, git
In-Reply-To: <20081220065135.6117@nanako3.lavabit.com>
[-- Attachment #1: Type: text/plain, Size: 555 bytes --]
On Sat, Dec 20, 2008 at 06:51:35AM +0900, Nanako Shiraishi <nanako3@lavabit.com> wrote:
> I understand that "Signed-off-by" is about code ownership and thought
> that the official history prefers to have a real name instead of a
> pseudonym. Perhaps you would want to say "Dan Jacobson
> <jidanni@jidanni.org>" or something similar?
I don't think it's a requirement, see 2b36b14 for example. Though yes,
in general it's considered childish to hide behind a nickname, instead
of using your real name. (ESR has a section about this in the "hacker
howto".)
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* [PATCH] diff.c: fix pointer type warning
From: René Scharfe @ 2008-12-19 22:10 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Mark Burton, Linus Torvalds, Git Mailing List
In-Reply-To: <20081218121118.3635c53c@crow>
As Mark Burton noted, the conversion to strbuf_readlink() caused a
compile warning on some architectures:
> diff.c: In function ‘diff_populate_filespec’:
> diff.c:1781: warning: passing argument 2 of ‘strbuf_detach’ from incompatible pointer type
A pointer to an unsigned long is given while a pointer to a size_t is
expected; the two types are not considered to be equivalent everywhere.
The real fix would be to change the type of the size member of struct
diff_filespec to size_t, but that would cause other warnings in
connection with functions expecting unsigned long, and attempts to fix
them might loose an avalanche of changes. Later. This patch just
silences the warning by adding an (implicit) casting step.
Reported-by: Mark Burton <markb@ordern.com>
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
diff.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/diff.c b/diff.c
index f160c1a..0484601 100644
--- a/diff.c
+++ b/diff.c
@@ -1778,7 +1778,8 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
if (strbuf_readlink(&sb, s->path, s->size))
goto err_empty;
- s->data = strbuf_detach(&sb, &s->size);
+ s->size = sb.len;
+ s->data = strbuf_detach(&sb, NULL);
s->should_free = 1;
return 0;
}
^ permalink raw reply related
* Re: [PATCH] Clarify git-format-patch --in-reply-to
From: Nanako Shiraishi @ 2008-12-19 21:51 UTC (permalink / raw)
To: jidanni; +Cc: gitster, git
In-Reply-To: <87k59wc73n.fsf@jidanni.org>
Quoting jidanni@jidanni.org:
> Signed-off-by: jidanni <jidanni@jidanni.org>
I understand that "Signed-off-by" is about code ownership and thought that the official history prefers to have a real name instead of a pseudonym. Perhaps you would want to say "Dan Jacobson <jidanni@jidanni.org>" or something similar?
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply
* Re: Odd merge behaviour involving reverts
From: Nanako Shiraishi @ 2008-12-19 21:45 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, Alan, git
In-Reply-To: <7vocz8a6zk.fsf@gitster.siamese.dyndns.org>
Quoting Junio C Hamano <gitster@pobox.com>:
> I hope this clears up confusion and fear.
You are correct that I misunderstood what Alan meant by corrected branch.
I think your explanation will help people if we make it part of the documentation. Especially because two different cases need two different recovery methods, and people need to learn which is which.
Thank you for your detailed response.
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply
* Re: Git Notes idea.
From: Jeff King @ 2008-12-19 21:25 UTC (permalink / raw)
To: Govind Salinas; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <5d46db230812190938r4e8ff994gfcb616c750be0f22@mail.gmail.com>
On Fri, Dec 19, 2008 at 11:38:55AM -0600, Govind Salinas wrote:
> This is my concern with keeping a history of the notes pseudo-branch. Let
> me restate what you are saying with an example
>
> 1) on branch A commit a
> 2) add note a`
> 3) on branch B commit b
> 4) add note b`
> 5) on branch B commit c
> 6) add note c`
> 7) delete branch A
> 8) gc after a time such that a is pruned
>
> Now either I will always have a note a` as an object forever even though
> the only commit that points to it is gone or I have to re-write the history of
> the notes branch from the point that it was added.
Yes, that's correct.
> Given this problem, is it really such a good idea to keep the history?
I think so. Otherwise how will you push and pull notes? You won't even
know which one is the more recent tree, let alone handle any merges
caused by editing notes in two places.
> On the other, other hand, pushing and pulling notes if a history is kept
> will have to involve a lot of rebasing/merging.
Depending on your workflow. It might just involve a lot of fast forwards
if the note writer is in one place.
> A possible solution is that notes are per-branch,
>
> refs/notes/heads/master
> refs/notes/heads/foo/bar
> refs/notes/remotes/baz/bang
Sorry, I don't quite get it. You are asking for per-branch notes that
keep history, or per-branch notes that don't keep history?
If the former, then you haven't solved the cruft accumulation problem.
You can get obsolete notes in your note history by rebasing on a branch
that is long-running (which is OK as long as you haven't published
_those particular_ commits). Or are you proposing to rebase and cleanup
the notes history every time you do a destructive operation?
If the latter, then I don't see how you've solved the push-pull and
merge problem (which you need history for).
But in either case, I think the solution is non-intuitive. If I annotate
a commit, and then merge the commit from one branch to another,
shouldn't the annotation stay?
Really, I am not sure this is worth getting too concerned about. Since
we are talking about cruft in the _history_ of the notes branch, it
won't impact actual notes usage (which will always just deal with the
most recent tree). So really we are talking about some uninteresting
objects in the db, which wastes some space. In practice, I suspect this
won't be that large because notes themselves are going to be relatively
short and in many cases, repetitive (i.e., many annotations may have the
same blob hash for several commits). And if it is a space problem, then
the right solution is to periodically truncate the notes history by
rewriting.
-Peff
^ permalink raw reply
* Re: How to extract files out of a "git bundle", no matter what?
From: Jeff King @ 2008-12-19 20:51 UTC (permalink / raw)
To: jidanni; +Cc: mdl123, spearce, git
In-Reply-To: <87vdtfc389.fsf@jidanni.org>
On Sat, Dec 20, 2008 at 04:35:50AM +0800, jidanni@jidanni.org wrote:
> JK> - the object pack in the bundle is "thin", meaning it may contain
> JK> deltas against objects that are reachable from A, but not B. So even
> JK> _within_ a changed file, you may see only the changes from A to B.
>
> OK, we here at the police forensics department would be very happy if
> we could at least get some ASCII out of that .BDL file, even if it is
> just a diff shred,
> - The password to the time bomb was BLORFZ
> + The password to the time bomb is NORFLZ
> that would be fine. All we know is after the work PACK it is all
> binary, and git-unpack-objects and git-unpack-file don't work on it.
AFAIK, there is no tool to try salvaging strings from an incomplete pack
(and you can't just run "strings" because the deltas are zlib
compressed). So if I were in the police forensics department, I think I
would read Documentation/technical/pack-format.txt and start hacking a
solution as quickly as possible.
-Peff
^ permalink raw reply
* Re: jgit doesn't support "compare with" and "replace with"?
From: Robin Rosenberg @ 2008-12-19 20:39 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Martin_S, git
In-Reply-To: <20081219152045.GR32487@spearce.org>
fredag 19 december 2008 16:20:45 skrev Shawn O. Pearce:
> Martin_S <iksdrijf@yahoo.com> wrote:
> >
> > Hi, I'm using eclipse 3.4 and jgit 0.4. The right click context menus don't
> > list "compare with" and "replace with". Am I doing something wrong?
>
> We haven't implemented them in EGit. So its not surprising that
> they aren't appearing.
Actually, we had it in v0.3 though it didn't always work. In particular it didn't work on
Windows...
The history rewrited killed it, but re-adding it would not be to hard, It's mostly about passing two explicit
versions to compare, which is already done in
The old version disappeared in 07f04ae5b1771069667028d225196daff29402a0, checkout out and rebuild
if you are really desperate. Reverting it is an option, but that is not trivial either so going forward and
reimplementing it (correctly this time) is a more appealing approach. Dependig on your needs, i.e. if
you only don't need clone/fetch/push you could go back to the commit mentioned above. The closest
tagged version is v0.3.1. As a bonus it draws the graph correctly, though it is not optimal.
-- robin
^ permalink raw reply
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