* [PATCH] Implement git remote rename
From: Miklos Vajna @ 2008-11-03 18:26 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, Brandon Casey, git
In-Reply-To: <7v63nh1sc7.fsf@gitster.siamese.dyndns.org>
The new rename subcommand does the followings:
1) Renames the remote.foo configuration section to remote.bar
2) Updates the remote.bar.fetch refspecs
3) Updates the branch.*.remote settings
4) Renames the tracking branches: renames the normal refs and rewrites
the symrefs to point to the new refs.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
On Fri, Oct 24, 2008 at 04:33:28PM -0700, Junio C Hamano <gitster@pobox.com> wrote:
> Hmm, remote_get() can read from all three supported places that you
> can define remotes. Could you explain what happens if the old remote
> is read from say $GIT_DIR/remotes/origin and you are renaming it to
> "upstream" with "git remote rename origin upstream"?
Currently it dies because it can't rename config section 'remote.origin'
to 'remote.upstream'.
> I suspect that if you record where you read the configuration from in
> "struct remote" and add necessary code to remove the original when
> rename.old is *not* coming from in-config definition, you would make
> it possible for repositories initialized with older git that has
> either $GIT_DIR/branches/origin or $GIT_DIR/remotes/origin to be
> migrated to the in-config format using "git remote rename origin
> origin".
Yes, that's possible. I think the patch is already large enough that it
would be better to do it as a separate patch, but I like the idea.
One important step is that currently we have to care about the
remote.upstream.fetch variable, but once migration is supported, we have
to pay attention to remote.upstream.url/push as well.
In the meantime here is an updated patch which applies on top of
mv/maint-branch-m-symref. However, it is not meant for 'maint', of
course. :)
The old version did not "rename" (in fact it is not just a rename but it
replaces origin with upstream in the contents) symrefs properly, now the
testcases are extended to check for this, too.
Documentation/git-remote.txt | 6 ++
builtin-remote.c | 153 ++++++++++++++++++++++++++++++++++++++++++
t/t5505-remote.sh | 15 ++++
3 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index bb99810..7b227b3 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -11,6 +11,7 @@ SYNOPSIS
[verse]
'git remote' [-v | --verbose]
'git remote add' [-t <branch>] [-m <master>] [-f] [--mirror] <name> <url>
+'git remote rename' <old> <new>
'git remote rm' <name>
'git remote show' [-n] <name>
'git remote prune' [-n | --dry-run] <name>
@@ -61,6 +62,11 @@ only makes sense in bare repositories. If a remote uses mirror
mode, furthermore, `git push` will always behave as if `\--mirror`
was passed.
+'rename'::
+
+Rename the remote named <old> to <new>. All remote tracking branches and
+configuration settings for the remote are updated.
+
'rm'::
Remove the remote named <name>. All remote tracking branches and
diff --git a/builtin-remote.c b/builtin-remote.c
index e396a3a..1ca6cdb 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -10,6 +10,7 @@
static const char * const builtin_remote_usage[] = {
"git remote",
"git remote add <name> <url>",
+ "git remote rename <old> <new>",
"git remote rm <name>",
"git remote show <name>",
"git remote prune <name>",
@@ -329,6 +330,156 @@ static int add_branch_for_removal(const char *refname,
return 0;
}
+struct rename_info {
+ const char *old;
+ const char *new;
+ struct string_list *remote_branches;
+};
+
+static int read_remote_branches(const char *refname,
+ const unsigned char *sha1, int flags, void *cb_data)
+{
+ struct rename_info *rename = cb_data;
+ struct strbuf buf = STRBUF_INIT;
+ struct string_list_item *item;
+ int flag;
+ unsigned char orig_sha1[20];
+ const char *symref;
+
+ strbuf_addf(&buf, "refs/remotes/%s", rename->old);
+ if(!prefixcmp(refname, buf.buf)) {
+ item = string_list_append(xstrdup(refname), rename->remote_branches);
+ symref = resolve_ref(refname, orig_sha1, 1, &flag);
+ if (flag & REF_ISSYMREF)
+ item->util = xstrdup(symref);
+ else
+ item->util = NULL;
+ }
+
+ return 0;
+}
+
+static int mv(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ struct remote *oldremote, *newremote;
+ struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT;
+ struct string_list remote_branches = { NULL, 0, 0, 0 };
+ struct rename_info rename;
+ int i;
+
+ if (argc != 3)
+ usage_with_options(builtin_remote_usage, options);
+
+ rename.old = argv[1];
+ rename.new = argv[2];
+ rename.remote_branches = &remote_branches;
+
+ oldremote = remote_get(rename.old);
+ if (!oldremote)
+ die("No such remote: %s", rename.old);
+
+ newremote = remote_get(rename.new);
+ if (newremote && (newremote->url_nr > 1 || newremote->fetch_refspec_nr))
+ die("remote %s already exists.", rename.new);
+
+ strbuf_addf(&buf, "refs/heads/test:refs/remotes/%s/test", rename.new);
+ if (!valid_fetch_refspec(buf.buf))
+ die("'%s' is not a valid remote name", rename.new);
+
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "remote.%s", rename.old);
+ strbuf_addf(&buf2, "remote.%s", rename.new);
+ if (git_config_rename_section(buf.buf, buf2.buf) < 1)
+ return error("Could not rename config section '%s' to '%s'",
+ buf.buf, buf2.buf);
+
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "remote.%s.fetch", rename.new);
+ if (git_config_set_multivar(buf.buf, NULL, NULL, 1))
+ return error("Could not remove config section '%s'", buf.buf);
+ for (i = 0; i < oldremote->fetch_refspec_nr; i++) {
+ char *ptr;
+
+ strbuf_reset(&buf2);
+ strbuf_addstr(&buf2, oldremote->fetch_refspec[i]);
+ ptr = strstr(buf2.buf, rename.old);
+ if (ptr)
+ strbuf_splice(&buf2, ptr-buf2.buf, strlen(rename.old),
+ rename.new, strlen(rename.new));
+ if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0))
+ return error("Could not append '%s'", buf.buf);
+ }
+
+ read_branches();
+ for (i = 0; i < branch_list.nr; i++) {
+ struct string_list_item *item = branch_list.items + i;
+ struct branch_info *info = item->util;
+ if (info->remote && !strcmp(info->remote, rename.old)) {
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "branch.%s.remote", item->string);
+ if (git_config_set(buf.buf, rename.new)) {
+ return error("Could not set '%s'", buf.buf);
+ }
+ }
+ }
+
+ /*
+ * First remove symrefs, then rename the rest, finally create
+ * the new symrefs.
+ */
+ for_each_ref(read_remote_branches, &rename);
+ for (i = 0; i < remote_branches.nr; i++) {
+ struct string_list_item *item = remote_branches.items + i;
+ int flag = 0;
+ unsigned char sha1[20];
+ const char *symref;
+
+ symref = resolve_ref(item->string, sha1, 1, &flag);
+ if (!(flag & REF_ISSYMREF))
+ continue;
+ if (delete_ref(item->string, NULL, REF_NODEREF))
+ die("deleting '%s' failed", item->string);
+ }
+ for (i = 0; i < remote_branches.nr; i++) {
+ struct string_list_item *item = remote_branches.items + i;
+
+ if (item->util)
+ continue;
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, item->string);
+ strbuf_splice(&buf, strlen("refs/remotes/"), strlen(rename.old),
+ rename.new, strlen(rename.new));
+ strbuf_reset(&buf2);
+ strbuf_addf(&buf2, "remote: renamed %s to %s",
+ item->string, buf.buf);
+ if (rename_ref(item->string, buf.buf, buf2.buf))
+ die("renaming '%s' failed", item->string);
+ }
+ for (i = 0; i < remote_branches.nr; i++) {
+ struct string_list_item *item = remote_branches.items + i;
+
+ if (!item->util)
+ continue;
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, item->string);
+ strbuf_splice(&buf, strlen("refs/remotes/"), strlen(rename.old),
+ rename.new, strlen(rename.new));
+ strbuf_reset(&buf2);
+ strbuf_addstr(&buf2, item->util);
+ strbuf_splice(&buf2, strlen("refs/remotes/"), strlen(rename.old),
+ rename.new, strlen(rename.new));
+ strbuf_reset(&buf3);
+ strbuf_addf(&buf3, "remote: renamed %s to %s",
+ item->string, buf.buf);
+ if (create_symref(buf.buf, buf2.buf, buf3.buf))
+ die("creating '%s' failed", buf.buf);
+ }
+ return 0;
+}
+
static int remove_branches(struct string_list *branches)
{
int i, result = 0;
@@ -695,6 +846,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)
result = show_all();
else if (!strcmp(argv[0], "add"))
result = add(argc, argv);
+ else if (!strcmp(argv[0], "rename"))
+ result = mv(argc, argv);
else if (!strcmp(argv[0], "rm"))
result = rm(argc, argv);
else if (!strcmp(argv[0], "show"))
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index c4380c7..0c956ba 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -328,4 +328,19 @@ test_expect_success 'reject adding remote with an invalid name' '
'
+# The first three test if the tracking branches are properly renamed,
+# the last two ones check if the config is updated.
+
+test_expect_success 'rename a remote' '
+
+ git clone one four &&
+ (cd four &&
+ git remote rename origin upstream &&
+ rmdir .git/refs/remotes/origin &&
+ test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/master" &&
+ test "$(git rev-parse upstream/master)" = "$(git rev-parse master)" &&
+ test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*" &&
+ test "$(git config branch.master.remote)" = "upstream")
+
+'
test_done
--
1.6.0.2
^ permalink raw reply related
* Re: [PATCH] Make Pthread link flags configurable
From: Jakub Narebski @ 2008-11-03 18:26 UTC (permalink / raw)
To: David Syzdek; +Cc: David M. Syzdek, git
In-Reply-To: <9a0027270811031018t2b90ee64kcd2ef5e9afa73f6a@mail.gmail.com>
David Syzdek wrote:
> On Mon, Nov 3, 2008 at 12:44 AM, Jakub Narebski <jnareb@gmail.com> wrote:
>> david.syzdek@acsalaska.net writes:
>>
>>> From: David M. Syzdek <david.syzdek@acsalaska.net>
>>>
>>> FreeBSD 4.x systems use the linker flags `-pthread' instead of the
>>> linker flags `-lpthread' when linking against the pthread library.
>>>
>>> Signed-off-by: David M. Syzdek <david.syzdek@acsalaska.net>
>>> ---
>>> Makefile | 4 +++-
>>> 1 files changed, 3 insertions(+), 1 deletions(-)
>>
>> Would it be possible to add support for this also to configure.ac
>> (and config.mak.in)?
>>
>
> I just sent a patch to the list that adds autoconf tests for pthreads.
> If the test is able to determine which flag to use, then it also sets
> THREADED_DELTA_SEARCH.
Thanks a lot.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCH] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Brandon Casey @ 2008-11-03 18:20 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: drafnel, git, gitster, nico
In-Reply-To: <490ED3FE.8040103@op5.se>
Andreas Ericsson wrote:
> drafnel@gmail.com wrote:
>> From: Brandon Casey <drafnel@gmail.com>
>>
>> Objects residing in pack files that have an associated .keep file are not
>> supposed to be repacked into new pack files, but they are.
>>
>
> I think that's a misconception. Packfiles that are marked with .keep files
> should never be deleted. There are, afaik, no rules against packing the
> same objects into other packfiles as well. This is nifty for dumb ref
> walkers, as they can use a small pack for incremental fetching while using
> a mega-pack for initial cloning.
Having no rules against an object residing in more than one pack is different
from intending for git to produce pack files with redundant objects.
I think one intention for the .keep mechanism was to allow for a size optimized
pack to be produced and distributed. Currently, if I am handed such a pack file,
I can not merely place it into my pack directory (along with the .idx and .keep
files) and then run git-gc to remove any redundancy. Instead, I would get
a _new_ pack file which would contain all of the objects in the repository and
effectively double the size of my objects store. That doesn't seem like
something a user would expect or should expect.
-brandon
^ permalink raw reply
* Re: [PATCH 1/3] packed_git: convert pack_local flag into generic bit mask
From: Brandon Casey @ 2008-11-03 18:24 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: drafnel, git, gitster, nico
In-Reply-To: <20081103161202.GJ15463@spearce.org>
Shawn O. Pearce wrote:
> drafnel@gmail.com wrote:
>> diff --git a/cache.h b/cache.h
>> index b0edbf9..0cb9350 100644
>> --- a/cache.h
>> +++ b/cache.h
>> @@ -679,12 +679,15 @@ extern struct packed_git {
>> int index_version;
>> time_t mtime;
>> int pack_fd;
>> - int pack_local;
>> + unsigned int flags;
>
> Hmm, isn't this a smaller change to make?
heh, well if you want to do it the "easy" way. :)
For some reason I've never used this bit field mechanism, but
I agree it is more readable and simpler, and you can't argue
with that.
-brandon
^ permalink raw reply
* Re: [Announce] teamGit v0.0.4
From: Alex Riesen @ 2008-11-03 18:28 UTC (permalink / raw)
To: Abhijit Bhopatkar; +Cc: Matthieu Moy, git
In-Reply-To: <2fcfa6df0811030535m208999ben2608878fb0978fae@mail.gmail.com>
Abhijit Bhopatkar, Mon, Nov 03, 2008 14:35:24 +0100:
> teamGit is a GUI for git,
> in its final roadmap it aims to aid small closed teams to use git,
What special features does it offer to aid small closed teams?
Why are they "closed"?
^ permalink raw reply
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.
From: Jakub Narebski @ 2008-11-03 18:18 UTC (permalink / raw)
To: Francis Galiegue; +Cc: Alexander Gavrilov, git
In-Reply-To: <200811031845.46451.fg@one2team.net>
Francis Galiegue <fg@one2team.net> writes:
> Le Monday 03 November 2008 18:26:44 Alexander Gavrilov, vous avez écrit :
>> On Mon, Nov 3, 2008 at 7:54 PM, Francis Galiegue <fg@one2team.net> wrote:
>>>
>>> It just seems to me that this is emulating functionality that
>>> multiple Web servers already provide...
>>>
>>> What's more, knowledge about these Web servers are _much_ more
>>> widespread than knowledge about gitweb.
>>>
>>> Why reinvent the wheel?
[...]
>> If you are speaking of web servers as in 'Apache', then how would it
>> know which files are going to be accessed when it executes
>> cgi-bin/gitweb.cgi?p=very/private/project.git to check permissions?
>>
>
> Well, as far as Apache is concerned, it can do:
>
> * basic .htpasswd authentication,
> * LDAP,
> * PAM,
> * SSL certificate check (via mod_ssl),
> * probably others.
>
> Plenty of possibilities.
[...]
Well, the question is if Apache (and other web servers used with
gitweb) can do authentication based on path_info or on query-string.
Because it is encoded in gitweb (via $projectroot) where to find git
repositories...
--
Jakub Narebski
Poland
ShadeHawk on #git
^ permalink raw reply
* Re: git bisect v2.6.27 v2.6.26 problem/bug
From: Linus Torvalds @ 2008-11-03 18:43 UTC (permalink / raw)
To: Miquel van Smoorenburg; +Cc: git
In-Reply-To: <20081103173911.GA12363@xs4all.net>
On Mon, 3 Nov 2008, Miquel van Smoorenburg wrote:
>
> If at this point I do a 'git bisect good' I end up in a 2.6.26
> branch, which is good, but after a few bisects I end up at
> a version before v2.6.26 (2.6.26-rc5) again, which should be
> impossible right ?
No, not at all.
What is going on is that you are hitting commits that were not merged into
2.6.26 (so they are _not_ in the "good" part), but they were _developed_
before it. So the kernel Makefile says "v2.6.26-rc8" (not quite 2.6.26
yet), but that's because the version in the Makefile ends up being a
linear explanation of what the nearest _earlier_ version was, but is not
at all indicative of the much more complex non-linear development model.
IOW, you have history that looks like
- A -> B -> C->
\ /
- D -
And let's say that 'A' is v2.6.26-rc8, while 'B' is the final v2.6.26
release, and is your 'good', while 'C' is 2.6.27, and is your 'bad'.
What does that make 'D' then?
It is clearly potentially bad, because it is _not_ in the good set (it was
merged after 2.6.26, and could very well be the source of your bug. But
think about what 'Makefile' must contain in 'D'.
The difference between linear history and non-linear history is very
important, and "git bisect" very much is all about getting it right. It
does't take a "linear" half-way point, it really does a _set_ operation,
and it bisects the set of commits. And that set of commits is a DAG, not a
linear series.
> Anyway - at the end I end up with a 'good' version that is
> 2.6.26-rc<something> which is kind of useless. I know that
> version up to 2.6.26 are good ...
Not at all. It's not "kind of useless", it's very important.
> What am I doing wrong ?
You're not doing anything wrong, you just didn't realize how non-linear
development works.
Linus
^ permalink raw reply
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.
From: Francis Galiegue @ 2008-11-03 18:44 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Alexander Gavrilov, git
In-Reply-To: <m38ws0fzca.fsf@localhost.localdomain>
Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit :
> >
> > Well, as far as Apache is concerned, it can do:
> >
> > * basic .htpasswd authentication,
> > * LDAP,
> > * PAM,
> > * SSL certificate check (via mod_ssl),
> > * probably others.
> >
> > Plenty of possibilities.
> [...]
>
> Well, the question is if Apache (and other web servers used with
> gitweb) can do authentication based on path_info or on query-string.
> Because it is encoded in gitweb (via $projectroot) where to find git
> repositories...
>
Can you expand on path_info and query-string? Keep in mind that Apache
has mod_rewrite, which can rewrite URLs in any way before it gets
actually sent to the underlying program (whether it be a CGI or
anything else), even badly (or mischievously).
--
fge
^ permalink raw reply
* Re: [PATCH] contrib/hooks/post-receive-email: Make revision display configurable
From: Andy Parkins @ 2008-11-03 18:58 UTC (permalink / raw)
To: Pete Harlan; +Cc: git
In-Reply-To: <1225668059-12670-1-git-send-email-pgit@pcharlan.com>
On Sunday 02 November 2008 23:20:59 Pete Harlan wrote:
> Add configuration option hooks.showrev, letting the user override how
> revisions will be shown in the commit email.
>
> Signed-off-by: Pete Harlan <pgit@pcharlan.com>
Acked-By: Andy Parkins <andyparkins@gmail.com>
--
Dr Andy Parkins
andyparkins@gmail.com
^ permalink raw reply
* Re: git-cvsimport BUG: some commits are completely out of phase (but cvsps sees them all right)
From: Samuel Lucas Vaz de Mello @ 2008-11-03 19:03 UTC (permalink / raw)
To: Michael Haggerty; +Cc: git
In-Reply-To: <490F1021.1090002@alum.mit.edu>
Michael Haggerty wrote:
> Francis Galiegue wrote:
>> The plan would be to convert all modules in one go, with no one committing in
>> the meantime, so that's not a problem.
>
> Then you should definitely try cvs2svn/cvs2git [1]. cvsps-based
> conversion tools all have known and unavoidable problems due to the
> limitations of cvsps.
>
Michael,
Does cvs2git plans to support incremental importing?
- Samuel
^ permalink raw reply
* Re: git-cvsimport BUG: some commits are completely out of phase (but cvsps sees them all right)
From: Shawn O. Pearce @ 2008-11-03 19:08 UTC (permalink / raw)
To: Samuel Lucas Vaz de Mello; +Cc: Michael Haggerty, git
In-Reply-To: <490F4B1E.2080707@datacom.ind.br>
Samuel Lucas Vaz de Mello <samuellucas@datacom.ind.br> wrote:
> Michael Haggerty wrote:
> > Francis Galiegue wrote:
> >> The plan would be to convert all modules in one go, with no one committing in
> >> the meantime, so that's not a problem.
> >
> > Then you should definitely try cvs2svn/cvs2git [1]. cvsps-based
> > conversion tools all have known and unavoidable problems due to the
> > limitations of cvsps.
>
> Does cvs2git plans to support incremental importing?
No, it doesn't, and likely never will. Computing the
change sets from CVS is ugly and more-or-less requires
that you do it all in one pass.
--
Shawn.
^ permalink raw reply
* Re: [RFC PATCH] gitweb: Support filtering projects by .htaccess files.
From: Jakub Narebski @ 2008-11-03 19:17 UTC (permalink / raw)
To: Francis Galiegue; +Cc: Alexander Gavrilov, git
In-Reply-To: <200811031944.03116.fg@one2team.net>
Dnia poniedziałek 3. listopada 2008 19:44, Francis Galiegue napisał:
> Le Monday 03 November 2008 19:18:56 Jakub Narebski, vous avez écrit :
> > > Well, as far as Apache is concerned, it can do:
> > >
> > > * basic .htpasswd authentication,
> > > * LDAP,
> > > * PAM,
> > > * SSL certificate check (via mod_ssl),
> > > * probably others.
> > >
> > > Plenty of possibilities.
> > [...]
> >
> > Well, the question is if Apache (and other web servers used with
> > gitweb) can do authentication based on path_info or on query-string.
> > Because it is encoded in gitweb (via $projectroot) where to find git
> > repositories...
> >
>
> Can you expand on path_info and query-string? Keep in mind that Apache
> has mod_rewrite, which can rewrite URLs in any way before it gets
> actually sent to the underlying program (whether it be a CGI or
> anything else), even badly (or mischievously).
What I mean here that the following example gitweb URLs
http://example.com/gitweb.cgi?p=some/project.git;a=commit;h=HEAD
http://example.com/gitweb.cgi/some/project.git/commit/HEAD
with the following gitweb configuration
$projectroot = /var/scm
both refer to git repository (directory) at
/var/scm/some/project.git
Apache (or other web server) would have to somehow decide based on URL
that it refers to some project, and based on project and authentication
decide whether to grant access to it.
What is more, and what cannot be done by web server alone, is that we
would want to not show projects which you don't have access to in the
'projects_list' page, i.e. at
http://example.com/gitweb.cgi
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [Q] Abbreviated history graph?
From: Linus Torvalds @ 2008-11-03 19:32 UTC (permalink / raw)
To: Brian Foster, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <200811031439.12111.brian.foster@innova-card.com>
On Mon, 3 Nov 2008, Brian Foster wrote:
>
> A colleague and I recently wanted to examine the
> history in a broad sense without worrying too much
> about the individual commits. What we (think we)
> wanted is a ‘gitk --all’ history graph showing only
> “named” historical points;
Ok, this is actually really easy to do with git. We have all the
infrastructure in place, and what you're asking for is fundamentally
really just an odd form of commit history simplification. Instead of
comparing the *contents* of the commits (the trees) to see if they are
interesting, you'd only check if there is a decoration (ie a tag or a
branch) pointing to the commit.
I'll post a simple series of four commits in a moment. They're all
trivial, and the first three are just setting stuff up (in fact, the very
first one is a commit I've already posted, and it's technically totally
unrelated, but since it touches the same area as one of the other ones,
I'm too lazy to try to separate it out).
Patchbombing to commence in 5.. 4.. 3.. 2.. 1..
Linus
^ permalink raw reply
* [PATCH 1/4] Add a 'source' decorator for commits
From: Linus Torvalds @ 2008-11-03 19:33 UTC (permalink / raw)
To: Brian Foster, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0811031129060.3419@nehalem.linux-foundation.org>
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon, 27 Oct 2008 12:51:59 -0700
We already support decorating commits by tags or branches that point to
them, but especially when we are looking at multiple branches together,
we sometimes want to see _how_ we reached a particular commit.
We can abuse the '->util' field in the commit to keep track of that as
we walk the commit lists, and get a reasonably useful view into which
branch or tag first reaches that commit.
Of course, if the commit is reachable through multiple sources (which is
common), our particular choice of "first" reachable is entirely random
and depends on the particular path we happened to follow.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
This is strictly unrelated to the rest, but as mentioned, it touches the
same areas, and I'm too lazy to split it out. I had it in my tree. It
won't hurt.
builtin-log.c | 2 ++
builtin-rev-list.c | 2 +-
log-tree.c | 8 +++++---
log-tree.h | 2 +-
revision.c | 4 ++++
revision.h | 1 +
6 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/builtin-log.c b/builtin-log.c
index a0944f7..176cbce 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -56,6 +56,8 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
if (!strcmp(arg, "--decorate")) {
load_ref_decorations();
decorate = 1;
+ } else if (!strcmp(arg, "--source")) {
+ rev->show_source = 1;
} else
die("unrecognized argument: %s", arg);
}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 06cdeb7..857742a 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -100,7 +100,7 @@ static void show_commit(struct commit *commit)
children = children->next;
}
}
- show_decorations(commit);
+ show_decorations(&revs, commit);
if (revs.commit_format == CMIT_FMT_ONELINE)
putchar(' ');
else
diff --git a/log-tree.c b/log-tree.c
index cec3c06..cf7947b 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -52,11 +52,13 @@ static void show_parents(struct commit *commit, int abbrev)
}
}
-void show_decorations(struct commit *commit)
+void show_decorations(struct rev_info *opt, struct commit *commit)
{
const char *prefix;
struct name_decoration *decoration;
+ if (opt->show_source && commit->util)
+ printf(" %s", (char *) commit->util);
decoration = lookup_decoration(&name_decoration, &commit->object);
if (!decoration)
return;
@@ -279,7 +281,7 @@ void show_log(struct rev_info *opt)
fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
if (opt->print_parents)
show_parents(commit, abbrev_commit);
- show_decorations(commit);
+ show_decorations(opt, commit);
if (opt->graph && !graph_is_commit_finished(opt->graph)) {
putchar('\n');
graph_show_remainder(opt->graph);
@@ -352,7 +354,7 @@ void show_log(struct rev_info *opt)
printf(" (from %s)",
diff_unique_abbrev(parent->object.sha1,
abbrev_commit));
- show_decorations(commit);
+ show_decorations(opt, commit);
printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));
if (opt->commit_format == CMIT_FMT_ONELINE) {
putchar(' ');
diff --git a/log-tree.h b/log-tree.h
index 3c8127b..f2a9008 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -12,7 +12,7 @@ int log_tree_diff_flush(struct rev_info *);
int log_tree_commit(struct rev_info *, struct commit *);
int log_tree_opt_parse(struct rev_info *, const char **, int);
void show_log(struct rev_info *opt);
-void show_decorations(struct commit *commit);
+void show_decorations(struct rev_info *opt, struct commit *commit);
void log_write_email_headers(struct rev_info *opt, const char *name,
const char **subject_p,
const char **extra_headers_p,
diff --git a/revision.c b/revision.c
index 2f646de..d45f05a 100644
--- a/revision.c
+++ b/revision.c
@@ -199,6 +199,8 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
mark_parents_uninteresting(commit);
revs->limited = 1;
}
+ if (revs->show_source && !commit->util)
+ commit->util = (void *) name;
return commit;
}
@@ -484,6 +486,8 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
if (parse_commit(p) < 0)
return -1;
+ if (revs->show_source && !p->util)
+ p->util = commit->util;
p->object.flags |= left_flag;
if (!(p->object.flags & SEEN)) {
p->object.flags |= SEEN;
diff --git a/revision.h b/revision.h
index 2fdb2dd..51a4863 100644
--- a/revision.h
+++ b/revision.h
@@ -53,6 +53,7 @@ struct rev_info {
left_right:1,
rewrite_parents:1,
print_parents:1,
+ show_source:1,
reverse:1,
reverse_output_stage:1,
cherry_pick:1,
--
1.6.0.3.616.gf1239d6.dirty
^ permalink raw reply related
* [PATCH 2/4] revision: make tree comparison functions take commits rather than trees
From: Linus Torvalds @ 2008-11-03 19:35 UTC (permalink / raw)
To: Brian Foster, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0811031132520.3419@nehalem.linux-foundation.org>
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon, 3 Nov 2008 10:45:41 -0800
Subject: [PATCH 2/4] revision: make tree comparison functions take commits rather than trees
This will make it easier to do various clever things that don't depend
on the pure tree contents. It also makes the parameter passing much
simpler - the callers doesn't really look at trees anywhere else, and
it's really the function that should look at the low-level details.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
This is a trivial no-op change that just passes commits instead of trees
to the commit compare functions. The whole point is that we can now start
comparing them based on not just contents of the trees, but other
attributes too.
The patch makes no semantic changes. Just preparation.
revision.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/revision.c b/revision.c
index d45f05a..56b09eb 100644
--- a/revision.c
+++ b/revision.c
@@ -294,8 +294,11 @@ static void file_change(struct diff_options *options,
DIFF_OPT_SET(options, HAS_CHANGES);
}
-static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
+static int rev_compare_tree(struct rev_info *revs, struct commit *parent, struct commit *commit)
{
+ struct tree *t1 = parent->tree;
+ struct tree *t2 = commit->tree;
+
if (!t1)
return REV_TREE_NEW;
if (!t2)
@@ -308,12 +311,13 @@ static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree
return tree_difference;
}
-static int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
+static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
{
int retval;
void *tree;
unsigned long size;
struct tree_desc empty, real;
+ struct tree *t1 = commit->tree;
if (!t1)
return 0;
@@ -347,7 +351,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
return;
if (!commit->parents) {
- if (rev_same_tree_as_empty(revs, commit->tree))
+ if (rev_same_tree_as_empty(revs, commit))
commit->object.flags |= TREESAME;
return;
}
@@ -367,7 +371,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
die("cannot simplify commit %s (because of %s)",
sha1_to_hex(commit->object.sha1),
sha1_to_hex(p->object.sha1));
- switch (rev_compare_tree(revs, p->tree, commit->tree)) {
+ switch (rev_compare_tree(revs, p, commit)) {
case REV_TREE_SAME:
tree_same = 1;
if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) {
@@ -387,7 +391,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
case REV_TREE_NEW:
if (revs->remove_empty_trees &&
- rev_same_tree_as_empty(revs, p->tree)) {
+ rev_same_tree_as_empty(revs, p)) {
/* We are adding all the specified
* paths from this parent, so the
* history beyond this parent is not
--
1.6.0.3.616.gf1239d6.dirty
^ permalink raw reply related
* [PATCH 3/4] Make '--decorate' set an explicit 'show_decorations' flag
From: Linus Torvalds @ 2008-11-03 19:39 UTC (permalink / raw)
To: Brian Foster, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0811031133590.3419@nehalem.linux-foundation.org>
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon, 3 Nov 2008 11:23:57 -0800
Subject: [PATCH 3/4] Make '--decorate' set an explicit 'show_decorations' flag
We will want to add decorations without necessarily showing them, so add
an explicit revisions info flag as to whether we're showing decorations
or not.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
Another really trivial preparatory patch. Instead of writing to a totally
unused and pointless local variable (yeah, don't ask me why it does that,
it's probably my brainfart from long ago), set a "revs->show_decorations"
flag that we actually _use_ to decide if we want to show decorations or
not when outputting logs.
This makes no semantic difference, since there are only two users of
decorations:
- format_decoration() which does everything by hand
- show_decorations() that now looks at the flag that we set when we
preload them.
It _will_ matter in the next commit, though. Because soon we'll start
loading decorations without actually wanting to necessarily show them!
builtin-log.c | 3 +--
log-tree.c | 2 ++
revision.h | 1 +
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/builtin-log.c b/builtin-log.c
index 176cbce..82ea07b 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -28,7 +28,6 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
struct rev_info *rev)
{
int i;
- int decorate = 0;
rev->abbrev = DEFAULT_ABBREV;
rev->commit_format = CMIT_FMT_DEFAULT;
@@ -55,7 +54,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
const char *arg = argv[i];
if (!strcmp(arg, "--decorate")) {
load_ref_decorations();
- decorate = 1;
+ rev->show_decorations = 1;
} else if (!strcmp(arg, "--source")) {
rev->show_source = 1;
} else
diff --git a/log-tree.c b/log-tree.c
index cf7947b..5444f08 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -59,6 +59,8 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
if (opt->show_source && commit->util)
printf(" %s", (char *) commit->util);
+ if (!opt->show_decorations)
+ return;
decoration = lookup_decoration(&name_decoration, &commit->object);
if (!decoration)
return;
diff --git a/revision.h b/revision.h
index 51a4863..0a1806a 100644
--- a/revision.h
+++ b/revision.h
@@ -54,6 +54,7 @@ struct rev_info {
rewrite_parents:1,
print_parents:1,
show_source:1,
+ show_decorations:1,
reverse:1,
reverse_output_stage:1,
cherry_pick:1,
--
1.6.0.3.616.gf1239d6.dirty
^ permalink raw reply related
* Re: git-cvsimport BUG: some commits are completely out of phase (but cvsps sees them all right)
From: Michael Haggerty @ 2008-11-03 19:40 UTC (permalink / raw)
To: Samuel Lucas Vaz de Mello; +Cc: git
In-Reply-To: <490F4B1E.2080707@datacom.ind.br>
Samuel Lucas Vaz de Mello wrote:
> Michael Haggerty wrote:
>> Francis Galiegue wrote:
>>> The plan would be to convert all modules in one go, with no one committing in
>>> the meantime, so that's not a problem.
>> Then you should definitely try cvs2svn/cvs2git [1]. cvsps-based
>> conversion tools all have known and unavoidable problems due to the
>> limitations of cvsps.
>
> Does cvs2git plans to support incremental importing?
Nope. It would be very difficult to get it right, and I've pretty much
run out of hacking time with the birth of my second child. But I'd be
happy to help any volunteers get started :-)
Michael
^ permalink raw reply
* [PATCH 4/4] Add support for 'namespace' history simplification
From: Linus Torvalds @ 2008-11-03 19:43 UTC (permalink / raw)
To: Brian Foster, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0811031135410.3419@nehalem.linux-foundation.org>
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon, 3 Nov 2008 11:25:46 -0800
Subject: [PATCH 4/4] Add support for 'namespace' history simplification
Maybe this is mis-named, but what it does is to simplify history not by
the contents of the tree, but whether a commit has been named (ie it's
referred to by some branch or tag) or not.
This makes it possible to see the relationship between different named
commits, without actually seeing any of the details.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
This is the actual real meat of the logic, and it's really trivial. The
actual code is really just a simple
if (simplify-by-namespace)
return lookup_decoration(..) ? REV_TREE_DIFFERENT : REV_TREE_SAME;
but it's a few more lines of addition than that because of parsing the
argument and setting the appropriate flags, and writing the above
two-liner as five lines with a comment in order to make it more readable.
No docs. I don't do docs. But you can use it like so:
gitk --simplify-namespace
and you're all done.
Ta-daa!
revision.c | 20 ++++++++++++++++++++
revision.h | 1 +
2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/revision.c b/revision.c
index 56b09eb..b48e626 100644
--- a/revision.c
+++ b/revision.c
@@ -11,6 +11,7 @@
#include "reflog-walk.h"
#include "patch-ids.h"
#include "decorate.h"
+#include "log-tree.h"
volatile show_early_output_fn_t show_early_output;
@@ -301,6 +302,17 @@ static int rev_compare_tree(struct rev_info *revs, struct commit *parent, struct
if (!t1)
return REV_TREE_NEW;
+
+ /*
+ * If we do history simplification by _name_, ignore the
+ * actual tree contents, and just check if we have a
+ * decoration
+ */
+ if (revs->simplify_namespace) {
+ struct name_decoration *name;
+ name = lookup_decoration(&name_decoration, &commit->object);
+ return name ? REV_TREE_DIFFERENT : REV_TREE_SAME;
+ }
if (!t2)
return REV_TREE_DIFFERENT;
tree_difference = REV_TREE_SAME;
@@ -1041,6 +1053,14 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
revs->rewrite_parents = 1;
revs->simplify_history = 0;
revs->limited = 1;
+ } else if (!strcmp(arg, "--simplify-namespace")) {
+ revs->simplify_merges = 1;
+ revs->rewrite_parents = 1;
+ revs->simplify_history = 0;
+ revs->simplify_namespace = 1;
+ revs->limited = 1;
+ revs->prune = 1;
+ load_ref_decorations();
} else if (!strcmp(arg, "--date-order")) {
revs->lifo = 0;
revs->topo_order = 1;
diff --git a/revision.h b/revision.h
index 0a1806a..bd1ec0d 100644
--- a/revision.h
+++ b/revision.h
@@ -43,6 +43,7 @@ struct rev_info {
lifo:1,
topo_order:1,
simplify_merges:1,
+ simplify_namespace:1,
tag_objects:1,
tree_objects:1,
blob_objects:1,
--
1.6.0.3.616.gf1239d6.dirty
^ permalink raw reply related
* Re: [Q] Abbreviated history graph?
From: Linus Torvalds @ 2008-11-03 20:15 UTC (permalink / raw)
To: Brian Foster, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0811031129060.3419@nehalem.linux-foundation.org>
On Mon, 3 Nov 2008, Linus Torvalds wrote:
>
> I'll post a simple series of four commits in a moment. They're all
> trivial, and the first three are just setting stuff up (in fact, the very
> first one is a commit I've already posted, and it's technically totally
> unrelated, but since it touches the same area as one of the other ones,
> I'm too lazy to try to separate it out).
Side note: it's certainly possible that we could improve on this. Right
now, "--simplify-namespace" will totally override any path simplification,
so you can't get a combination of pathnames _and_ naming commits. I don't
know exactly what the rules should be, but I could imagine that we could
do something like:
- if no pathnames are given, work the way the current patch-series works.
- if path-names are given, make rev_compare_tree() truen
REV_TREE_DIFFERENT if a name decoration _or_ a tree difference exists.
Anyway, that's a fairly trivial extension to the idea, and doesn't really
matter for the basic code. It can easily be left for later.
Linus
^ permalink raw reply
* Re: [PATCH] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Andreas Ericsson @ 2008-11-03 20:25 UTC (permalink / raw)
To: Brandon Casey; +Cc: drafnel, git, gitster, nico
In-Reply-To: <RqVk2AkdyUcFTIGofSkQwl1GtBTXMYzMqaOQiAOmBXAyPDuWlQug-w@cipher.nrlssc.navy.mil>
Brandon Casey wrote:
> Andreas Ericsson wrote:
>> drafnel@gmail.com wrote:
>>> From: Brandon Casey <drafnel@gmail.com>
>>>
>>> Objects residing in pack files that have an associated .keep file are not
>>> supposed to be repacked into new pack files, but they are.
>>>
>> I think that's a misconception. Packfiles that are marked with .keep files
>> should never be deleted. There are, afaik, no rules against packing the
>> same objects into other packfiles as well. This is nifty for dumb ref
>> walkers, as they can use a small pack for incremental fetching while using
>> a mega-pack for initial cloning.
>
> Having no rules against an object residing in more than one pack is different
> from intending for git to produce pack files with redundant objects.
>
> I think one intention for the .keep mechanism was to allow for a size optimized
> pack to be produced and distributed. Currently, if I am handed such a pack file,
> I can not merely place it into my pack directory (along with the .idx and .keep
> files) and then run git-gc to remove any redundancy. Instead, I would get
> a _new_ pack file which would contain all of the objects in the repository and
> effectively double the size of my objects store. That doesn't seem like
> something a user would expect or should expect.
>
So long as "git repack -a" still creates a mega-pack, I'm fine with whatever.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: Are binary xdeltas only used if you use git-gc?
From: Thanassis Tsiodras @ 2008-11-03 20:35 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Matthieu Moy, Jakub Narebski, git
In-Reply-To: <alpine.LFD.2.00.0811010924550.13034@xanadu.home>
Despair...
I just tested "git push --thin"...
Doesn't work.
It still sends the complete object, not a tiny pack as it could (should).
But perhaps I now understand why:
I run git-gc on both the remote end and the working end (before
changing anything,
i.e. with both repos being in sync - "git pull" and "git push" report all OK).
I then noticed that on the remote side, .git/objects/pack had one big pack file,
but on the local one I have two .pack files...!
I proceeded to try (many combinations of params on) git-repack in a vain attempt
to make my local repos also have one single .pack file (presumably, it
should be able
to exactly mirror the remote one, since it has the same objects inside
it!). No way...
git-prune and "git-fsck --full --strict --unreachable" report no errors either.
I'm at a loss as to why the two repos are having different "pack
representation" of the
same objects and why git-gc and git-repack fail to create a single
pack on my working
side, but I'm guessing that this is why "git push --thin" fails to
send small xdeltas...
Any help/advice on what to try next would be most welcome...
Thanassis.
On 11/1/08, Nicolas Pitre <nico@cam.org> wrote:
> On Sat, 1 Nov 2008, Thanassis Tsiodras wrote:
>
>> Thanks to everybody for your help.
>>
>> I will setup an alias to always use "git push --thin".
>> For the reverse direction, I don't see a --thin for "git pull",
>>
>> My understanding is that "git pull" is optimal,
>> and does what --thin does for push anyway, right?
>
> Exact.
>
>
> Nicolas
>
--
What I gave, I have; what I spent, I had; what I kept, I lost. -Old Epitaph
^ permalink raw reply
* Re: [Q] Abbreviated history graph?
From: Linus Torvalds @ 2008-11-03 20:34 UTC (permalink / raw)
To: Brian Foster, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0811031211180.3419@nehalem.linux-foundation.org>
On Mon, 3 Nov 2008, Linus Torvalds wrote:
>
> Side note: it's certainly possible that we could improve on this. Right
> now, "--simplify-namespace" will totally override any path simplification,
> so you can't get a combination of pathnames _and_ naming commits. I don't
> know exactly what the rules should be, but I could imagine that we could
> do something like:
>
> - if no pathnames are given, work the way the current patch-series works.
>
> - if path-names are given, make rev_compare_tree() truen
> REV_TREE_DIFFERENT if a name decoration _or_ a tree difference exists.
The incremental diff to do this would be something like the appended.
Linus
---
revision.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/revision.c b/revision.c
index b48e626..1b716c7 100644
--- a/revision.c
+++ b/revision.c
@@ -311,7 +311,10 @@ static int rev_compare_tree(struct rev_info *revs, struct commit *parent, struct
if (revs->simplify_namespace) {
struct name_decoration *name;
name = lookup_decoration(&name_decoration, &commit->object);
- return name ? REV_TREE_DIFFERENT : REV_TREE_SAME;
+ if (name)
+ return REV_TREE_DIFFERENT;
+ if (!revs->prune_data)
+ return REV_TREE_SAME;
}
if (!t2)
return REV_TREE_DIFFERENT;
^ permalink raw reply related
* [PATCH v2 1/3] t7700: demonstrate mishandling of objects in packs with a .keep file
From: Brandon Casey @ 2008-11-03 20:37 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Shawn O. Pearce, Git Mailing List, Nicolas Pitre
In-Reply-To: <20081103161202.GJ15463@spearce.org>
From: Brandon Casey <drafnel@gmail.com>
Objects residing in pack files that have an associated .keep file are not
supposed to be repacked into new pack files, but they are.
Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
---
This version replaces the use of 'head -n -1' with a grep, and should work on
all platforms.
-brandon
t/t7700-repack.sh | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
create mode 100755 t/t7700-repack.sh
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
new file mode 100755
index 0000000..27af5ab
--- /dev/null
+++ b/t/t7700-repack.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+test_description='git repack works correctly'
+
+. ./test-lib.sh
+
+test_expect_failure 'objects in packs marked .keep are not repacked' '
+ echo content1 > file1 &&
+ echo content2 > file2 &&
+ git add . &&
+ git commit -m initial_commit &&
+ # Create two packs
+ # The first pack will contain all of the objects except one
+ git rev-list --objects --all | grep -v file2 |
+ git pack-objects pack > /dev/null &&
+ # The second pack will contain the excluded object
+ packsha1=$(git rev-list --objects --all | grep file2 |
+ git pack-objects pack) &&
+ touch -r pack-$packsha1.pack pack-$packsha1.keep &&
+ objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 |
+ sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") &&
+ mv pack-* .git/objects/pack/ &&
+ git repack -A -d -l &&
+ git prune-packed &&
+ for p in .git/objects/pack/*.idx; do
+ idx=$(basename $p)
+ test "pack-$packsha1.idx" = "$idx" && continue
+ if git verify-pack -v $p | egrep "^$objsha1"; then
+ found_duplicate_object=1
+ echo "DUPLICATE OBJECT FOUND"
+ break
+ fi
+ done &&
+ test -z "$found_duplicate_object"
+'
+
+test_done
+
--
1.6.0.3.552.g12334
^ permalink raw reply related
* [PATCH v2 2/3] packed_git: convert pack_local flag into a bitfield and add pack_keep
From: Brandon Casey @ 2008-11-03 20:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List, Shawn O. Pearce, Nicolas Pitre
In-Reply-To: <muOuA1nLBoljLnZoguxeFeKt-8Q-I9Y3ljvxnLWLt9KyA8HwVtMa4Q@cipher.nrlssc.navy.mil>
From: Brandon Casey <drafnel@gmail.com>
pack_keep will be set when a pack file has an associated .keep file.
Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
---
This patch and the following one redo the previous 3-patch series using a
bitfield as prudently suggested by Shawn.
It seemed silly to keep the conversion of pack_local into a bitfield, and the
introduction of pack_keep separate, so all 7 lines are in this one patch.
-brandon
cache.h | 3 ++-
sha1_file.c | 5 +++++
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/cache.h b/cache.h
index b0edbf9..b80cb08 100644
--- a/cache.h
+++ b/cache.h
@@ -679,7 +679,8 @@ extern struct packed_git {
int index_version;
time_t mtime;
int pack_fd;
- int pack_local;
+ unsigned pack_local:1,
+ pack_keep:1;
unsigned char sha1[20];
/* something like ".git/objects/pack/xxxxx.pack" */
char pack_name[FLEX_ARRAY]; /* more */
diff --git a/sha1_file.c b/sha1_file.c
index ab2b520..f2b25bd 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -841,6 +841,11 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
return NULL;
}
memcpy(p->pack_name, path, path_len);
+
+ strcpy(p->pack_name + path_len, ".keep");
+ if (!access(p->pack_name, F_OK))
+ p->pack_keep = 1;
+
strcpy(p->pack_name + path_len, ".pack");
if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
free(p);
--
1.6.0.3.552.g12334
^ permalink raw reply related
* [PATCH v2 3/3] pack-objects: honor '.keep' files
From: Brandon Casey @ 2008-11-03 20:43 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List, Shawn O. Pearce, Nicolas Pitre
In-Reply-To: <-RiFxYEd9Wiq2fWX74zYGUiEwrzLeoFDb1KuG3-Xo-s@cipher.nrlssc.navy.mil>
From: Brandon Casey <drafnel@gmail.com>
By default, pack-objects creates a pack file with every object specified by
the user. There are two options which can be used to exclude objects which
are accessible by the repository.
1) --incremental
This excludes any object which already exists in an accessible pack.
2) --local
This excludes any object which exists in a non-local pack.
With this patch, both arguments also cause objects which exist in packs
marked with a .keep file to be excluded. Only the --local option requires
an explicit check for the .keep file. If the user doesn't want the objects
in a pack marked with .keep to be exclude, then the .keep file should be
removed.
Additionally, this fixes the repack bug which allowed porcelain repack to
create packs which contained objects already contained in existing packs
marked with a .keep file.
Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
---
builtin-pack-objects.c | 2 +-
t/t7700-repack.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 15b80db..8be9113 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -701,7 +701,7 @@ static int add_object_entry(const unsigned char *sha1, enum object_type type,
break;
if (incremental)
return 0;
- if (local && !p->pack_local)
+ if (local && (!p->pack_local || p->pack_keep))
return 0;
}
}
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index 27af5ab..5b1cd05 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -4,7 +4,7 @@ test_description='git repack works correctly'
. ./test-lib.sh
-test_expect_failure 'objects in packs marked .keep are not repacked' '
+test_expect_success 'objects in packs marked .keep are not repacked' '
echo content1 > file1 &&
echo content2 > file2 &&
git add . &&
--
1.6.0.3.552.g12334
^ 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