* Re: [PATCH] Restore expected list order for --merge-order switch
From: Jon Seymour @ 2005-07-05 23:21 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour
In-Reply-To: <20050705010619.13581.qmail@blackcubes.dyndns.org>
G'day Linus,
Is there some reason why this didn't get applied?
jon.
On 7/5/05, Jon Seymour <jon.seymour@gmail.com> wrote:
>
> A recent change to rev-list altered the order in which start points
> are presented to the merge-order sort algorithm. This caused
> breaks in the t/t6001 unit tests.
>
> This change restores the order in which start points are presented to the
> the merge-order sort algorithm (but leaves the order unchanged from
> the immediately preceding behaviour for non --merge-order sorts).
>
> The order in which arguments are presented to the merge-order
> sort algorithm is significant, since left-most arguments
> are expected to sort last so as to be consistent with
> how left-most parents sort.
>
> Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
^ permalink raw reply
* Re: [PATCH] Restore expected list order for --merge-order switch
From: Linus Torvalds @ 2005-07-05 23:43 UTC (permalink / raw)
To: jon; +Cc: git, jon.seymour
In-Reply-To: <2cfc403205070516216b911160@mail.gmail.com>
On Wed, 6 Jul 2005, Jon Seymour wrote:
>
> Is there some reason why this didn't get applied?
I think it's horribly horribly ugly.
I really don't see the point of argument ordering mattering, and I think
the test is broken. Convince me otherwise.
Linus
^ permalink raw reply
* zlib experts, please..
From: Linus Torvalds @ 2005-07-05 23:57 UTC (permalink / raw)
To: Git Mailing List
I just hit an interesting pack failure because of how git (mis-)uses zlib,
and I'm wondering what to do about it.
In particular, the "git-unpack-objects" code gets a data stream, and only
knows the _unpacked_ size of each object, because writing packed size is
extremely inconvenient in many ways (let me count the ways.. At pack time,
we want to fill in the size field before we've even packed things, and at
unpack time, we really don't care about the packed size, but we _do_ care
about the unpacked size in order to be able to allocate the right sized
allocation for the result).
However, it turns out that there's a silly special case: a zero-sized
"blob" object will ne encoded as a single byte "0x30" followed by the
"packed representation of empty".
Now, you'd expect the packed representation of empty to be empty, but
that's not apparently what zlib does. It actually seems to pack zero bytes
as 8 bytes of "78 9c 03 00 00 00 00 01". Which is fine, I don't care, with
git this will literally happen for only one single object, so it's not
like I care about the expansion.
But what I care about is that when git-unpack-objects sees that it wants a
zero-byte object, and asks zlib to unpack it, zlib will not actually use
the bytes it wrote - it will just say "oh, you wanted zero bytes, here's
zero bytes". Which means that the stream handling gets upset.
Now, I can easily fix this by just teaching the packing code that it
should pack the zero-byte object as zero bytes, and not let zlib mess it
up. In fact, I've done exactly that. However, now I worry that there's
some other case where zlib uncompression doesn't eat everything that zlib
compression generated. I've not found it, and I think a zero sized case is
special (it's kind of like a "break" event), but this is yet another cry
for zlib expertise in case somebody knows...
Linus
^ permalink raw reply
* Re: zlib experts, please..
From: Linus Torvalds @ 2005-07-06 0:04 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0507051644100.3570@g5.osdl.org>
On Tue, 5 Jul 2005, Linus Torvalds wrote:
>
> But what I care about is that when git-unpack-objects sees that it wants a
> zero-byte object, and asks zlib to unpack it, zlib will not actually use
> the bytes it wrote - it will just say "oh, you wanted zero bytes, here's
> zero bytes". Which means that the stream handling gets upset.
Actually, never mind. zlib does exactly the right thing, and eats the 8
bytes of header that it wrote for "empty". The real culprit was that
git-unpack-objects incorrectly made that zero a special case on reading,
but not writing.
So just ignore me. zlib actually does what I expected it to do, even for
the zero case.
Linus
^ permalink raw reply
* Re: expensive local git clone
From: Linus Torvalds @ 2005-07-06 0:42 UTC (permalink / raw)
To: David S. Miller, Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0507041327580.3570@g5.osdl.org>
On Mon, 4 Jul 2005, Linus Torvalds wrote:
>
> I'm making something based on pack-files.
Ok, as of a few minutes ago there's now a pack-based "git clone" there. Of
course, it hasn't percolated out to the mirrors yet, so you'll not see it
for a while unless you have a master.kernel.org account like David, but
basically you can do
git clone /some/absolute/path new-dir
and it will clone the old project into new-dir using pack-files. The need
for an absolute path in the source is just because the "git clone" script
ends up "cd'ing" to the new directory before the clone, so a relative path
would need to be relative to the "new-dir" location, which is just
confusing. Oh, well.
Anyway, as mentioned, you can certainly do a local clone a lot faster with
"cp -rl" (and yes, I'll apply Junio's patch if he makes it available
against the new version, and adds a flag to make it conditional), but
using a pack-file means that the new thing not only will be totally
independent of the old one (which you may _want_ to do, especially if they
are on different filesystems), but it also means that the above works over
ssh too, ie
git clone master.kernel.org:/pub/scm/git/git.git my-git
should now do the right thing (indeed, I've even tested it - although I've
not tried it with things like multiple branches etc, which _should_ all
work automatically but.. I'm pulling Jeff's tree as I write this, but
master.kernel.org is slow, so it will be some time..).
Btw, one small note: when doing a "git clone", the newly cloned repo will
not be checked out, and "master" will be the default HEAD regardless of
what the other happened to be at (unless the other side was really screwed
up and we can't match up any "master" at all). So use "git checkout xxx"
to actually set whatever branch you want to use after a clone.
Linus
^ permalink raw reply
* Re: cvsimport: rewritten in Perl
From: Linus Torvalds @ 2005-07-06 2:41 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: Matthias Urlichs, git
In-Reply-To: <20050705230226.0F9F4353A69@atlas.denx.de>
On Wed, 6 Jul 2005, Wolfgang Denk wrote:
>
> I tested this on the U-Boot CVS repository (available at
> http://cvs.sourceforge.net/cvstarballs/u-boot-cvsroot.tar.bz2).
>
> Committing initial tree 2183da96d548c02bd4f99b05e673395f81212878
> Cannot create object: Too many open files
If you make it print out its <pid> and then pause, you can use
ls -l /proc/<pid>/fd/
to get an idea of what the files may be. Looks like the new perl version
is leaking file descriptors..
Matthias?
Linus
^ permalink raw reply
* Re: Merging and parents
From: Linus Torvalds @ 2005-07-06 3:26 UTC (permalink / raw)
To: Matthias Urlichs; +Cc: git
In-Reply-To: <pan.2005.07.05.16.19.28.957617@smurf.noris.de>
On Tue, 5 Jul 2005, Matthias Urlichs wrote:
>
> I just had this ugly merge situation:
>
> M
> |\
> | \
> A B
> |\/|
> |/\|
> C D
> | /
> |/
> E
>
> Suppose both the EC and the ED branch add files (not with conflicting
> filenames!) which then get modified somewhere between C/D and M.
>
> No matter which node gets picked as the parent, some files will end
> up as "created on different branches" because the chosen parent doesn't
> have them, even though, strictly speaking, it ain't so.
So walk me through it. Why is this ugly?
It's kind of interesting in that it has a merge-base that isn't unique any
more: both C and D are "equally valid" merge bases, but do it really
generate any real problems?
Let's say that you pick C as the merge base, which means that both A and B
suddenly have the same new files show up (that came from D). Now, to make
it interesting, let's say that D/B also modified that file, so that you
have the merge at M see two different files just "show up".
The trivial merger will fail this case, for sure. So I agree that it's a
problem for the _current_ stupid merger, but it's not a fundamentally hard
thing to do per se. Go backwards in history, look for where it was
created, and use that as the merge-base for that particular file.
So yes, the current merge is very very stupid. It's worked impressively
well for the kernel, though, so stupid tends to often be "good enough".
And since it _has_ been good enough, I personally haven't been motivated
to try to improve the merge logic.
Basically, the first-level trivial merge that "git-read-tree -m" does is
really meant to just cut down the list of files to a manageable level, so
that you can do the "real work" on a per-file level without being bogged
down by having 17,000+ files to work with.
So if you want to document that the current automatic merge is stupid,
hey, go wild. It _is_ stupid. It's surprisingly effective, but that may be
because of kernel development patterns and may not be true in other
projects.
And if somebody wants to write a better merger than the current
git-merge-one-file-script, I can only encourage you. I think git has the
potential to have made the "normal case" so cheap that the algorithms in
git-merge-one-file-script could be quite advanced, without it slowing down
things noticeably. So to some degree I think git should _allow_ for doing
very complicated merges, exactly because it efficiently pinpoints the
effort to the place where it is needed. So a lot of merges that are
interesting in theory but aren't _practical_ as a main merge, might
actually be practical with git.
Linus
^ permalink raw reply
* Re: git-update-cache:
From: Sam Ravnborg @ 2005-07-06 1:11 UTC (permalink / raw)
To: git
In-Reply-To: <20050705224220.GA22219@mars.ravnborg.org>
On Wed, Jul 06, 2005 at 12:42:20AM +0200, Sam Ravnborg wrote:
> >
> > I receive the following error:
> > git-update-cache: symbol lookup error: git-update-cache: undefined
> > symbol: deflateBound
> >
>
> > open("/usr/lib/libz.so.1", O_RDONLY) = 3
>
> This is the reason.
>
> For a strange reason when git-update-chache was compiled is was linked
> dynamically towards an older libz.so version.
> Latest installed is libz.1.2.2 which includes deflateBound.
> libz.so.1 points at 1.1.4 which does not.
The solution was to let libz.so.1 point to latest libz.so file.
In my gentoo distribution there seems to be inconsistency
if /lib or /usr/lib is used. That was the root cause.
Back to do some useful stuff..
Sam
^ permalink raw reply
* [PATCH] sha1_file.c;prepare_packed_git_one() - fix DIR leak
From: Junio C Hamano @ 2005-07-06 6:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
The function calls opendir() without a matching closedir().
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
sha1_file.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
7a47797264a0be7955f3422a6e79e3311ab2775f
diff --git a/sha1_file.c b/sha1_file.c
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -463,6 +463,7 @@ static void prepare_packed_git_one(char
p->next = packed_git;
packed_git = p;
}
+ closedir(dir);
}
void prepare_packed_git(void)
^ permalink raw reply
* Re: cvsimport: rewritten in Perl
From: Sven Verdoolaege @ 2005-07-06 6:37 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Wolfgang Denk, Matthias Urlichs, git
In-Reply-To: <Pine.LNX.4.58.0507051936350.3570@g5.osdl.org>
On Tue, Jul 05, 2005 at 07:41:30PM -0700, Linus Torvalds wrote:
> If you make it print out its <pid> and then pause, you can use
>
> ls -l /proc/<pid>/fd/
>
> to get an idea of what the files may be. Looks like the new perl version
> is leaking file descriptors..
>
> Matthias?
That was my mistake, actually.
Thanks for spotting this.
skimo
--
git-cvsimport-script: close temporary file.
---
commit 6b6fdaa290f7dfd178a518fcafb9e14e652eb8ac
tree 725e7c6ecc75a0e90a6bc002ce540bd74dca999e
parent f4b3a4c30b5ea3a5de2a2597a3c53266017d02ba
author Sven Verdoolaege <skimo@kotnet.org> Wed, 06 Jul 2005 08:01:47 +0200
committer Sven Verdoolaege <skimo@kotnet.org> Wed, 06 Jul 2005 08:01:47 +0200
git-cvsimport-script | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/git-cvsimport-script b/git-cvsimport-script
--- a/git-cvsimport-script
+++ b/git-cvsimport-script
@@ -317,6 +317,7 @@ sub file {
$res = $self->_line($fh);
die "No input: $fn $rev\n" unless defined $res;
}
+ close ($fh);
return ($name, $res);
}
^ permalink raw reply
* [PATCH] Add commify function to cg-Xlib
From: Frank Sorenson @ 2005-07-06 7:00 UTC (permalink / raw)
To: Git Mailing List, Petr Baudis
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Here is a patch to add a commify function to cg-Xlib. I'll follow
this up with a patch that uses the new function to commify the
number and size of objects pulled in cg-pull.
Signed-off-by: Frank Sorenson <frank@tuxrocks.com>
Add a commify function to cg-Xlib
- ---
commit de4fd646c8307777137b9a4c1b5735f9573167f6
tree 1b9d3d0db498fde457d60f6658f616a1aa6b9fe3
parent b21855b8734ca76ea08c0c17e4a204191b6e3add
author Frank Sorenson <frank@tuxrocks.com> Wed, 06 Jul 2005 00:38:16 -0600
committer Frank Sorenson <frank@tuxrocks.com> Wed, 06 Jul 2005 00:38:16 -0600
cg-Xlib | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/cg-Xlib b/cg-Xlib
- --- a/cg-Xlib
+++ b/cg-Xlib
@@ -128,6 +128,9 @@ update_index () {
git-update-cache --refresh | sed 's/needs update$/locally modified/'
}
+commify() {
+ echo $1 | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta'
+}
print_help () {
which "cg-$1" >/dev/null 2>&1 || exit 1
Frank
- --
Frank Sorenson - KD7TZK
Systems Manager, Computer Science Department
Brigham Young University
frank@tuxrocks.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFCy4GiaI0dwg4A47wRAg+vAJ9ZCn7ptBARMY+ELyS+uQ893/aDLgCgsk8b
dhfcgflxQRURowVFP2qiRe4=
=u7ap
-----END PGP SIGNATURE-----
^ permalink raw reply
* [PATCH] Commify numbers in cg-pull
From: Frank Sorenson @ 2005-07-06 7:04 UTC (permalink / raw)
To: Git Mailing List, Petr Baudis
In-Reply-To: <42CB81A2.7080405@tuxrocks.com>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Here is a patch to commify the number and size of objects pulled
in cg-pull. Depends on the previous "Add commify function" patch.
Signed-off-by: Frank Sorenson <frank@tuxrocks.com>
Commify number and size of objects pulled in pull_progress
- ---
commit 03fb604eb8c24851096cca14bed19f4eacc79686
tree 191e8aa3a034e302aa660a9a5b5c0c64e2e88ac9
parent de4fd646c8307777137b9a4c1b5735f9573167f6
author Frank Sorenson <frank@tuxrocks.com> Wed, 06 Jul 2005 00:47:56 -0600
committer Frank Sorenson <frank@tuxrocks.com> Wed, 06 Jul 2005 00:47:56 -0600
cg-pull | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/cg-pull b/cg-pull
- --- a/cg-pull
+++ b/cg-pull
@@ -82,7 +82,7 @@ pull_progress() {
size=$(($size + $(stat -c '%s' "$object" 2>/dev/null)))
objects=$(($objects + 1));
- - echo -ne "progress: $objects objects, $size bytes$percentage\r"
+ echo -ne "progress: $(commify $objects) objects, $(commify $size) bytes$percentage\r"
done;
[ "$last_objects" != "$objects" ] && echo
}
Frank
- --
Frank Sorenson - KD7TZK
Systems Manager, Computer Science Department
Brigham Young University
frank@tuxrocks.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFCy4J4aI0dwg4A47wRAihxAKCOAioNWvYBDPkOvk/hYUgfUuMdewCgm1ea
4IGx09Ew6tytbOAyPrUxHZU=
=YM7f
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: cvsimport: rewritten in Perl
From: Matthias Urlichs @ 2005-07-06 7:32 UTC (permalink / raw)
To: Linus Torvalds, Wolfgang Denk, git
In-Reply-To: <20050706063712.GV18608MdfPADPa@garage.linux.student.kuleuven.ac.be>
[-- Attachment #1: Type: text/plain, Size: 654 bytes --]
Hi,
Sven Verdoolaege:
> > to get an idea of what the files may be. Looks like the new perl version
> > is leaking file descriptors..
> >
> > Matthias?
>
> That was my mistake, actually.
> Thanks for spotting this.
>
Ouch. For me, the main danger of lots of Python programming is that
I tend not to see this kind of problem any more, because in Python it
Simply Doesn't Happen.
--
Matthias Urlichs | {M:U} IT Design @ m-u-it.de | smurf@smurf.noris.de
Disclaimer: The quote was selected randomly. Really. | http://smurf.noris.de
- -
Conscience is the inner voice that warns us somebody is looking
-- H. L. Mencken
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH 5/6] Introduce --topo-order switch to git-rev-list
From: Jon Seymour @ 2005-07-06 7:51 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour
This patch introduces a --topo-order switch to git-rev-list.
When this --switch is specified, a minimal topological sort
weaker than the --merge-order sort is applied to the output
list.
The invariant of the resulting list is:
a is reachable from b => ord(b) < ord(a)
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
Documentation/git-rev-list.txt | 9 +++++++--
rev-list.c | 27 +++++++++++++++++++++++++--
2 files changed, 32 insertions(+), 4 deletions(-)
8829e9cd41c15ecc39214d76e117c28cfc8757ce
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -9,13 +9,15 @@ git-rev-list - Lists commit objects in r
SYNOPSIS
--------
-'git-rev-list' [ *--max-count*=number ] [ *--max-age*=timestamp ] [ *--min-age*=timestamp ] [ *--merge-order* [ *--show-breaks* ] ] <commit>
+'git-rev-list' [ *--max-count*=number ] [ *--max-age*=timestamp ] [ *--min-age*=timestamp ] [ *--merge-order* ] [ *--show-breaks* ] [ *--topo-order* ] <commit>... ^<prune>...
DESCRIPTION
-----------
Lists commit objects in reverse chronological order starting at the
given commit, taking ancestry relationship into account. This is
-useful to produce human-readable log output.
+useful to produce human-readable log output. If prune points are specified
+with ^<prune>... arguments, the output will not include any commits reachable
+from (and including) the prune points.
If *--merge-order* is specified, the commit history is decomposed into a
unique sequence of minimal, non-linear epochs and maximal, linear epochs.
@@ -59,6 +61,9 @@ represent an arbtirary DAG in a linear f
*--show-breaks* implies **-merge-order*.
+If *--topo-order* is specified, the commit history is sorted in a topological
+order that is weaker than the topological order generated by *--merge-order*.
+
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
diff --git a/rev-list.c b/rev-list.c
--- a/rev-list.c
+++ b/rev-list.c
@@ -20,6 +20,7 @@ static const char rev_list_usage[] =
" --unpacked\n"
" --header\n"
" --pretty\n"
+ " --topo-order\n"
" --merge-order [ --show-breaks ]";
static int unpacked = 0;
@@ -38,10 +39,12 @@ static enum cmit_fmt commit_format = CMI
static int merge_order = 0;
static int show_breaks = 0;
static int stop_traversal = 0;
+static int topo_order = 0;
struct rev_list_fns {
struct commit_list * (*insert)(struct commit *, struct commit_list **);
struct commit_list * (*limit)(struct commit_list *);
+ void (*post_limit_sort)(struct commit_list **);
void (*process)(struct commit_list *);
};
@@ -425,12 +428,21 @@ static void merge_order_sort(struct comm
struct rev_list_fns default_fns = {
&insert_by_date,
&limit_list,
- &show_commit_list
+ NULL,
+ &show_commit_list
+};
+
+struct rev_list_fns topo_order_fns = {
+ &insert_by_date,
+ &limit_list,
+ &sort_in_topological_order,
+ &show_commit_list
};
struct rev_list_fns merge_order_fns = {
&commit_list_insert,
NULL,
+ NULL,
&merge_order_sort
};
@@ -439,7 +451,7 @@ int main(int argc, char **argv)
struct commit_list *list = NULL;
struct commit_list *sorted = NULL;
struct commit_list **list_tail = &list;
- struct rev_list_fns * fns = &default_fns;
+ struct rev_list_fns * fns = NULL;
int i, limited = 0;
for (i = 1 ; i < argc; i++) {
@@ -498,6 +510,11 @@ int main(int argc, char **argv)
merge_order = 1;
continue;
}
+ if (!strcmp(arg, "--topo-order")) {
+ topo_order = 1;
+ limited=1;
+ continue;
+ }
flags = 0;
if (*arg == '^') {
@@ -512,11 +529,17 @@ int main(int argc, char **argv)
}
if (merge_order)
fns=&merge_order_fns;
+ else if (topo_order)
+ fns=&topo_order_fns;
+ else
+ fns=&default_fns;
while (list)
(*(fns->insert))(pop_commit(&list), &sorted);
list=sorted;
if (limited && fns->limit)
list = (*(fns->limit))(list);
+ if (fns->post_limit_sort)
+ (*(fns->post_limit_sort))(&list);
(*(fns->process))(list);
return 0;
}
------------
^ permalink raw reply
* [PATCH 6/6] Change gitk so that it uses --topo-order rather than --merge-order
From: Jon Seymour @ 2005-07-06 7:51 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour, paulus
This change is made so that gitk --all produces the same result for
every user irrespective of whether git-rev-parse --all produces
the same result for every user. By using --topo-order rather than
--merge-order this can be guaranteed and the existing (non-timestamp dependent)
behaviour of --merge-order can be maintained.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
Paul, could you review this patch and if you agree, ack it.
The rationale for changing gitk to use --topo-order is that git-rev-list will
produce the same order for --topo-order irrespective of the order of the
start list, whereas git-rev-list --merge-order produces an order that is deliberately
sensitive to the order of the start list.
Linus wants gitk --all to behave the same way, irrespective of what order
git-rev-parse --all produces its output. I want --merge-order to keep its
existing behaviour, so we agreed on this compromise whereby gitk uses
--topo-order rather than --merge-order by default.
My understanding of your code is that you only expect a minimal topological ordering
guarantee and the ordering produced by --topo-order should be sufficient
for your needs - that is, you don't rely on the other aspect of the
--merge-order invariant.
I'll leave it to you and Linus to decide how you want to manage the merge between
your HEAD and Linus'.
---
gitk | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
ff2ca5764029d451f2a728845dad12c4e950fae1
diff --git a/gitk b/gitk
--- a/gitk
+++ b/gitk
@@ -37,7 +37,7 @@ proc getcommits {rargs} {
set parsed_args $rargs
}
if [catch {
- set commfd [open "|git-rev-list --header --merge-order $parsed_args" r]
+ set commfd [open "|git-rev-list --header --topo-order $parsed_args" r]
} err] {
puts stderr "Error executing git-rev-list: $err"
exit 1
------------
^ permalink raw reply
* [PATCH 4/6] Add a topological sort procedure to commit.c [rev 4]
From: Jon Seymour @ 2005-07-06 7:51 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour
This patch introduces an in-place topological sort procedure to commit.c.
Given a list of commits, sort_in_topological_order() will perform an in-place
topological sort of that list.
The invariant that applies to the resulting list is:
a reachable from b => ord(b) < ord(a)
This invariant is weaker than the --merge-order invariant, but is cheaper
to calculate (assuming the list has been identified) and will serve any
purpose where only a minimal topological order guarantee is required.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
Note: this patch currently has no observable consequences since nothing
in this patch calls it. A future patch will use this algorithm to provide
support for a --topo-order flag.
This patch is a complete replacement for earlier revisions of this patch.
[rev 2]
* incorporates Junio's questions/comments as commentary,
* adds object.util save/restore functionality so that no
assumption is made about the pre-existing state of object.util
upon entry to the procedure.
[rev 3]
* removed object.util save/restore
* added more documentation to header about pre-conditions
[rev 4]
* re-applied rev 3 to new patch series - no other change
---
commit.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
commit.h | 13 ++++++++
2 files changed, 120 insertions(+), 0 deletions(-)
f80e897fd36a77425cdec24af48746706d7a2e74
diff --git a/commit.c b/commit.c
--- a/commit.c
+++ b/commit.c
@@ -3,6 +3,22 @@
#include "commit.h"
#include "cache.h"
+struct sort_node
+{
+ /*
+ * the number of children of the associated commit
+ * that also occur in the list being sorted.
+ */
+ unsigned int indegree;
+
+ /*
+ * reference to original list item that we will re-use
+ * on output.
+ */
+ struct commit_list * list_item;
+
+};
+
const char *commit_type = "commit";
enum cmit_fmt get_commit_format(const char *arg)
@@ -346,3 +362,94 @@ int count_parents(struct commit * commit
return count;
}
+/*
+ * Performs an in-place topological sort on the list supplied.
+ */
+void sort_in_topological_order(struct commit_list ** list)
+{
+ struct commit_list * next = *list;
+ struct commit_list * work = NULL;
+ struct commit_list ** pptr = list;
+ struct sort_node * nodes;
+ struct sort_node * next_nodes;
+ int count = 0;
+
+ /* determine the size of the list */
+ while (next) {
+ next = next->next;
+ count++;
+ }
+ /* allocate an array to help sort the list */
+ nodes = xcalloc(count, sizeof(*nodes));
+ /* link the list to the array */
+ next_nodes = nodes;
+ next=*list;
+ while (next) {
+ next_nodes->list_item = next;
+ next->item->object.util = next_nodes;
+ next_nodes++;
+ next = next->next;
+ }
+ /* update the indegree */
+ next=*list;
+ while (next) {
+ struct commit_list * parents = next->item->parents;
+ while (parents) {
+ struct commit * parent=parents->item;
+ struct sort_node * pn = (struct sort_node *)parent->object.util;
+
+ if (pn)
+ pn->indegree++;
+ parents=parents->next;
+ }
+ next=next->next;
+ }
+ /*
+ * find the tips
+ *
+ * tips are nodes not reachable from any other node in the list
+ *
+ * the tips serve as a starting set for the work queue.
+ */
+ next=*list;
+ while (next) {
+ struct sort_node * node = (struct sort_node *)next->item->object.util;
+
+ if (node->indegree == 0) {
+ commit_list_insert(next->item, &work);
+ }
+ next=next->next;
+ }
+ /* process the list in topological order */
+ while (work) {
+ struct commit * work_item = pop_commit(&work);
+ struct sort_node * work_node = (struct sort_node *)work_item->object.util;
+ struct commit_list * parents = work_item->parents;
+
+ while (parents) {
+ struct commit * parent=parents->item;
+ struct sort_node * pn = (struct sort_node *)parent->object.util;
+
+ if (pn) {
+ /*
+ * parents are only enqueued for emission
+ * when all their children have been emitted thereby
+ * guaranteeing topological order.
+ */
+ pn->indegree--;
+ if (!pn->indegree)
+ commit_list_insert(parent, &work);
+ }
+ parents=parents->next;
+ }
+ /*
+ * work_item is a commit all of whose children
+ * have already been emitted. we can emit it now.
+ */
+ *pptr = work_node->list_item;
+ pptr = &(*pptr)->next;
+ *pptr = NULL;
+ work_item->object.util = NULL;
+ }
+ free(nodes);
+}
diff --git a/commit.h b/commit.h
--- a/commit.h
+++ b/commit.h
@@ -59,4 +59,17 @@ struct commit *pop_most_recent_commit(st
struct commit *pop_commit(struct commit_list **stack);
int count_parents(struct commit * commit);
+
+/*
+ * Performs an in-place topological sort of list supplied.
+ *
+ * Pre-conditions:
+ * all commits in input list and all parents of those
+ * commits must have object.util == NULL
+ *
+ * Post-conditions:
+ * invariant of resulting list is:
+ * a reachable from b => ord(b) < ord(a)
+ */
+void sort_in_topological_order(struct commit_list ** list);
#endif /* COMMIT_H */
------------
^ permalink raw reply
* [PATCH 3/6] Introduce struct rev_list_fns to rev-list.c to reduce amount of conditional processing.
From: Jon Seymour @ 2005-07-06 7:51 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour
Per a suggestion from Linus, I have introduced the rev_list_fns structure into
rev-list.c
The intent of this change is to make use of a strategy pattern to configure
the behaviour of git-rev-list and so help limit the ever-increasing
proliferation of boolean switches throughout the body of the code.
This change also makes --show-breaks imply --merge-order rather than require
it as before. There was no advantage to the previous strict argument
checking.
A subsequent change will take advantage of this pattern to introduce a
topological sort switch.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
Documentation/git-rev-list.txt | 2 +
rev-list.c | 54 +++++++++++++++++++++++++++-------------
2 files changed, 38 insertions(+), 18 deletions(-)
1ecc1f5936fb35d2ea8e7aef2d97643a78fe1069
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -57,7 +57,7 @@ Commits marked with (^) are not parents
These "breaks" represent necessary discontinuities implied by trying to
represent an arbtirary DAG in a linear form.
-*--show-breaks* is only valid if *--merge-order* is also specified.
+*--show-breaks* implies **-merge-order*.
Author
------
diff --git a/rev-list.c b/rev-list.c
--- a/rev-list.c
+++ b/rev-list.c
@@ -39,6 +39,12 @@ static int merge_order = 0;
static int show_breaks = 0;
static int stop_traversal = 0;
+struct rev_list_fns {
+ struct commit_list * (*insert)(struct commit *, struct commit_list **);
+ struct commit_list * (*limit)(struct commit_list *);
+ void (*process)(struct commit_list *);
+};
+
static void show_commit(struct commit *commit)
{
commit->object.flags |= SHOWN;
@@ -410,9 +416,30 @@ static struct commit *get_commit_referen
die("%s is unknown object", name);
}
+static void merge_order_sort(struct commit_list * list)
+{
+ if (sort_list_in_merge_order(list, &process_commit))
+ die("commit graph traversal failed");
+}
+
+struct rev_list_fns default_fns = {
+ &insert_by_date,
+ &limit_list,
+ &show_commit_list
+};
+
+struct rev_list_fns merge_order_fns = {
+ &commit_list_insert,
+ NULL,
+ &merge_order_sort
+};
+
int main(int argc, char **argv)
{
struct commit_list *list = NULL;
+ struct commit_list *sorted = NULL;
+ struct commit_list **list_tail = &list;
+ struct rev_list_fns * fns = &default_fns;
int i, limited = 0;
for (i = 1 ; i < argc; i++) {
@@ -468,6 +495,7 @@ int main(int argc, char **argv)
}
if (!strcmp(arg, "--show-breaks")) {
show_breaks = 1;
+ merge_order = 1;
continue;
}
@@ -477,26 +505,18 @@ int main(int argc, char **argv)
arg++;
limited = 1;
}
- if (show_breaks && !merge_order)
- usage(rev_list_usage);
commit = get_commit_reference(arg, flags);
if (!commit)
continue;
- if (!merge_order)
- insert_by_date(commit, &list);
- else
- commit_list_insert(commit, &list);
+ list_tail = &commit_list_insert(commit, list_tail)->next;
}
-
- if (!merge_order) {
- if (limited)
- list = limit_list(list);
- show_commit_list(list);
- } else {
- if (sort_list_in_merge_order(list, &process_commit)) {
- die("merge order sort failed\n");
- }
- }
-
+ if (merge_order)
+ fns=&merge_order_fns;
+ while (list)
+ (*(fns->insert))(pop_commit(&list), &sorted);
+ list=sorted;
+ if (limited && fns->limit)
+ list = (*(fns->limit))(list);
+ (*(fns->process))(list);
return 0;
}
------------
^ permalink raw reply
* [PATCH 2/6] Swap order of insert_by_date arguments
From: Jon Seymour @ 2005-07-06 7:51 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour
Swap the order of insert_by_date arguments so that it
matches the order of commit_list_insert.
This patch anticipates a future change which will call the
function via a pointer.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
commit.c | 8 ++++----
commit.h | 6 +++++-
epoch.c | 4 ++--
rev-list.c | 2 +-
4 files changed, 12 insertions(+), 8 deletions(-)
486d4dee9772a59b955574951e8d4946b75cf9fa
diff --git a/commit.c b/commit.c
--- a/commit.c
+++ b/commit.c
@@ -147,7 +147,7 @@ void free_commit_list(struct commit_list
}
}
-void insert_by_date(struct commit_list **list, struct commit *item)
+struct commit_list * insert_by_date(struct commit *item, struct commit_list **list)
{
struct commit_list **pp = list;
struct commit_list *p;
@@ -157,7 +157,7 @@ void insert_by_date(struct commit_list *
}
pp = &p->next;
}
- commit_list_insert(item, pp);
+ return commit_list_insert(item, pp);
}
@@ -165,7 +165,7 @@ void sort_by_date(struct commit_list **l
{
struct commit_list *ret = NULL;
while (*list) {
- insert_by_date(&ret, (*list)->item);
+ insert_by_date((*list)->item, &ret);
*list = (*list)->next;
}
*list = ret;
@@ -186,7 +186,7 @@ struct commit *pop_most_recent_commit(st
parse_commit(commit);
if (!(commit->object.flags & mark)) {
commit->object.flags |= mark;
- insert_by_date(list, commit);
+ insert_by_date(commit, list);
}
parents = parents->next;
}
diff --git a/commit.h b/commit.h
--- a/commit.h
+++ b/commit.h
@@ -44,7 +44,11 @@ enum cmit_fmt {
extern enum cmit_fmt get_commit_format(const char *arg);
extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned long len, char *buf, unsigned long space);
-void insert_by_date(struct commit_list **list, struct commit *item);
+/*
+ * Inserts item into the list specified in most recent commit date first order.
+ * A pointer to the most recently inserted item is returned.
+ */
+struct commit_list * insert_by_date(struct commit *item, struct commit_list **list);
/** Removes the first commit from a list sorted by date, and adds all
* of its parents.
diff --git a/epoch.c b/epoch.c
--- a/epoch.c
+++ b/epoch.c
@@ -255,11 +255,11 @@ static int find_base_for_list(struct com
if (!parent_node) {
parent_node = new_mass_counter(parent, &distribution);
- insert_by_date(&pending, parent);
+ insert_by_date(parent, &pending);
commit_list_insert(parent, &cleaner);
} else {
if (!compare(&parent_node->pending, get_zero()))
- insert_by_date(&pending, parent);
+ insert_by_date(parent, &pending);
add(&parent_node->pending, &parent_node->pending, &distribution);
}
}
diff --git a/rev-list.c b/rev-list.c
--- a/rev-list.c
+++ b/rev-list.c
@@ -483,7 +483,7 @@ int main(int argc, char **argv)
if (!commit)
continue;
if (!merge_order)
- insert_by_date(&list, commit);
+ insert_by_date(commit, &list);
else
commit_list_insert(commit, &list);
}
------------
^ permalink raw reply
* [PATCH 1/6] Temporary fixup to rev-list.c to restore expected order of arguments presented to --merge-order sort.
From: Jon Seymour @ 2005-07-06 7:51 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour
This patch adds a hacky special case to the rev-list main to restore the order in which
the --merge-order sort algorithm receives arguments.
A subsequent patch will abstract this out more cleanly.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
rev-list.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
c63fe4678d33db15db076606f7a133868e91f1bc
diff --git a/rev-list.c b/rev-list.c
--- a/rev-list.c
+++ b/rev-list.c
@@ -482,7 +482,10 @@ int main(int argc, char **argv)
commit = get_commit_reference(arg, flags);
if (!commit)
continue;
- insert_by_date(&list, commit);
+ if (!merge_order)
+ insert_by_date(&list, commit);
+ else
+ commit_list_insert(commit, &list);
}
if (!merge_order) {
------------
^ permalink raw reply
* Re: [PATCH] Add commify function to cg-Xlib
From: Petr Baudis @ 2005-07-06 7:59 UTC (permalink / raw)
To: Frank Sorenson; +Cc: Git Mailing List
In-Reply-To: <42CB81A2.7080405@tuxrocks.com>
Dear diary, on Wed, Jul 06, 2005 at 09:00:50AM CEST, I got a letter
where Frank Sorenson <frank@tuxrocks.com> told me that...
> Here is a patch to add a commify function to cg-Xlib. I'll follow
> this up with a patch that uses the new function to commify the
> number and size of objects pulled in cg-pull.
>
> Signed-off-by: Frank Sorenson <frank@tuxrocks.com>
I don't know. Could you give some supporting argumentation, please? Is
it really that hard to read for the Americans without the commas? It is
at least harder to read for me as an European - we don't have any
commas in there, just spaces (if anything at all). Besides, the number
is usually not in higher order than thousands, so... why is it worth it?
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
<Espy> be careful, some twit might quote you out of context..
^ permalink raw reply
* [PATCH] clone-pack.c:write_one_ref() - Create leading directories.
From: Junio C Hamano @ 2005-07-06 8:11 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <7voe9gxw7y.fsf@assigned-by-dhcp.cox.net>
The function write_one_ref() is passed the list of refs received
from the other end, which was obtained by directory traversal
under $GIT_DIR/refs; this can contain paths other than what
git-init-db prepares and would fail to clone when there is
such.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
cache.h | 2 ++
clone-pack.c | 5 ++++-
sha1_file.c | 19 +++++++++++++++++++
3 files changed, 25 insertions(+), 1 deletions(-)
dfad9e5e585c1c9e1eaf599878f040f7ae519b18
diff --git a/cache.h b/cache.h
--- a/cache.h
+++ b/cache.h
@@ -161,6 +161,8 @@ extern void rollback_index_file(struct c
extern char *git_path(const char *fmt, ...);
extern char *sha1_file_name(const unsigned char *sha1);
+int safe_create_leading_directories(char *path);
+
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern void * map_sha1_file(const unsigned char *sha1, unsigned long *size);
extern int unpack_sha1_header(z_stream *stream, void *map, unsigned long mapsize, void *buffer, unsigned long size);
diff --git a/clone-pack.c b/clone-pack.c
--- a/clone-pack.c
+++ b/clone-pack.c
@@ -68,9 +68,12 @@ static int is_master(struct ref *ref)
static void write_one_ref(struct ref *ref)
{
char *path = git_path(ref->name);
- int fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0666);
+ int fd;
char *hex;
+ if (safe_create_leading_directories(path))
+ die("unable to create leading directory for %s", ref->name);
+ fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (fd < 0)
die("unable to create ref %s", ref->name);
hex = sha1_to_hex(ref->sha1);
diff --git a/sha1_file.c b/sha1_file.c
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -130,6 +130,25 @@ char *git_path(const char *fmt, ...)
return ret;
}
+int safe_create_leading_directories(char *path)
+{
+ char *pos = path;
+
+ while (pos) {
+ pos = strchr(pos, '/');
+ if (!pos)
+ break;
+ *pos = 0;
+ if (mkdir(path, 0777) < 0)
+ if (errno != EEXIST) {
+ *pos = '/';
+ return -1;
+ }
+ *pos++ = '/';
+ }
+ return 0;
+}
+
int get_sha1(const char *str, unsigned char *sha1)
{
static const char *prefix[] = {
^ permalink raw reply
* [PATCH] Tidy up - slight simplification of rev-list.c
From: Jon Seymour @ 2005-07-06 8:12 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour
This patch implements a small tidy up of rev-list.c to reduce
(but not eliminate) the amount of ugliness associated
with the merge_order flag.
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
Linus: I decided not to abstract this out as a function
as _too_ much abstraction can be a bad thing from a
readability point of view. Let me know if you disagree.
---
rev-list.c | 10 +++-------
1 files changed, 3 insertions(+), 7 deletions(-)
34a034b978c6b946fafdf41b42c5f67ee9c94599
diff --git a/rev-list.c b/rev-list.c
--- a/rev-list.c
+++ b/rev-list.c
@@ -78,19 +78,15 @@ static void show_commit(struct commit *c
static int filter_commit(struct commit * commit)
{
- if (merge_order && stop_traversal && commit->object.flags & BOUNDARY)
+ if (stop_traversal && (commit->object.flags & BOUNDARY))
return STOP;
if (commit->object.flags & (UNINTERESTING|SHOWN))
return CONTINUE;
if (min_age != -1 && (commit->date > min_age))
return CONTINUE;
if (max_age != -1 && (commit->date < max_age)) {
- if (!merge_order)
- return STOP;
- else {
- stop_traversal = 1;
- return CONTINUE;
- }
+ stop_traversal=1;
+ return merge_order?CONTINUE:STOP;
}
if (max_count != -1 && !max_count--)
return STOP;
------------
^ permalink raw reply
* [PATCH] Short-circuit git-clone-pack while cloning locally.
From: Junio C Hamano @ 2005-07-06 8:14 UTC (permalink / raw)
To: Linus Torvalds; +Cc: David S. Miller, Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0507051721450.3570@g5.osdl.org>
>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:
LT> Anyway, as mentioned, you can certainly do a local clone a lot faster with
LT> "cp -rl" (and yes, I'll apply Junio's patch if he makes it available
LT> against the new version, and adds a flag to make it conditional),...
By invitation.
------------
When we are cloning a repository on a local filesystem, it is
faster to just create a hard linkfarm of .git/object hierarchy
and copy the .git/refs files. By default, the script uses the
clone-pack method, but with -l and -c parameters it can be told
to do the hard linkfarm and recursive file copy to replicate
.git/object hierarchy.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
git-clone-script | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 79 insertions(+), 1 deletions(-)
1eb81b1791a751ca0fd1c3e7c1d4a4baacdd042a
diff --git a/git-clone-script b/git-clone-script
--- a/git-clone-script
+++ b/git-clone-script
@@ -1,4 +1,81 @@
#!/bin/sh
+#
+# Copyright (c) 2005, Linus Torvalds
+# Copyright (c) 2005, Junio C Hamano
+#
+# Clone a repository into a different directory that does not yet exist.
+
+usage() {
+ echo >&2 "* git clone [-l|-c|-p] <repo> <dir>"
+ exit 1
+}
+
+# what to do when running locally
+local_use=default
+while
+ case "$#,$1" in
+ 0,*) break ;;
+ *,-l) local_use=link ;;
+ *,-c) local_use=copy ;;
+ *,-p) local_use=pack ;;
+ *,-*) usage ;;
+ *) break ;;
+ esac
+do
+ shift
+done
+
repo="$1"
dir="$2"
-mkdir "$dir" && cd "$dir" && git-init-db && git-clone-pack "$repo"
+mkdir "$dir" &&
+D=$(
+ (cd "$dir" && git-init-db && pwd)
+) || exit 1
+
+# See if repo is a local directory.
+is_local=f
+if (
+ cd "$repo/objects" 2>/dev/null
+)
+then
+ is_local=t
+fi
+
+case "$local_use,$is_local" in
+default,f)
+ ;;
+*,f) echo >&2 "-l|-c|-p flag can be used only when cloning a local repo"
+ exit 1
+ ;;
+copy,t | link,t)
+ l=
+ case "$local_use" in
+ link)
+ # See if we can hardlink and drop "l" if not.
+ sample_file=$(cd "$repo" && \
+ find objects -type f -print | sed -e 1q)
+
+ # objects directory should not be empty since we are cloning!
+ test -f "$repo/$sample_file" || exit
+
+ if ln "$repo/$sample_file" "$D/.git/objects/sample" 2>/dev/null
+ then
+ l=l
+ fi &&
+ rm -f "$D/.git/objects/sample"
+ ;;
+ esac &&
+ cp -r$l "$repo/objects" "$D/.git/" || exit 1
+
+ # Make a duplicate of refs and HEAD pointer
+ HEAD=
+ if test -f "$repo/HEAD"
+ then
+ HEAD=HEAD
+ fi
+ tar Ccf "$repo" - refs $HEAD | tar Cxf "$D/.git" - || exit 1
+ ;;
+*)
+ cd "$D" && git clone-pack "$repo"
+ ;;
+esac
^ permalink raw reply
* [PATCH] Let umask do its work upon filesystem object creation.
From: Junio C Hamano @ 2005-07-06 8:21 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
IIRC our strategy was to let the users' umask take care of the
final mode bits. This patch fixes places that deviate from it.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
apply.c | 2 +-
csum-file.c | 2 +-
entry.c | 4 ++--
init-db.c | 2 +-
receive-pack.c | 2 +-
5 files changed, 6 insertions(+), 6 deletions(-)
ccb441ce2e7be11fcab19f385332c530bff132f0
diff --git a/apply.c b/apply.c
--- a/apply.c
+++ b/apply.c
@@ -1237,7 +1237,7 @@ static void create_subdirectories(const
len = slash - path;
memcpy(buf, path, len);
buf[len] = 0;
- if (mkdir(buf, 0755) < 0) {
+ if (mkdir(buf, 0777) < 0) {
if (errno != EEXIST)
break;
}
diff --git a/csum-file.c b/csum-file.c
--- a/csum-file.c
+++ b/csum-file.c
@@ -86,7 +86,7 @@ struct sha1file *sha1create(const char *
die("you wascally wabbit, you");
f->namelen = len;
- fd = open(f->name, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ fd = open(f->name, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (fd < 0)
die("unable to open %s (%s)", f->name, strerror(errno));
f->fd = fd;
diff --git a/entry.c b/entry.c
--- a/entry.c
+++ b/entry.c
@@ -12,10 +12,10 @@ static void create_directories(const cha
len = slash - path;
memcpy(buf, path, len);
buf[len] = 0;
- if (mkdir(buf, 0755)) {
+ if (mkdir(buf, 0777)) {
if (errno == EEXIST) {
struct stat st;
- if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0755))
+ if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0777))
continue;
if (!stat(buf, &st) && S_ISDIR(st.st_mode))
continue; /* ok */
diff --git a/init-db.c b/init-db.c
--- a/init-db.c
+++ b/init-db.c
@@ -7,7 +7,7 @@
static void safe_create_dir(const char *dir)
{
- if (mkdir(dir, 0755) < 0) {
+ if (mkdir(dir, 0777) < 0) {
if (errno != EEXIST) {
perror(dir);
exit(1);
diff --git a/receive-pack.c b/receive-pack.c
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -70,7 +70,7 @@ static void update(const char *name, uns
if (!has_sha1_file(new_sha1))
die("unpack should have generated %s, but I can't find it!", new_hex);
- newfd = open(lock_name, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ newfd = open(lock_name, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (newfd < 0)
die("unable to create %s (%s)", lock_name, strerror(errno));
^ permalink raw reply
* [PATCH 1/3] Factor out useful test case infrastructure from t/t6001... into t/t6000-lib.sh
From: Jon Seymour @ 2005-07-06 10:11 UTC (permalink / raw)
To: git; +Cc: torvalds, jon.seymour
Functions that are useful to other t6xxx testcases are moved into t6000-lib.sh
To use these functions in a test case, use a test-case pre-amble like:
. ./test-lib.sh
. ../t6000-lib.sh # t6xxx specific functions
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
---
This patch series introduces tests for the git-rev-list --bisect functionality
and includes Mark Allen's sed separator patch.
The patches included are:
[PATCH 1/3] Factor out useful test case infrastructure from t/t6001... into t/t6000-lib.sh
[PATCH 2/3] Introduce unit tests for git-rev-list --bisect
[PATCH 3/3] Change the sed seperator in t/t6000-lib.sh.
---
t/t6000-lib.sh | 105 +++++++++++++++++++++++++++++++++++++
t/t6001-rev-list-merge-order.sh | 112 ---------------------------------------
2 files changed, 106 insertions(+), 111 deletions(-)
create mode 100644 t/t6000-lib.sh
a6686d8335905d55ef6cf996af1d3eb229ad955c
diff --git a/t/t6000-lib.sh b/t/t6000-lib.sh
new file mode 100644
--- /dev/null
+++ b/t/t6000-lib.sh
@@ -0,0 +1,105 @@
+[ -d .git/refs/tags ] || mkdir -p .git/refs/tags
+
+sed_script="";
+
+# Answer the sha1 has associated with the tag. The tag must exist in .git or .git/refs/tags
+tag()
+{
+ _tag=$1
+ [ -f .git/refs/tags/$_tag ] || error "tag: \"$_tag\" does not exist"
+ cat .git/refs/tags/$_tag
+}
+
+# Generate a commit using the text specified to make it unique and the tree
+# named by the tag specified.
+unique_commit()
+{
+ _text=$1
+ _tree=$2
+ shift 2
+ echo $_text | git-commit-tree $(tag $_tree) "$@"
+}
+
+# Save the output of a command into the tag specified. Prepend
+# a substitution script for the tag onto the front of $sed_script
+save_tag()
+{
+ _tag=$1
+ [ -n "$_tag" ] || error "usage: save_tag tag commit-args ..."
+ shift 1
+ "$@" >.git/refs/tags/$_tag
+ sed_script="s/$(tag $_tag)/$_tag/g${sed_script+;}$sed_script"
+}
+
+# Replace unhelpful sha1 hashses with their symbolic equivalents
+entag()
+{
+ sed "$sed_script"
+}
+
+# Execute a command after first saving, then setting the GIT_AUTHOR_EMAIL
+# tag to a specified value. Restore the original value on return.
+as_author()
+{
+ _author=$1
+ shift 1
+ _save=$GIT_AUTHOR_EMAIL
+
+ export GIT_AUTHOR_EMAIL="$_author"
+ "$@"
+ export GIT_AUTHOR_EMAIL="$_save"
+}
+
+commit_date()
+{
+ _commit=$1
+ git-cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p"
+}
+
+on_committer_date()
+{
+ _date=$1
+ shift 1
+ GIT_COMMITTER_DATE=$_date "$@"
+}
+
+# Execute a command and suppress any error output.
+hide_error()
+{
+ "$@" 2>/dev/null
+}
+
+check_output()
+{
+ _name=$1
+ shift 1
+ if eval "$*" | entag > $_name.actual
+ then
+ diff $_name.expected $_name.actual
+ else
+ return 1;
+ fi
+}
+
+# Turn a reasonable test description into a reasonable test name.
+# All alphanums translated into -'s which are then compressed and stripped
+# from front and back.
+name_from_description()
+{
+ tr "'" '-' | tr '~`!@#$%^&*()_+={}[]|\;:"<>,/? ' '-' | tr -s '-' | tr '[A-Z]' '[a-z]' | sed "s/^-*//;s/-*\$//"
+}
+
+
+# Execute the test described by the first argument, by eval'ing
+# command line specified in the 2nd argument. Check the status code
+# is zero and that the output matches the stream read from
+# stdin.
+test_output_expect_success()
+{
+ _description=$1
+ _test=$2
+ [ $# -eq 2 ] || error "usage: test_output_expect_success description test <<EOF ... EOF"
+ _name=$(echo $_description | name_from_description)
+ cat > $_name.expected
+ test_expect_success "$_description" "check_output $_name \"$_test\""
+}
diff --git a/t/t6001-rev-list-merge-order.sh b/t/t6001-rev-list-merge-order.sh
--- a/t/t6001-rev-list-merge-order.sh
+++ b/t/t6001-rev-list-merge-order.sh
@@ -6,117 +6,7 @@
test_description='Tests git-rev-list --merge-order functionality'
. ./test-lib.sh
-
-#
-# TODO: move the following block (upto --- end ...) into testlib.sh
-#
-[ -d .git/refs/tags ] || mkdir -p .git/refs/tags
-
-sed_script="";
-
-# Answer the sha1 has associated with the tag. The tag must exist in .git or .git/refs/tags
-tag()
-{
- _tag=$1
- [ -f .git/refs/tags/$_tag ] || error "tag: \"$_tag\" does not exist"
- cat .git/refs/tags/$_tag
-}
-
-# Generate a commit using the text specified to make it unique and the tree
-# named by the tag specified.
-unique_commit()
-{
- _text=$1
- _tree=$2
- shift 2
- echo $_text | git-commit-tree $(tag $_tree) "$@"
-}
-
-# Save the output of a command into the tag specified. Prepend
-# a substitution script for the tag onto the front of $sed_script
-save_tag()
-{
- _tag=$1
- [ -n "$_tag" ] || error "usage: save_tag tag commit-args ..."
- shift 1
- "$@" >.git/refs/tags/$_tag
- sed_script="s/$(tag $_tag)/$_tag/g${sed_script+;}$sed_script"
-}
-
-# Replace unhelpful sha1 hashses with their symbolic equivalents
-entag()
-{
- sed "$sed_script"
-}
-
-# Execute a command after first saving, then setting the GIT_AUTHOR_EMAIL
-# tag to a specified value. Restore the original value on return.
-as_author()
-{
- _author=$1
- shift 1
- _save=$GIT_AUTHOR_EMAIL
-
- export GIT_AUTHOR_EMAIL="$_author"
- "$@"
- export GIT_AUTHOR_EMAIL="$_save"
-}
-
-commit_date()
-{
- _commit=$1
- git-cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p"
-}
-
-on_committer_date()
-{
- _date=$1
- shift 1
- GIT_COMMITTER_DATE=$_date "$@"
-}
-
-# Execute a command and suppress any error output.
-hide_error()
-{
- "$@" 2>/dev/null
-}
-
-check_output()
-{
- _name=$1
- shift 1
- if eval "$*" | entag > $_name.actual
- then
- diff $_name.expected $_name.actual
- else
- return 1;
- fi
-}
-
-# Turn a reasonable test description into a reasonable test name.
-# All alphanums translated into -'s which are then compressed and stripped
-# from front and back.
-name_from_description()
-{
- tr "'" '-' | tr '~`!@#$%^&*()_+={}[]|\;:"<>,/? ' '-' | tr -s '-' | tr '[A-Z]' '[a-z]' | sed "s/^-*//;s/-*\$//"
-}
-
-
-# Execute the test described by the first argument, by eval'ing
-# command line specified in the 2nd argument. Check the status code
-# is zero and that the output matches the stream read from
-# stdin.
-test_output_expect_success()
-{
- _description=$1
- _test=$2
- [ $# -eq 2 ] || error "usage: test_output_expect_success description test <<EOF ... EOF"
- _name=$(echo $_description | name_from_description)
- cat > $_name.expected
- test_expect_success "$_description" "check_output $_name \"$_test\""
-}
-
-# --- end of stuff to move ---
+. ../t6000-lib.sh # t6xxx specific functions
# test-case specific test function
check_adjacency()
------------
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox