* Re: Git Notes idea.
From: Jeff King @ 2008-12-20 4:54 UTC (permalink / raw)
To: Govind Salinas; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <5d46db230812191424m14e82c5fx1c1c12027db901ed@mail.gmail.com>
On Fri, Dec 19, 2008 at 04:24:01PM -0600, Govind Salinas wrote:
> > 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.
Let's say I have a tree T1 like this:
$COMMIT_A -> $BLOB_A
$COMMIT_B -> $BLOB_B1
and a tree T2 like this:
$COMMIT_B -> $BLOB_B2
$COMMIT_C -> $BLOB_C
what is the correct merge? Was $COMMIT_A added in T1, or deleted in T2?
How about $COMMIT_C? Even if you went with a strategy like "always add
from both" (which I don't think is a good idea, because deleted notes
will keep popping back up) you have a conflict with $COMMIT_B. Should
it be B1 or B2? You can't tell if B1 became B2, vice versa, or if there
is a true merge conflict.
> > 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.
OK. But my point is that this is an incomplete solution. You can _still_
get cruft, and you _still_ have to deal with that cruft some other way.
So we will still end up having to implement something else. And I might
even be fine with a partial solution that helped some if it didn't come
with a cost, but I think the "notes stick to branches" behavior is
strictly worse.
> > 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.
I don't like that because:
- the user is going to end up manually resolving merge conflicts for
things that _should_ have been fast forwards. But much worse, it's
going to be on content they may never even have seen before. How
will they decide which is which?
- how do you push notes? There's no opportunity to handle the merge
on the remote side. And you can't just pull, merge locally, and push
what is now a fast-forward, because there is no concept of
fast-forward without history.
- Suddenly pulling and pushing notes isn't just taken care of by the
usual ref transfer mechanisms. We have to implement a whole new
system.
> 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
What if every person who contributed to the kernel contributed history
cruft? It's really the same problem, and it is solved by people keeping
their trees clean (via rebase) and being picky about how data comes into
your tree (i.e., don't pull from people with cruft). I suspect Linus
wouldn't pull notes at all (and they wouldn't make it over patch
transmission anyway). But in a workflow that is pulling the notes, the
right time to clean up history is probably before publishing. That is,
you can rebase and clean up your notes history just before you push it
to somewhere public, just like you might clean up messy history.
> 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.
It is hairy, and I wish there were a better solution. But I think every
other option is much worse.
-Peff
^ permalink raw reply
* [PATCH] Remove the requirement opaquelocktoken uri scheme
From: Kirill A. Korinskiy @ 2008-12-20 6:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, catap
In-Reply-To: <7vljucbows.fsf@gitster.siamese.dyndns.org>
The program flow of pushing over http is:
- call lock_remote() to issue a DAV_LOCK request to the server to lock
info/refs and branch refs being pushed into; handle_new_lock_ctx() is
used to parse its response to populate "struct remote_lock" that is
returned from lock_remote();
- send objects;
- call unlock_remote() to drop the lock.
The handle_new_lock_ctx() function assumed that the server will use a
lock token in opaquelocktoken URI scheme, which may have been an Ok
assumption under RFC 2518, but under RFC 4918 which obsoletes the older
standard it is not necessarily true.
This resulted in push failure (often resulted in "cannot lock existing
info/refs" error message) when talking to a server that does not use
opaquelocktoken URI scheme.
Signed-off-by: Kirill A. Korinskiy <catap@catap.ru>
---
http-push.c | 14 ++++++--------
1 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/http-push.c b/http-push.c
index 5cecef434a7740a3f853462978c3e071b4da7e74..7c6460919bf3eba10c46cede11ffdd9c53fd2dd2 100644
--- a/http-push.c
+++ b/http-push.c
@@ -595,7 +595,7 @@ static int refresh_lock(struct remote_lock *lock)
lock->refreshing = 1;
if_header = xmalloc(strlen(lock->token) + 25);
- sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token);
+ sprintf(if_header, "If: (<%s>)", lock->token);
sprintf(timeout_header, "Timeout: Second-%ld", lock->timeout);
dav_headers = curl_slist_append(dav_headers, if_header);
dav_headers = curl_slist_append(dav_headers, timeout_header);
@@ -1120,10 +1120,8 @@ static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed)
lock->timeout =
strtol(ctx->cdata + 7, NULL, 10);
} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
- if (!prefixcmp(ctx->cdata, "opaquelocktoken:")) {
- lock->token = xmalloc(strlen(ctx->cdata) - 15);
- strcpy(lock->token, ctx->cdata + 16);
- }
+ lock->token = xmalloc(strlen(ctx->cdata) + 1);
+ strcpy(lock->token, ctx->cdata);
}
}
}
@@ -1308,7 +1306,7 @@ static int unlock_remote(struct remote_lock *lock)
int rc = 0;
lock_token_header = xmalloc(strlen(lock->token) + 31);
- sprintf(lock_token_header, "Lock-Token: <opaquelocktoken:%s>",
+ sprintf(lock_token_header, "Lock-Token: <%s>",
lock->token);
dav_headers = curl_slist_append(dav_headers, lock_token_header);
@@ -1722,7 +1720,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)
struct curl_slist *dav_headers = NULL;
if_header = xmalloc(strlen(lock->token) + 25);
- sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token);
+ sprintf(if_header, "If: (<%s>)", lock->token);
dav_headers = curl_slist_append(dav_headers, if_header);
strbuf_addf(&out_buffer.buf, "%s\n", sha1_to_hex(sha1));
@@ -1941,7 +1939,7 @@ static void update_remote_info_refs(struct remote_lock *lock)
add_remote_info_ref, &buffer.buf);
if (!aborted) {
if_header = xmalloc(strlen(lock->token) + 25);
- sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token);
+ sprintf(if_header, "If: (<%s>)", lock->token);
dav_headers = curl_slist_append(dav_headers, if_header);
slot = get_active_slot();
--
1.5.6.5
^ permalink raw reply related
* [ANNOUNCE] GIT 1.6.0.6
From: Junio C Hamano @ 2008-12-20 6:40 UTC (permalink / raw)
To: git; +Cc: linux-kernel
The latest maintenance release GIT 1.6.0.6 is available at the
usual places:
http://www.kernel.org/pub/software/scm/git/
git-1.6.0.6.tar.{gz,bz2} (source tarball)
git-htmldocs-1.6.0.6.tar.{gz,bz2} (preformatted docs)
git-manpages-1.6.0.6.tar.{gz,bz2} (preformatted docs)
The RPM binary packages for a few architectures are also provided
as courtesy.
RPMS/$arch/git-*-1.6.0.6-1.fc9.$arch.rpm (RPM)
Among miscellaneous fixes, this contains a local gitweb security fix.
Maintenance releases for older versions (v1.5.4.7, v1.5.5.6 and v1.5.6.6)
are also available at the same place.
----------------------------------------------------------------
Changes since v1.6.0.5 are as follows:
David Aguilar (1):
git-mergetool: properly handle "git mergetool -- filename"
Deskin Miller (1):
git-svn: Make following parents atomic
Jim Meyering (1):
git-config.txt: fix a typo
Johannes Schindelin (2):
fast-import: close pack before unlinking it
fast-export: deal with tag objects that do not have a tagger
Junio C Hamano (6):
work around Python warnings from AsciiDoc
git-show: do not segfault when showing a bad tag
pager: do not dup2 stderr if it is already redirected
gitweb: do not run "git diff" that is Porcelain
GIT 1.5.4.7
fast-import: make tagger information optional
Linus Torvalds (1):
fsck: reduce stack footprint
Markus Heidelberg (1):
Documentation: fix typos, grammar, asciidoc syntax
Miklos Vajna (1):
SubmittingPatches: mention the usage of real name in Signed-off-by: lines
Nicolas Pitre (1):
make sure packs to be replaced are closed beforehand
Wu Fengguang (1):
git-send-email: handle email address with quoted comma
^ permalink raw reply
* [Security] gitweb local privilege escalation (fix)
From: Junio C Hamano @ 2008-12-20 6:46 UTC (permalink / raw)
To: git; +Cc: linux-kernel
In-Reply-To: <7vljub1h92.fsf@gitster.siamese.dyndns.org>
[-- Attachment #1: Type: text/plain, Size: 1050 bytes --]
Current gitweb has a possible local privilege escalation bug that allows a
malicious repository owner to run a command of his choice by specifying
diff.external configuration variable in his repository and running a
crafted gitweb query.
Recent (post 1.4.3) gitweb itself never generates a link that would result
in such a query, and the safest and cleanest fix to this issue is to
simply drop the support for it. Maintenance release v1.6.0.6, v1.5.6.6,
v1.5.5.6 and v1.5.4.7 are already available at k.org (see the announcement
for v1.6.0.6 I sent out a few minutes ago), and the master branch and
others pushed out tonight have the same fix.
This message contains two patches (credits go to Matt McCutchen, Jeff King
and Jakub Narebski) to do the fix yourself:
(1) for Git 1.5.4.X, 1.5.5.X, and 1.5.6.X, and
(2) for Git 1.6.0.X.
Distro packagers and people on the vendor security list have been notified
about this fix earlier this week; people running gitweb from vendor
supplied binaries should be able to get updates from them as well.
[-- Attachment #2: gitweb hotfix for 1.5.[456].X series --]
[-- Type: text/plain, Size: 2313 bytes --]
>From dfff4b7aa42de7e7d58caeebe2c6128449f09b76 Mon Sep 17 00:00:00 2001
From: Junio C Hamano <gitster@pobox.com>
Date: Tue, 16 Dec 2008 19:42:02 -0800
Subject: [PATCH] gitweb: do not run "git diff" that is Porcelain
Jakub says that legacy-style URI to view two blob differences are never
generated since 1.4.3. This codepath runs "git diff" Porcelain from the
gitweb, which is a no-no. It can trigger diff.external command that is
specified in the configuration file of the repository being viewed.
This patch applies to v1.5.4 and later.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
gitweb/gitweb.perl | 38 ++------------------------------------
1 files changed, 2 insertions(+), 36 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index b582332..86a6ced 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -4809,43 +4809,9 @@ sub git_blobdiff {
or die_error(undef, "Open git-diff-tree failed");
}
- # old/legacy style URI
- if (!%diffinfo && # if new style URI failed
- defined $hash && defined $hash_parent) {
- # fake git-diff-tree raw output
- $diffinfo{'from_mode'} = $diffinfo{'to_mode'} = "blob";
- $diffinfo{'from_id'} = $hash_parent;
- $diffinfo{'to_id'} = $hash;
- if (defined $file_name) {
- if (defined $file_parent) {
- $diffinfo{'status'} = '2';
- $diffinfo{'from_file'} = $file_parent;
- $diffinfo{'to_file'} = $file_name;
- } else { # assume not renamed
- $diffinfo{'status'} = '1';
- $diffinfo{'from_file'} = $file_name;
- $diffinfo{'to_file'} = $file_name;
- }
- } else { # no filename given
- $diffinfo{'status'} = '2';
- $diffinfo{'from_file'} = $hash_parent;
- $diffinfo{'to_file'} = $hash;
- }
-
- # non-textual hash id's can be cached
- if ($hash =~ m/^[0-9a-fA-F]{40}$/ &&
- $hash_parent =~ m/^[0-9a-fA-F]{40}$/) {
- $expires = '+1d';
- }
-
- # open patch output
- open $fd, "-|", git_cmd(), "diff", @diff_opts,
- '-p', ($format eq 'html' ? "--full-index" : ()),
- $hash_parent, $hash, "--"
- or die_error(undef, "Open git-diff failed");
- } else {
+ # old/legacy style URI -- not generated anymore since 1.4.3.
+ if (!%diffinfo) {
die_error('404 Not Found', "Missing one of the blob diff parameters")
- unless %diffinfo;
}
# header
--
1.6.1.rc3.19.g66a9
[-- Attachment #3: gitweb hotfix for 1.6.0.X series --]
[-- Type: text/plain, Size: 1630 bytes --]
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index ced7bb7..804670c 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -4863,43 +4863,9 @@ sub git_blobdiff {
or die_error(500, "Open git-diff-tree failed");
}
- # old/legacy style URI
- if (!%diffinfo && # if new style URI failed
- defined $hash && defined $hash_parent) {
- # fake git-diff-tree raw output
- $diffinfo{'from_mode'} = $diffinfo{'to_mode'} = "blob";
- $diffinfo{'from_id'} = $hash_parent;
- $diffinfo{'to_id'} = $hash;
- if (defined $file_name) {
- if (defined $file_parent) {
- $diffinfo{'status'} = '2';
- $diffinfo{'from_file'} = $file_parent;
- $diffinfo{'to_file'} = $file_name;
- } else { # assume not renamed
- $diffinfo{'status'} = '1';
- $diffinfo{'from_file'} = $file_name;
- $diffinfo{'to_file'} = $file_name;
- }
- } else { # no filename given
- $diffinfo{'status'} = '2';
- $diffinfo{'from_file'} = $hash_parent;
- $diffinfo{'to_file'} = $hash;
- }
-
- # non-textual hash id's can be cached
- if ($hash =~ m/^[0-9a-fA-F]{40}$/ &&
- $hash_parent =~ m/^[0-9a-fA-F]{40}$/) {
- $expires = '+1d';
- }
-
- # open patch output
- open $fd, "-|", git_cmd(), "diff", @diff_opts,
- '-p', ($format eq 'html' ? "--full-index" : ()),
- $hash_parent, $hash, "--"
- or die_error(500, "Open git-diff failed");
- } else {
- die_error(400, "Missing one of the blob diff parameters")
- unless %diffinfo;
+ # old/legacy style URI -- not generated anymore since 1.4.3.
+ if (!%diffinfo) {
+ die_error('404 Not Found', "Missing one of the blob diff parameters")
}
# header
^ permalink raw reply related
* Re: [PATCH] git-send-email: handle email address with quoted comma
From: Junio C Hamano @ 2008-12-20 6:48 UTC (permalink / raw)
To: Wu Fengguang; +Cc: git@vger.kernel.org, Matt Kraai
In-Reply-To: <20081219081010.GA12494@localhost>
Wu Fengguang <fengguang.wu@intel.com> writes:
> Thank you for the helpful information. The patch is updated and tested
Thanks. I'll apply but it would be nice to have an additional test script
somewhere in t/t9001-send-email.sh to protect this change from regression
by future changes.
^ permalink raw reply
* Re: [PATCH] Documentation: fix typos, grammar, asciidoc syntax
From: Junio C Hamano @ 2008-12-20 6:48 UTC (permalink / raw)
To: markus.heidelberg; +Cc: git
In-Reply-To: <200812191314.19302.markus.heidelberg@web.de>
Markus Heidelberg <markus.heidelberg@web.de> writes:
> Signed-off-by: Markus Heidelberg <markus.heidelberg@web.de>
> ---
> Documentation/diff-format.txt | 2 +-
> Documentation/diff-generate-patch.txt | 6 +++---
> Documentation/git-commit.txt | 2 +-
> Documentation/git-diff-tree.txt | 4 ++--
> Documentation/git-mailinfo.txt | 2 +-
> Documentation/git-receive-pack.txt | 4 ++--
> Documentation/git-reflog.txt | 4 ++--
> Documentation/git-show-branch.txt | 4 ++--
> Documentation/git-submodule.txt | 2 +-
> Documentation/git-update-index.txt | 8 ++++----
> Documentation/gitcore-tutorial.txt | 8 ++++----
> Documentation/gitk.txt | 4 ++--
> Documentation/i18n.txt | 4 ++--
> 13 files changed, 27 insertions(+), 27 deletions(-)
Whew, quite a lot of typos there are.
> @@ -172,7 +172,7 @@ only the primary branches. In addition, if you happen to be on
> your topic branch, it is shown as well.
>
> ------------
> -$ git show-branch --reflog='10,1 hour ago' --list master
> +$ git show-branch --reflog="10,1 hour ago" --list master
> ------------
Is this just a personal taste, or a correction to typography?
Other than this one, I did not find anything else in your patch that
looked iffy. Thanks for lending a good set of eyeballs.
^ permalink raw reply
* Re: [PATCH 1/4] Introduce commit notes
From: Jeff King @ 2008-12-20 6:53 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0812200034450.30769@pacific.mpi-cbg.de>
On Sat, Dec 20, 2008 at 12:35:06AM +0100, Johannes Schindelin wrote:
> 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.
Hmm. I wanted to try some performance comparisons based on this
implementation, but I can't get your 1/4 to apply. Conflicts in
config.txt and cache.h when applying to master, and "sha1 information is
lacking or useless" for a 3-way merge. What did you base this on?
-Peff
^ permalink raw reply
* Re: [PATCH] Make git revert warn the user when reverting a merge commit.
From: Robin Rosenberg @ 2008-12-20 7:08 UTC (permalink / raw)
To: Boyd Stephen Smith Jr., Junio C Hamano; +Cc: git
In-Reply-To: <200812182039.15169.bss@iguanasuicide.net>
fredag 19 december 2008 03:39:15 skrev Boyd Stephen Smith Jr.:
> Signed-off-by: Boyd Stephen Smith Jr <bss@iguanasuicide.net>
> ---
> On Thursday 2008 December 18 18:21:25 Linus Torvalds wrote:
> > I suspect we should warn about reverting merges.
>
Or mention the reverted parent in the commit message since it is not obvious.
-- robin
>From e982c8cefcdeefd6e8aabc8c354bed69161f40ee Mon Sep 17 00:00:00 2001
From: Robin Rosenberg <robin.rosenberg@dewire.com>
Date: Sat, 20 Dec 2008 07:22:39 +0100
Subject: [PATCH] Mention reverted parent in commit message for reverted merge.
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
builtin-revert.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/builtin-revert.c b/builtin-revert.c
index 4038b41..fc59229 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -352,6 +352,10 @@ static int revert_or_cherry_pick(int argc, const char **argv)
add_to_msg(oneline_body + 1);
add_to_msg("\"\n\nThis reverts commit ");
add_to_msg(sha1_to_hex(commit->object.sha1));
+ if (commit->parents->next) {
+ add_to_msg(" removing\ncontributions from ");
+ add_to_msg(sha1_to_hex(parent->object.sha1));
+ }
add_to_msg(".\n");
} else {
base = parent;
--
1.6.1.rc3.36.g43d5.dirty
^ permalink raw reply related
* Re: [PATCH 1/4] Introduce commit notes
From: Robin Rosenberg @ 2008-12-20 7:55 UTC (permalink / raw)
To: Jeff King; +Cc: Johannes Schindelin, Govind Salinas, Git Mailing List
In-Reply-To: <20081220065337.GA2581@coredump.intra.peff.net>
lördag 20 december 2008 07:53:38 skrev Jeff King:
> On Sat, Dec 20, 2008 at 12:35:06AM +0100, Johannes Schindelin wrote:
>
> > 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.
>
> Hmm. I wanted to try some performance comparisons based on this
> implementation, but I can't get your 1/4 to apply. Conflicts in
> config.txt and cache.h when applying to master, and "sha1 information is
> lacking or useless" for a 3-way merge. What did you base this on?
patch(1) however can crunch it, with the exception of cache.h. Shouldn't
git am/appy and patch agree on git generated patches (without binary diffs)?
-- robin
^ permalink raw reply
* Re: [PATCH 1/4] Introduce commit notes
From: Jeff King @ 2008-12-20 8:05 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: Johannes Schindelin, Govind Salinas, Git Mailing List
In-Reply-To: <200812200855.14915.robin.rosenberg.lists@dewire.com>
On Sat, Dec 20, 2008 at 08:55:14AM +0100, Robin Rosenberg wrote:
> > Hmm. I wanted to try some performance comparisons based on this
> > implementation, but I can't get your 1/4 to apply. Conflicts in
> > config.txt and cache.h when applying to master, and "sha1 information is
> > lacking or useless" for a 3-way merge. What did you base this on?
>
> patch(1) however can crunch it, with the exception of cache.h. Shouldn't
> git am/appy and patch agree on git generated patches (without binary diffs)?
No. git apply is intentionally much more strict about applying under the
assumption that it is better to force a conflict than to silently apply
something that has a reasonable chance of being completely wrong.
And usually it is not a big deal because falling back to the 3-way merge
is a much nicer way of handling any conflicts _anyway_ (I find .rej
files so much more useless than conflict markers, personally).
In this case I was able to:
1. git am /the/patch
2. patch -p1 <.git/rebase-apply/patch
3. manually inspect the results for sanity, and fix up the cache.h
bit that failed totally
4. git add -u && git add notes.[ch]
5. git am --resolved
-Peff
^ permalink raw reply
* Re: rsync deprecated?
From: Mike Hommey @ 2008-12-20 8:15 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vljuei2xw.fsf@gitster.siamese.dyndns.org>
On Wed, Dec 17, 2008 at 07:20:59PM -0800, Junio C Hamano wrote:
> Markus Heidelberg <markus.heidelberg@web.de> writes:
>
> > in the "Merging external work" section of the gitcore-tutorial it is
> > stated that the rsync transport is deprecated. The description was added
> > in commit 914328a (Update tutorial., 2005-08-30) together with the
> > "deprecated" note. Having never heard/read this before and since this
> > commit is quite old, I wonder if it is still the case or there was a
> > solution for this problem.
>
> Sorry, I do not quite understand what you perceive as "this problem".
>
> It has been deprecated for too long a time. Maybe it is time to remove
> the support, instead of carrying the deprecated command forever? Is that
> the problem you are talking about?
>
> I tend to agree that rsync transport way outlived its usefulness, and not
> maintained at all. There may be unnoticed and undiagnosed bugs lurking,
> but nobody knows about it because nobody uses it.
Something that could well make this transport be maintained would be to
make it share code/internal API with the "local file transport".
Ideally, http, rsync and file could all share the same basis, and
ensuring the file transport to be functional would pretty much guarantee
all work.
Anyways, I'm not the right person to say that, as I've been failing to
deliver a beginning of such code for a year, now (damn, time goes too
fast).
Maybe libgit2 could be a good occasion to start some API like this,
though.
Mike
^ permalink raw reply
* Re: [PATCH 1/4] Introduce commit notes
From: Junio C Hamano @ 2008-12-20 8:17 UTC (permalink / raw)
To: Jeff King
Cc: Robin Rosenberg, Johannes Schindelin, Govind Salinas,
Git Mailing List
In-Reply-To: <20081220080546.GA4580@coredump.intra.peff.net>
Jeff King <peff@peff.net> writes:
> No. git apply is intentionally much more strict about applying under the
> assumption that it is better to force a conflict than to silently apply
> something that has a reasonable chance of being completely wrong.
>
> And usually it is not a big deal because falling back to the 3-way merge
> is a much nicer way of handling any conflicts _anyway_ (I find .rej
> files so much more useless than conflict markers, personally).
>
> In this case I was able to:
>
> 1. git am /the/patch
> 2. patch -p1 <.git/rebase-apply/patch
> 3. manually inspect the results for sanity, and fix up the cache.h
> bit that failed totally
> 4. git add -u && git add notes.[ch]
> 5. git am --resolved
I usually skip 2-4 and edit .git/rebase-apply/patch in place instead, and
run "git am" instead of step 5.
Why was the patch, that was based on something that is clearly different
from what other people work on, sent to the list in the first place? IOW,
what good does it do to show your patch if other people (plural) need to
spend a lot of time and head-scratching?
^ permalink raw reply
* Re: [PATCH] git-send-email: handle email address with quoted comma
From: Matt Kraai @ 2008-12-19 16:28 UTC (permalink / raw)
To: git
In-Reply-To: <20081219081010.GA12494@localhost>
Howdy,
Wu Fengguang <fengguang.wu <at> intel.com> writes:
> +sub split_addrs {
> + return parse_line('\s*,\s*', 1, @_);
> +}
> +
I'm not sure it's still a good idea to use parse_line. It should work OK for
now, since split_addrs is only passed one string. If anyone ever tries to pass
it a list of strings, however, parse_line will ignore all but the first.
--
Matt
^ permalink raw reply
* Re: [PATCH 1/4] Introduce commit notes
From: Jeff King @ 2008-12-20 8:23 UTC (permalink / raw)
To: Junio C Hamano
Cc: Robin Rosenberg, Johannes Schindelin, Govind Salinas,
Git Mailing List
In-Reply-To: <7vk59vz2dx.fsf@gitster.siamese.dyndns.org>
On Sat, Dec 20, 2008 at 12:17:46AM -0800, Junio C Hamano wrote:
> > 1. git am /the/patch
> > 2. patch -p1 <.git/rebase-apply/patch
> > 3. manually inspect the results for sanity, and fix up the cache.h
> > bit that failed totally
> > 4. git add -u && git add notes.[ch]
> > 5. git am --resolved
>
> I usually skip 2-4 and edit .git/rebase-apply/patch in place instead, and
> run "git am" instead of step 5.
How do you track down the source of the conflict to do the patch fixup?
In this case, it was a context line in the patch that had been deleted
in my version. Do you just find the appropriate chunk in what you have
already and visually compare?
-Peff
^ permalink raw reply
* Re: rsync deprecated?
From: demerphq @ 2008-12-20 10:12 UTC (permalink / raw)
To: Mike Hommey; +Cc: Junio C Hamano, git
In-Reply-To: <20081220081511.GA28212@glandium.org>
2008/12/20 Mike Hommey <mh@glandium.org>:
> On Wed, Dec 17, 2008 at 07:20:59PM -0800, Junio C Hamano wrote:
>> Markus Heidelberg <markus.heidelberg@web.de> writes:
>>
>> > in the "Merging external work" section of the gitcore-tutorial it is
>> > stated that the rsync transport is deprecated. The description was added
>> > in commit 914328a (Update tutorial., 2005-08-30) together with the
>> > "deprecated" note. Having never heard/read this before and since this
>> > commit is quite old, I wonder if it is still the case or there was a
>> > solution for this problem.
>>
>> Sorry, I do not quite understand what you perceive as "this problem".
>>
>> It has been deprecated for too long a time. Maybe it is time to remove
>> the support, instead of carrying the deprecated command forever? Is that
>> the problem you are talking about?
>>
>> I tend to agree that rsync transport way outlived its usefulness, and not
>> maintained at all. There may be unnoticed and undiagnosed bugs lurking,
>> but nobody knows about it because nobody uses it.
>
> Something that could well make this transport be maintained would be to
> make it share code/internal API with the "local file transport".
> Ideally, http, rsync and file could all share the same basis, and
> ensuring the file transport to be functional would pretty much guarantee
> all work.
Just for the record: cloning via rsync is broken currently. I reported
this actually only shortly before Junio made this comment. Apparently
the code to copy across HEAD is missing from the rsync code, although
it is present for HTTP code.
Is there a bug tracking tool that git uses? I asked on #git on irc and
they said to just mail the list, but ive not seen any response to my
mail at all and the timing of Junios comment makes me wonder if my
report was seen by list regulars at all.
cheers,
Yves
--
perl -Mre=debug -e "/just|another|perl|hacker/"
^ permalink raw reply
* RFC: Change whatchanged to report changes from merges by default?
From: Mark Burton @ 2008-12-20 10:42 UTC (permalink / raw)
To: git
Hi,
Is it just an accident of history or by design that whatchanged
requires the -m option to show changes introduced by merges but
diff and git log show those changes without requiring any extra
options?
Would it not make more sense to have git whatchanged show the changes
introduced by merges by default and then people can use the (already
supported) --no-merges option to suppress that behaviour?
It appears that just setting rev.ignore_merges to 0 in cmd_whatchanged()
would do the trick. Shall I submit a patch?
Mark
^ permalink raw reply
* Re: [Security] gitweb local privilege escalation (fix)
From: Jakub Narebski @ 2008-12-20 10:54 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, linux-kernel
In-Reply-To: <7vhc4z1gys.fsf@gitster.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Current gitweb has a possible local privilege escalation bug that allows a
> malicious repository owner to run a command of his choice by specifying
> diff.external configuration variable in his repository and running a
> crafted gitweb query.
>
> Recent (post 1.4.3) gitweb itself never generates a link that would result
> in such a query, and the safest and cleanest fix to this issue is to
> simply drop the support for it. Maintenance release v1.6.0.6, v1.5.6.6,
> v1.5.5.6 and v1.5.4.7 are already available at k.org (see the announcement
> for v1.6.0.6 I sent out a few minutes ago), and the master branch and
> others pushed out tonight have the same fix.
>From what I have found diff.external works only since v1.5.4 (see
commit cbe02100), so when gitweb started using git-diff for old
legacy links to not use $tmpdir and /usr/bin/diff -u it wasn't an
issue...
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* [PATCH] handle_remote_ls_ctx can parsing href starting at http://
From: Kirill A. Korinskiy @ 2008-12-20 11:23 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Kirill A. Korinskiy
The program call remote_ls() to get remote objects over http;
handle_remote_ls_ctx() is used to parse it's response to populated
"struct remote_ls_ctx" that is returned from remote_ls().
The handle_remote_ls_ctx() function assumed that the server will
returned local path in href field, but RFC 4918 demand of support full
URI (http://localhost/repo.git for example).
This resulted in push failure (git-http-push ask server
PROPFIND /repo.git/alhost:8080/repo.git/refs/) when a server returned
full URI.
Signed-off-by: Kirill A. Korinskiy <catap@catap.ru>
---
http-push.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/http-push.c b/http-push.c
index 7c6460919bf3eba10c46cede11ffdd9c53fd2dd2..abf0269e0fe20a43a6247fc7584dc2d58322a8fa 100644
--- a/http-push.c
+++ b/http-push.c
@@ -87,6 +87,7 @@ static struct object_list *objects;
struct repo
{
char *url;
+ char *path;
int path_len;
int has_info_refs;
int can_update_info_refs;
@@ -1424,9 +1425,10 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
ls->userFunc(ls);
}
} else if (!strcmp(ctx->name, DAV_PROPFIND_NAME) && ctx->cdata) {
- ls->dentry_name = xmalloc(strlen(ctx->cdata) -
+ char *path = strstr(ctx->cdata, remote->path);
+ ls->dentry_name = xmalloc(strlen(path) -
remote->path_len + 1);
- strcpy(ls->dentry_name, ctx->cdata + remote->path_len);
+ strcpy(ls->dentry_name, path + remote->path_len);
} else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
ls->dentry_flags |= IS_DIR;
}
@@ -2206,10 +2208,11 @@ int main(int argc, char **argv)
if (!remote->url) {
char *path = strstr(arg, "//");
remote->url = arg;
+ remote->path_len = strlen(arg);
if (path) {
- path = strchr(path+2, '/');
- if (path)
- remote->path_len = strlen(path);
+ remote->path = strchr(path+2, '/');
+ if (remote->path)
+ remote->path_len = strlen(remote->path);
}
continue;
}
@@ -2238,8 +2241,9 @@ int main(int argc, char **argv)
rewritten_url = xmalloc(strlen(remote->url)+2);
strcpy(rewritten_url, remote->url);
strcat(rewritten_url, "/");
+ remote->path = rewritten_url + (remote->path - remote->url);
+ remote->path_len++;
remote->url = rewritten_url;
- ++remote->path_len;
}
/* Verify DAV compliance/lock support */
--
1.5.6.5
^ permalink raw reply related
* Re: [Security] gitweb local privilege escalation (fix)
From: Nanako Shiraishi @ 2008-12-20 11:26 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, linux-kernel
Quoting Jakub Narebski <jnareb@gmail.com>:
> Junio C Hamano <gitster@pobox.com> writes:
>
>> Current gitweb has a possible local privilege escalation bug that allows a
>> malicious repository owner to run a command of his choice by specifying
>> diff.external configuration variable in his repository and running a
>> crafted gitweb query.
>>
>> Recent (post 1.4.3) gitweb itself never generates a link that would result
>> in such a query, and the safest and cleanest fix to this issue is to
>> simply drop the support for it. Maintenance release v1.6.0.6, v1.5.6.6,
>> v1.5.5.6 and v1.5.4.7 are already available at k.org (see the announcement
>> for v1.6.0.6 I sent out a few minutes ago), and the master branch and
>> others pushed out tonight have the same fix.
>
> From what I have found diff.external works only since v1.5.4 (see
> commit cbe02100), so when gitweb started using git-diff for old
> legacy links to not use $tmpdir and /usr/bin/diff -u it wasn't an
> issue...
Sorry, but I do not understand what you are trying to say.
The maintenance releases Junio listed above go only as far back as v1.5.4.X series, so it covers the necessary range of versions, and no further back than that. Do you see a problem with that?
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply
* [PATCH] Add a documentat on how to revert a faulty merge
From: Nanako Shiraishi @ 2008-12-20 11:27 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Linus and Junio explained issues that are involved in reverting a merge
and how to continue working with a branch that was updated since such a
revert on the mailing list. This is to help new people who did not see
these messages.
Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
---
Documentation/howto/revert-a-faulty-merge.txt | 179 +++++++++++++++++++++++++
1 files changed, 179 insertions(+), 0 deletions(-)
create mode 100644 Documentation/howto/revert-a-faulty-merge.txt
diff --git a/Documentation/howto/revert-a-faulty-merge.txt b/Documentation/howto/revert-a-faulty-merge.txt
new file mode 100644
index 0000000..c3ef24f
--- /dev/null
+++ b/Documentation/howto/revert-a-faulty-merge.txt
@@ -0,0 +1,179 @@
+Date: Fri, 19 Dec 2008 00:45:19 -0800
+From: Linus Torvalds <torvalds@linux-foundation.org>, Junio C Hamano <gitster@pobox.com>
+Subject: Re: Odd merge behaviour involving reverts
+Abstract: Sometimes a branch that was already merged to the mainline
+ is later found to be faulty. Linus and Junio give guidance on
+ recovering from such a premature merge and continuing development
+ after the offending branch is fixed.
+Message-ID: <7vocz8a6zk.fsf@gitster.siamese.dyndns.org>
+References: <alpine.LFD.2.00.0812181949450.14014@localhost.localdomain>
+
+Alan <alan@clueserver.org> said:
+
+ I have a master branch. We have a branch off of that that some
+ developers are doing work on. They claim it is ready. We merge it
+ into the master branch. It breaks something so we revert the merge.
+ They make changes to the code. they get it to a point where they say
+ it is ok and we merge again.
+
+ When examined, we find that code changes made before the revert are
+ not in the master branch, but code changes after are in the master
+ branch.
+
+and asked for help recovering from this situation.
+
+The history immediately after the "revert of the merge" would look like
+this:
+
+ ---o---o---o---M---x---x---W
+ /
+ ---A---B
+
+where A and B are on the side development that was not so good, M is the
+merge that brings those premature changes into the mainline, x are changes
+unrelated to what the side branch did and already made on the mainline,
+and W is the "revert of the merge M" (doesn't W look M upside down?).
+IOW, "diff W^..W" is similar to "diff -R M^..M".
+
+Such a "revert" of the merge can be made with:
+
+ $ git revert -m 1 M
+
+After the develpers of the side branch fixes up, the history may look like
+this:
+
+ ---o---o---o---M---x---x---W---x
+ /
+ ---A---B-------------------C---D
+
+where C and D are to fix what was broken in A and B, and you may already
+have some other changes on the mainline after W.
+
+If you merge the updated side branch (with D at its tip), none of the
+changes made in A nor B will be in the result, because they were reverted
+by W. That is what Alan saw.
+
+Linus explains the situation:
+
+ Reverting a regular commit just effectively undoes what that commit
+ did, and is fairly straightforward. But reverting a merge commit also
+ undoes the _data_ that the commit changed, but it does absolutely
+ nothing to the effects on _history_ that the merge had.
+
+ So the merge will still exist, and it will still be seen as joining
+ the two branches together, and future merges will see that merge as
+ the last shared state - and the revert that reverted the merge brought
+ in will not affect that at all.
+
+ So a "revert" undoes the data changes, but it's very much _not_ an
+ "undo" in the sense that it doesn't undo the effects of a commit on
+ the repository history.
+
+ So if you think of "revert" as "undo", then you're going to always
+ miss this part of reverts. Yes, it undoes the data, but no, it doesn't
+ undo history.
+
+In such a situation, you would want to first revert the previous revert,
+which would make the history look like this:
+
+ ---o---o---o---M---x---x---W---x---Y
+ /
+ ---A---B-------------------C---D
+
+where Y is the revert of W. Such a "revert of the revert" can be done
+with:
+
+ $ git revert W
+
+This history would (ignoring possible conflicts between what W and W..Y
+changed) be equivalent to not having W nor Y at all in the history:
+
+ ---o---o---o---M---x---x-------x----
+ /
+ ---A---B-------------------C---D
+
+and merging the side branch again will not have conflict arising from an
+earlier revert and revert of the revert.
+
+ ---o---o---o---M---x---x-------x-------*
+ / /
+ ---A---B-------------------C---D
+
+Of course the changes made in C and D still can conflict with what was
+done by any of the x, but that is just a normal merge conflict.
+
+On the other hand, if the developers of the side branch discarded their
+faulty A and B, and redone the changes on top of the updated master branch
+after the revert, the history would have looked like this:
+
+ ---o---o---o---M---x---x---W---x---x
+ / \
+ ---A---B A'--B'--C'
+
+If you reverted the revert in such a case as in the previous example:
+
+ ---o---o---o---M---x---x---W---x---x---Y---*
+ / \ /
+ ---A---B A'--B'--C'
+
+where Y is the revert of W, A' and B'are rerolled A and B, and there may
+also be a further fix-up C' on the side branch. "diff Y^..Y" is similar
+to "diff -R W^..W" (which in turn means it is similar to "diff M^..M"),
+and "diff A'^..C'" by definition would be similar but different from that,
+because it is a rerolled series of the earlier change. There would be a
+lot of overlapping change that results in conflicts. So do not do "revert
+of revert" blindly.
+
+ ---o---o---o---M---x---x---W---x---x
+ / \
+ ---A---B A'--B'--C'
+
+In the history with rebased side branch, W (and M) are behind the merge
+base of the updated branch and the tip of the master, and they should
+merge without the past faulty merge and its revert getting in the way.
+
+To recap, these are two very different scenarios, and wants two very
+different resolution strategies:
+
+ - If the faulty side branch was fixed by adding corrections on top, then
+ doing a revert of the previous revert would be the right thing to do.
+
+ - If the faulty side branch whose effects were discarded by an earlier
+ revert of a merge was rebuilt from scratch (i.e. rebasing and fixing,
+ as you seem to have interpreted), then re-merging the result without
+ doing anything else fancy would be the right thing to do.
+
+However, there are things to keep in mind when reverting a merge (and
+reverting such a revert).
+
+For example, think about what reverting a merge (and then reverting the
+revert) does to bisectability. Ignore the fact that the revert of a revert
+is undoing it - just think of it as a "single commit that does a lot".
+Because that is what it does.
+
+When you have a problem you are chasing down, and you hit a "revert this
+merge", what you're hitting is essentially a single commit that contains
+all the changes (but obviously in reverse) of all the commits that got
+merged. So it's debugging hell, because now you don't have lots of small
+changes that you can try to pinpoint which _part_ of it changes.
+
+But does it all work? Sure it does. You can revert a merge, and from a
+purely technical angle, git did it very naturally and had no real
+troubles. It just considered it a change from "state before merge" to
+"state after merge", and that was it. Nothing complicated, nothing odd,
+nothing really dangerous. Git will do it without even thinking about it.
+
+So from a technical angle, there's nothing wrong with reverting a merge,
+but from a workflow angle it's something that you generally should try to
+avoid.
+
+If at all possible, for example, if you find a problem that got merged
+into the main tree, rather than revert the merge, try _really_ hard to
+bisect the problem down into the branch you merged, and just fix it, or
+try to revert the individual commit that caused it.
+
+Yes, it's more complex, and no, it's not always going to work (sometimes
+the answer is: "oops, I really shouldn't have merged it, because it wasn't
+ready yet, and I really need to undo _all_ of the merge"). So then you
+really should revert the merge, but when you want to re-do the merge, you
+now need to do it by reverting the revert.
--
1.6.1.rc3
--
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/
^ permalink raw reply related
* Re: [PATCH 4/4] Add an expensive test for git-notes
From: Johannes Schindelin @ 2008-12-20 11:51 UTC (permalink / raw)
To: Boyd Stephen Smith Jr.; +Cc: Git Mailing List, Jeff King, Govind Salinas
In-Reply-To: <200812191749.43512.bss@iguanasuicide.net>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 437 bytes --]
Hi,
On Fri, 19 Dec 2008, Boyd Stephen Smith Jr. wrote:
> On Friday 2008 December 19 17:37:15 Johannes Schindelin wrote:
> > + test_expect_success 'notes timing' "time_notes 100"
> ^^^
> Probably should be ${count}.
No. It times a git log 100 times (actually, 99 times due to a thinko).
This is only to protect against jitter, otherwise I'd do it only once.
Hth,
Dscho
^ permalink raw reply
* [PATCH v2 0/4] Notes, reloaded
From: Johannes Schindelin @ 2008-12-20 12:04 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <20081220065337.GA2581@coredump.intra.peff.net>
My apologies; I forgot to rebase the series from my personal fork to Junio's
next. This is the version that should apply cleanly.
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
* [PATCH v2 1/4] Introduce commit notes
From: Johannes Schindelin @ 2008-12-20 12:05 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0812201304210.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 21ea165..b35a32a 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -422,6 +422,21 @@ relatively high IO latencies. With this set to 'true', git will do the
index comparison to the filesystem data in parallel, allowing
overlapping IO's.
+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 5fcff9a..dc0a324 100644
--- a/Makefile
+++ b/Makefile
@@ -370,6 +370,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
@@ -451,6 +452,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 9dabcc7..9192853 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);
@@ -546,6 +548,7 @@ enum rebase_setup_type {
extern enum branch_track git_branch_track;
extern enum rebase_setup_type autorebase;
+extern char *notes_ref_name;
#define GIT_REPO_VERSION 0
extern int repository_format_version;
diff --git a/commit.c b/commit.c
index c99db16..10e532a 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 790405a..e5d5b4b 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 e278bce..0edae21 100644
--- a/environment.c
+++ b/environment.c
@@ -45,6 +45,7 @@ enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
/* 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 f6ff312..2d2872f 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;
@@ -881,5 +882,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.412.ga72b
^ permalink raw reply related
* [PATCH v2 2/4] Add a script to edit/inspect notes
From: Johannes Schindelin @ 2008-12-20 12:05 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0812201304210.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 327e660..ac5fbf4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,6 +82,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 dc0a324..5082f0f 100644
--- a/Makefile
+++ b/Makefile
@@ -258,6 +258,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.412.ga72b
^ permalink raw reply related
* [PATCH v2 3/4] Speed up git notes lookup
From: Johannes Schindelin @ 2008-12-20 12:05 UTC (permalink / raw)
To: Jeff King; +Cc: Govind Salinas, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0812201304210.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.412.ga72b
^ 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