* [PATCH next] t1505: remove debugging cruft
From: Thomas Rast @ 2009-01-24 22:23 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Johannes Schindelin
In-Reply-To: <200901242322.02440.trast@student.ethz.ch>
Remove a call to git-log that I introduced for debugging and that
accidentally made it into d18ba22 (sha1_name: support @{-N} syntax in
get_sha1(), 2009-01-17).
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
t/t1505-rev-parse-last.sh | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/t/t1505-rev-parse-last.sh b/t/t1505-rev-parse-last.sh
index c745ec4..d709ecf 100755
--- a/t/t1505-rev-parse-last.sh
+++ b/t/t1505-rev-parse-last.sh
@@ -32,8 +32,6 @@ test_expect_success 'setup' '
#
# and 'side' should be the last branch
-git log --graph --all --pretty=oneline --decorate
-
test_rev_equivalent () {
git rev-parse "$1" > expect &&
--
1.6.1.468.g15c0
^ permalink raw reply related
* Re: Heads up: major rebase -i -p rework coming up
From: Thomas Rast @ 2009-01-24 22:47 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Stephen Haberman, spearce, Björn Steinbrink
In-Reply-To: <alpine.DEB.1.00.0901242056070.14855@racer>
[-- Attachment #1: Type: text/plain, Size: 1729 bytes --]
Johannes Schindelin wrote:
> Worse, the whole concept of "pick <merge-sha1>" just does not fly well.
[...]
> - merge $sha1 [$sha1...] was $sha1 "Merge ..."
>
> will merge the given list of commits into the current HEAD, for
> the user's reference and to keep up-to-date what was rewritten,
> the original merge is shown after the keyword "was" (which is not
> a valid SHA-1, luckily)
I really like the underlying idea. I'm not even sure if the current
semantics are well-defined in all cases; an explicit merge command at
least makes it very clear what is going on.
However, I think the syntax as proposed above is a bit confusing in
the usual two-parent merge. I couldn't tell whether
merge A was B
was intended to be read as "the merge of A into the current branch" or
"the merge with sha1 A" right away, and I doubt I'll be able to tell
without looking in the (rare) cases I have to invoke rebase -i -p.
I can't really come up with a better replacement for 'was', so how
about
merge A # was B "Merge..."
which would make it more clear that the "was B..." has no effect
whatsoever on the merge's semantics.
> A - B - - - E
> \ /
> C - D
>
> could yield this TODO script:
>
> pick A
> pick C
> pick D
> goto A'
> pick B
> merge D' was E
I kind of wonder if it would be possible to decorate the TODO with
'git log --graph' output, to make it easier to follow the history as
it is built. Perhaps something like
* pick A
|\
* | pick B
goto A'
| * pick C
| * pick D
|/
goto B'
* merge D' # was E
Well, maybe it's not such a good idea after all.
--
Thomas Rast
trast@{inf,student}.ethz.ch
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: Heads up: major rebase -i -p rework coming up
From: Junio C Hamano @ 2009-01-24 23:01 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Stephan Beyer, git, Stephen Haberman, spearce, Thomas Rast,
Björn Steinbrink
In-Reply-To: <alpine.DEB.1.00.0901242156320.14855@racer>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> - What's with the apostrophe? I seem to remember that you argued it
>> would be enough to make "A" stand for the original when it is used for
>> the first time and the second and later use can stand for the result
>> of the last use (e.g. the "goto A'" above can be simply spelled as
>> "goto A"), when I suggested to use "mark" in a way similar to how
>> fast-import language uses it during the sequencer discussion?
>>
>> I am not complaining; I am just being curious why the sudden change of
>> heart.
>
> Very easy explanation. I got convinced by your arguments. Even if I
> could imagine that I never use the thing without apostrophe, it is good to
> have an obvious indicator that this is not necessarily the original
> commit.
Now that does not make much sense to me.
The reason I suggested that 'mark' would give a cleaner semantics was
because in your earlier design "A" could either stand for the original or
it could stand for the result of an operation that used "A", and there
could be more than one operation that uses "A". Explicitly naming each
result with a mark would give us an unambiguous way to distinguish them.
I however do not think you would ever use A twice in the context of
"rebase -i/-p". Cherry-picking the same commit twice to create two copies
of them will not happen in that context.
While trying to recreate something like this on top of a commit "o", you
would have to talk about "A" multiple times,...
B---M
/ / \
---o---A---C \
\ \ \
D---N-------O
... but even in such a picture, after one "pick A", you would always want
to refer to the result of the pick, and never the original A.
pick A
goto A'^
pick D
merge A' was N
goto A'
pick B
goto A'
pick C
merge B' was M
merge N' was O
So I am inclined to think that "first use refers to the original, second
and thereafter will refer to the result of the first use" would be a good
enough semantics for "rebase -i/-p", and you do not need "A" vs "A'" for
this.
By the way, I think this example shows that your "goto" might need a way
to refer to the "onto" commit in some way (I just used "A'^" there).
On the other hand, if you are aiming to allow users to create (by editing
the insn file) an arbitrarily different structure like this, starting from
the same topology:
---o---B---C---A
\ \
A---D-------O
that is, rebasing the upper line of development into one linear sequence
with different patch order, while rebasing the lower line into another
linear sequence by rebasing D on top of A, you would need to be able to
refer to the two different results of "using A", and your "A'" notation
would not help.
pick B
pick C
pick A
goto B'^
pick A
pick D
merge A' was O
The last "merge A' was O" is done while on the result of applying D on top
of the result of applying A on the lower line, and wants to call the tip
of the upper line by referring it as "the result of applying A".
But there are two results from applying A, and I do not think you can
avoid 'mark', even though you for some reason seem to hate it.
If this kind of transformation is outside the scope of your redesign
(which I think is a sensible design decision), I do not see why you would
need "A vs A'".
You either need the full power of 'mark', or "A is original until it is
used, and then the one and only one result once it is used,"; nothing in
between like "A vs A'" would make much sense.
^ permalink raw reply
* [PATCH 01/10] cvsserver: removed unused sha1Or-k mode from kopts_from_path
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
In-Reply-To: <1232840601-24696-1-git-send-email-mmogilvi_git@miniinfo.net>
sha1Or-k was a vestige from an early, never-released
attempt to handle some oddball cases of CRLF conversion (-k option).
Ultimately it wasn't needed, and I should have gotten rid of it
before submitting the CRLF patch in the first place.
See also 90948a42892779 (add ability to guess -kb from contents).
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
git-cvsserver.perl | 38 +++++---------------------------------
1 files changed, 5 insertions(+), 33 deletions(-)
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index fef7faf..1de0c1e 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -2355,42 +2355,14 @@ sub kopts_from_path
}
elsif( ($cfg->{gitcvs}{allbinary} =~ /^\s*guess\s*$/i) )
{
- if( $srcType eq "sha1Or-k" &&
- !defined($name) )
+ if( is_binary($srcType,$name) )
{
- my ($ret)=$state->{entries}{$path}{options};
- if( !defined($ret) )
- {
- $ret=$state->{opt}{k};
- if(defined($ret))
- {
- $ret="-k$ret";
- }
- else
- {
- $ret="";
- }
- }
- if( ! ($ret=~/^(|-kb|-kkv|-kkvl|-kk|-ko|-kv)$/) )
- {
- print "E Bad -k option\n";
- $log->warn("Bad -k option: $ret");
- die "Error: Bad -k option: $ret\n";
- }
-
- return $ret;
+ $log->debug("... as binary");
+ return "-kb";
}
else
{
- if( is_binary($srcType,$name) )
- {
- $log->debug("... as binary");
- return "-kb";
- }
- else
- {
- $log->debug("... as text");
- }
+ $log->debug("... as text");
}
}
}
@@ -2497,7 +2469,7 @@ sub open_blob_or_die
die "Unable to open file $name: $!\n";
}
}
- elsif( $srcType eq "sha1" || $srcType eq "sha1Or-k" )
+ elsif( $srcType eq "sha1" )
{
unless ( defined ( $name ) and $name =~ /^[a-zA-Z0-9]{40}$/ )
{
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 00/10] Misc. cvsserver, dashless, and test suite patches
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
This series of small patches fixes a few minor issues I noticed
while researching what it would take to for cvsserver to support
cvs's "-r" flags properly. No real progress on the "-r" front,
but see comments in the "cvsserver: add comments about database ..."
email.
The "run test suite without dashed..." patch has wide scope,
even though is is fairly small. It (along with fixing the things it
found in t2300 and t3409) was inspired by a desire to avoid future
regressions of the bug fixed in "cvsserver: run dashless 'git commands'"
patch, where git-cvsserver was trying to run dashed commands that
are not in the default PATH...
As this patch series was going to press, I noticed that
the "run test suite without dashed..." patch probably conflicts with
recently posted valgrind test suite patches. See extra comments in
the email for possible resolutions.
The other patches in this series are mostly independent of each other.
When working on the "git-shell" patch, I noticed a couple of other
things related to "git-shell" that maybe ought to be changed (change
the argc==2 special case, and document the best way(s) to
configure an account to use git-shell). See also extra information in
the email.
--
Matthew Ogilvie [mmogilvi_git@miniinfo.net]
Matthew Ogilvie (10):
cvsserver: removed unused sha1Or-k mode from kopts_from_path
cvsserver: add comments about database schema/usage
cvsserver: remove unused functions _headrev and gethistory
git-shell: allow running git-cvsserver, not just cvs
cvsserver: run dashless "git command"s to access plumbing
t2300: use documented technique to invoke git-sh-setup
t3409: use dashless "git commit" instead of "git-commit"
run test suite without dashed git-commands in PATH
Revert "adapt git-cvsserver manpage to dash-free syntax"
cvsserver doc: emphasize using CVS_SERVER= phrase within CVSROOT
.gitignore | 1 +
Documentation/git-cvsserver.txt | 29 +++++--
Documentation/git-shell.txt | 5 +-
Makefile | 40 +++++++---
git-cvsserver.perl | 163 ++++++++++++++++---------------------
shell.c | 1 +
t/t2300-cd-to-toplevel.sh | 2 +-
t/t3409-rebase-preserve-merges.sh | 6 +-
t/t9400-git-cvsserver-server.sh | 88 ++++++++++++++++++++
t/test-lib.sh | 14 +++-
test-bin-wrapper.sh | 12 +++
11 files changed, 246 insertions(+), 115 deletions(-)
create mode 100644 test-bin-wrapper.sh
^ permalink raw reply
* [PATCH 02/10] cvsserver: add comments about database schema/usage
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
In-Reply-To: <1232840601-24696-2-git-send-email-mmogilvi_git@miniinfo.net>
No functionality changes, but these comments should make it easier to
understand how it works.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
This is the result of some initial research into what it would
take to support switching branches/tags/commithashes for the entire
sandbox using "cvs update -r TAG". This seems like the one remaining
big missing feature that makes git-cvsserver a substantial downgrade
compared to a real CVS server.
git-cvsserver's support for cvs's "-r" arguments is kind of hit
or miss:
- Some commands ignore it completely. This includes "checkout",
but checkout does have a kind of workaround: you can checkout
any branch by specifying "cvs checkout branch". (Normally
it is "cvs checkout module".) But that sandbox is then locked
to that branch, you can't switch to another.
- Some commands (e.g. update) allow you to specify CVS-style
version numbers with -r, but that is generally only useful if
you are examining a single file.
- Some of those commands also recognize git commit hashes. But
due to the internal database model, the commithash form will only
work for files that were actually modified in the requested
commit, and for which cvsserver has previously decided that
the commit is on the same branch that the sandbox
is locked to (it has already assigned CVS revision numbers
for it). Other commands (including update) do not recognize
the commithash form at all (ignores it if it doesn't look like
a CVS version number, even though the underlying getmeta()
function is more a little more general).
Even the relatively simple goal of being able to update to an
older version on the same branch involves some significant costs:
- Perhaps store O(numCommits*totalNumFiles) entries in the
revision table, instead of the current more reasonable
O(numCommits*averageNumChangedFilesPerCommit). Perhaps
this could be combined with a significant schema change that
involves assigning short ints to distinct commithash
values and distinct filenames, looking up author/mode
information directly in git on demand, and just storing the
short ints in the revisions table to shrink each row
as much as possible.
- Fork off extra git commands to find the most recent
commit (relative to the supplied commit) that modified each
file, then look that up in the DB. For many files, it
is likely to have to search quite a ways, and if it the search
is done with a separate command per file, it could
get expensive. Also watch out for "other"
branches that won't be in the DB. Sounds like a lot
of extra CPU usage re-parsing commit history for every
file...
Thoughts about full branch support in cvsserver:
- One way would be to add a "branch" column to the "revisions"
and "headers" tables. Also add a branch table (details TBD)?
- Alternatively, drop the DB and see if maybe we could store
file revision number information using git's core data structures:
"refs/cvsfileversions/{branch}", with a tree structure for storing
file revision number to commithash/path mappings that is
specifically designed to use the strengths of the DAG
representation and pack files.
- I have vague notions of other techniques as well.
- Recognise that names of branches may change as heads advance
and things get merged, but the CVS branch /number/ needs
to remain consistent.
- Recognize that in general you can not reliably regenerate
the DB. Depending on what sequence of git-cvsserver and
git-merge commands, versions of files can end up with
different CVS revision numbers.
- Has anyone thought about implementing server emulators for
other version control systems (git-svnserver and similar)?
--
Matthew Ogilvie [mmogilvi_git@miniinfo.net]
git-cvsserver.perl | 46 ++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index 1de0c1e..f7891b8 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -2045,6 +2045,10 @@ sub statecleanup
$state->{entries} = {};
}
+# Return working directory revision int "X" from CVS revision "1.X" out
+# of the the working directory "entries" state, for the given filename.
+# Return negative "X" to represent the file is scheduled for removal
+# when it is committed.
sub revparse
{
my $filename = shift;
@@ -2775,6 +2779,16 @@ sub new
}
# Construct the revision table if required
+ # The revision table stores an entry for each file, each time that file
+ # changes.
+ # numberOfRecords = O( numCommits * averageNumChangedFilesPerCommit )
+ # This is not sufficient to support "-r {commithash}" for any
+ # files except files that were modified by that commit (also,
+ # some places in the code ignore/effectively strip out -r in
+ # some cases, before it gets passed to getmeta()).
+ # The "filehash" field typically has a git blob hash, but can also
+ # be set to "dead" to indicate that the given version of the file
+ # should not exist in the sandbox.
unless ( $self->{tables}{$self->tablename("revision")} )
{
my $tablename = $self->tablename("revision");
@@ -2802,6 +2816,15 @@ sub new
}
# Construct the head table if required
+ # The head table (along with the "last_commit" entry in the property
+ # table) is the persisted working state of the "sub update" subroutine.
+ # All of it's data is read entirely first, and completely recreated
+ # last, every time "sub update" runs.
+ # This is also used by "sub getmeta" when it is asked for the latest
+ # version of a file (as opposed to some specific version).
+ # Another way of thinking about it is as a single slice out of
+ # "revisions", giving just the most recent revision information for
+ # each file.
unless ( $self->{tables}{$self->tablename("head")} )
{
my $tablename = $self->tablename("head");
@@ -2824,6 +2847,7 @@ sub new
}
# Construct the properties table if required
+ # - "last_commit" - Used by "sub update".
unless ( $self->{tables}{$self->tablename("properties")} )
{
my $tablename = $self->tablename("properties");
@@ -2836,6 +2860,11 @@ sub new
}
# Construct the commitmsgs table if required
+ # The commitmsgs table is only used for merge commits, since
+ # "sub update" will only keep one branch of parents. Shortlogs
+ # for ignored commits (i.e. not on the chosen branch) will be used
+ # to construct a replacement "collapsed" merge commit message,
+ # which will be stored in this table. See also "sub commitmessage".
unless ( $self->{tables}{$self->tablename("commitmsgs")} )
{
my $tablename = $self->tablename("commitmsgs");
@@ -2867,6 +2896,14 @@ sub tablename
=head2 update
+Bring the database up to date with the latest changes from
+the git repository.
+
+Internal working state is read out of the "head" table and the
+"last_commit" property, then it updates "revisions" based on that, and
+finally it writes the new internal state back to the "head" table
+so it can be used as a starting point the next time update is called.
+
=cut
sub update
{
@@ -2980,17 +3017,18 @@ sub update
next;
} elsif (@{$commit->{parents}} > 1) {
# it is a merge commit, for each parent that is
- # not $lastpicked, see if we can get a log
+ # not $lastpicked (not given a CVS revision number),
+ # see if we can get a log
# from the merge-base to that parent to put it
# in the message as a merge summary.
my @parents = @{$commit->{parents}};
foreach my $parent (@parents) {
- # git-merge-base can potentially (but rarely) throw
- # several candidate merge bases. let's assume
- # that the first one is the best one.
if ($parent eq $lastpicked) {
next;
}
+ # git-merge-base can potentially (but rarely) throw
+ # several candidate merge bases. let's assume
+ # that the first one is the best one.
my $base = eval {
safe_pipe_capture('git-merge-base',
$lastpicked, $parent);
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 06/10] t2300: use documented technique to invoke git-sh-setup
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
In-Reply-To: <1232840601-24696-6-git-send-email-mmogilvi_git@miniinfo.net>
This is needed to allow the test suite to run against a minimal bin
directory instead of GIT_EXEC_PATH.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
t/t2300-cd-to-toplevel.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/t/t2300-cd-to-toplevel.sh b/t/t2300-cd-to-toplevel.sh
index e42cbfe..eac348a 100755
--- a/t/t2300-cd-to-toplevel.sh
+++ b/t/t2300-cd-to-toplevel.sh
@@ -8,7 +8,7 @@ test_cd_to_toplevel () {
test_expect_success "$2" '
(
cd '"'$1'"' &&
- . git-sh-setup &&
+ . "$(git --exec-path)"/git-sh-setup &&
cd_to_toplevel &&
[ "$(unset PWD; /bin/pwd)" = "$TOPLEVEL" ]
)
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 05/10] cvsserver: run dashless "git command"s to access plumbing
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
In-Reply-To: <1232840601-24696-5-git-send-email-mmogilvi_git@miniinfo.net>
git-cvsserver has been installed in the default $(bindir)
since 1df2a1ce806, but if you actually invoke it that way
(CVS_SERVER=git-cvsserver), it was failing because most of the
dashed-form plumbing commands cvsserver invokes are not in the PATH.
It seems best not to just switch to pure CVS_SERVER="git cvsserver",
which does not work with cvs's ":fork:" connection scheme. In
this case "cvs" presumably uses the whole value as argv[0] for
exec(), and of course no execuable named "git cvsserver" exists.
But both settings worked under some circumstances:
CVS_SERVER="git cvsserver" works OK for cvs's ":ext:" scheme (at
least with ssh), presumably because of how sshd invokes
/bin/sh -c "{args}" with limited quoting, and "git"
would set up the PATH so that cvsserver could run dashed commands
correctly.
Also, CVS_SERVER="git-cvsserver" has been working OK under git's test
framework, because the test framework currently always sets up a PATH
that includes the dashed forms.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
Note: I only changed the actual command invocations; I left error
messages and comments as-is. Should they be changed as well?
--
Matthew Ogilvie [mmogilvi_git@miniinfo.net]
git-cvsserver.perl | 40 ++++++++++++++++++++--------------------
1 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index fe23b49..8e9e659 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -283,7 +283,7 @@ sub req_Root
return 0;
}
- my @gitvars = `git-config -l`;
+ my @gitvars = `git config -l`;
if ($?) {
print "E problems executing git-config on the server -- this is not a git repository or the PATH is not set correctly.\n";
print "E \n";
@@ -700,7 +700,7 @@ sub req_Modified
# Save the file data in $state
$state->{entries}{$state->{directory}.$data}{modified_filename} = $filename;
$state->{entries}{$state->{directory}.$data}{modified_mode} = $mode;
- $state->{entries}{$state->{directory}.$data}{modified_hash} = `git-hash-object $filename`;
+ $state->{entries}{$state->{directory}.$data}{modified_hash} = `git hash-object $filename`;
$state->{entries}{$state->{directory}.$data}{modified_hash} =~ s/\s.*$//s;
#$log->debug("req_Modified : file=$data mode=$mode size=$size");
@@ -1287,7 +1287,7 @@ sub req_ci
# do a checkout of the file if it is part of this tree
if ($wrev) {
- system('git-checkout-index', '-f', '-u', $filename);
+ system('git', 'checkout-index', '-f', '-u', $filename);
unless ($? == 0) {
die "Error running git-checkout-index -f -u $filename : $!";
}
@@ -1329,15 +1329,15 @@ sub req_ci
{
$log->info("Removing file '$filename'");
unlink($filename);
- system("git-update-index", "--remove", $filename);
+ system("git", "update-index", "--remove", $filename);
}
elsif ( $addflag )
{
$log->info("Adding file '$filename'");
- system("git-update-index", "--add", $filename);
+ system("git", "update-index", "--add", $filename);
} else {
$log->info("Updating file '$filename'");
- system("git-update-index", $filename);
+ system("git", "update-index", $filename);
}
}
@@ -1349,7 +1349,7 @@ sub req_ci
return;
}
- my $treehash = `git-write-tree`;
+ my $treehash = `git write-tree`;
chomp $treehash;
$log->debug("Treehash : $treehash, Parenthash : $parenthash");
@@ -1366,7 +1366,7 @@ sub req_ci
}
close $msg_fh;
- my $commithash = `git-commit-tree $treehash -p $parenthash < $msg_filename`;
+ my $commithash = `git commit-tree $treehash -p $parenthash < $msg_filename`;
chomp($commithash);
$log->info("Commit hash : $commithash");
@@ -1819,7 +1819,7 @@ sub req_annotate
# TODO: if we got a revision from the client, use that instead
# to look up the commithash in sqlite (still good to default to
# the current head as we do now)
- system("git-read-tree", $lastseenin);
+ system("git", "read-tree", $lastseenin);
unless ($? == 0)
{
print "E error running git-read-tree $lastseenin $ENV{GIT_INDEX_FILE} $!\n";
@@ -1828,7 +1828,7 @@ sub req_annotate
$log->info("Created index '$ENV{GIT_INDEX_FILE}' with commit $lastseenin - exit status $?");
# do a checkout of the file
- system('git-checkout-index', '-f', '-u', $filename);
+ system('git', 'checkout-index', '-f', '-u', $filename);
unless ($? == 0) {
print "E error running git-checkout-index -f -u $filename : $!\n";
return;
@@ -1859,7 +1859,7 @@ sub req_annotate
close ANNOTATEHINTS
or (print "E failed to write $a_hints: $!\n"), return;
- my @cmd = (qw(git-annotate -l -S), $a_hints, $filename);
+ my @cmd = (qw(git annotate -l -S), $a_hints, $filename);
if (!open(ANNOTATE, "-|", @cmd)) {
print "E error invoking ". join(' ',@cmd) .": $!\n";
return;
@@ -2080,17 +2080,17 @@ sub transmitfile
die "Need filehash" unless ( defined ( $filehash ) and $filehash =~ /^[a-zA-Z0-9]{40}$/ );
- my $type = `git-cat-file -t $filehash`;
+ my $type = `git cat-file -t $filehash`;
chomp $type;
die ( "Invalid type '$type' (expected 'blob')" ) unless ( defined ( $type ) and $type eq "blob" );
- my $size = `git-cat-file -s $filehash`;
+ my $size = `git cat-file -s $filehash`;
chomp $size;
$log->debug("transmitfile($filehash) size=$size, type=$type");
- if ( open my $fh, '-|', "git-cat-file", "blob", $filehash )
+ if ( open my $fh, '-|', "git", "cat-file", "blob", $filehash )
{
if ( defined ( $options->{targetfile} ) )
{
@@ -2942,7 +2942,7 @@ sub update
push @git_log_params, $self->{module};
}
# git-rev-list is the backend / plumbing version of git-log
- open(GITLOG, '-|', 'git-rev-list', @git_log_params) or die "Cannot call git-rev-list: $!";
+ open(GITLOG, '-|', 'git', 'rev-list', @git_log_params) or die "Cannot call git-rev-list: $!";
my @commits;
@@ -3029,7 +3029,7 @@ sub update
# several candidate merge bases. let's assume
# that the first one is the best one.
my $base = eval {
- safe_pipe_capture('git-merge-base',
+ safe_pipe_capture('git', 'merge-base',
$lastpicked, $parent);
};
# The two branches may not be related at all,
@@ -3041,7 +3041,7 @@ sub update
if ($base) {
my @merged;
# print "want to log between $base $parent \n";
- open(GITLOG, '-|', 'git-log', '--pretty=medium', "$base..$parent")
+ open(GITLOG, '-|', 'git', 'log', '--pretty=medium', "$base..$parent")
or die "Cannot call git-log: $!";
my $mergedhash;
while (<GITLOG>) {
@@ -3083,7 +3083,7 @@ sub update
if ( defined ( $lastpicked ) )
{
- my $filepipe = open(FILELIST, '-|', 'git-diff-tree', '-z', '-r', $lastpicked, $commit->{hash}) or die("Cannot call git-diff-tree : $!");
+ my $filepipe = open(FILELIST, '-|', 'git', 'diff-tree', '-z', '-r', $lastpicked, $commit->{hash}) or die("Cannot call git-diff-tree : $!");
local ($/) = "\0";
while ( <FILELIST> )
{
@@ -3157,7 +3157,7 @@ sub update
# this is used to detect files removed from the repo
my $seen_files = {};
- my $filepipe = open(FILELIST, '-|', 'git-ls-tree', '-z', '-r', $commit->{hash}) or die("Cannot call git-ls-tree : $!");
+ my $filepipe = open(FILELIST, '-|', 'git', 'ls-tree', '-z', '-r', $commit->{hash}) or die("Cannot call git-ls-tree : $!");
local $/ = "\0";
while ( <FILELIST> )
{
@@ -3448,7 +3448,7 @@ sub commitmessage
return $message;
}
- my @lines = safe_pipe_capture("git-cat-file", "commit", $commithash);
+ my @lines = safe_pipe_capture("git", "cat-file", "commit", $commithash);
shift @lines while ( $lines[0] =~ /\S/ );
$message = join("",@lines);
$message .= " " if ( $message =~ /\n$/ );
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 03/10] cvsserver: remove unused functions _headrev and gethistory
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
In-Reply-To: <1232840601-24696-3-git-send-email-mmogilvi_git@miniinfo.net>
Remove:
- _headrev() - cvsserver already uses similar functionality
from getmeta() and gethead().
- gethistory() - cvsserver already uses similar functions
gethistorydense() and getlog().
- #'annotate' comment - Uncommented annotate line is 2 lines earlier.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
git-cvsserver.perl | 37 ++++---------------------------------
1 files changed, 4 insertions(+), 33 deletions(-)
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index f7891b8..fe23b49 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -78,7 +78,6 @@ my $methods = {
'editors' => \&req_EMPTY,
'annotate' => \&req_annotate,
'Global_option' => \&req_Globaloption,
- #'annotate' => \&req_CATCHALL,
};
##############################################
@@ -3310,19 +3309,6 @@ sub insert_head
$insert_head->execute($name, $revision, $filehash, $commithash, $modified, $author, $mode);
}
-sub _headrev
-{
- my $self = shift;
- my $filename = shift;
- my $tablename = $self->tablename("head");
-
- my $db_query = $self->{dbh}->prepare_cached("SELECT filehash, revision, mode FROM $tablename WHERE name=?",{},1);
- $db_query->execute($filename);
- my ( $hash, $revision, $mode ) = $db_query->fetchrow_array;
-
- return ( $hash, $revision, $mode );
-}
-
sub _get_prop
{
my $self = shift;
@@ -3382,6 +3368,8 @@ sub gethead
=head2 getlog
+See also gethistorydense().
+
=cut
sub getlog
@@ -3467,25 +3455,6 @@ sub commitmessage
return $message;
}
-=head2 gethistory
-
-This function takes a filename (with path) argument and returns an arrayofarrays
-containing revision,filehash,commithash ordered by revision descending
-
-=cut
-sub gethistory
-{
- my $self = shift;
- my $filename = shift;
- my $tablename = $self->tablename("revision");
-
- my $db_query;
- $db_query = $self->{dbh}->prepare_cached("SELECT revision, filehash, commithash FROM $tablename WHERE name=? ORDER BY revision DESC",{},1);
- $db_query->execute($filename);
-
- return $db_query->fetchall_arrayref;
-}
-
=head2 gethistorydense
This function takes a filename (with path) argument and returns an arrayofarrays
@@ -3495,6 +3464,8 @@ This version of gethistory skips deleted entries -- so it is useful for annotate
The 'dense' part is a reference to a '--dense' option available for git-rev-list
and other git tools that depend on it.
+See also getlog().
+
=cut
sub gethistorydense
{
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 04/10] git-shell: allow running git-cvsserver, not just cvs
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie, Johannes.Schindelin
In-Reply-To: <1232840601-24696-4-git-send-email-mmogilvi_git@miniinfo.net>
Add the ability to ask a git-shell restricted account to explicitly run
git-cvsserver, instead of requesting a fake "cvs". With this, an account
could be reconfigured to use/not use git-shell without requiring
changes to client side configuration. It also avoids confusing
users about which way cvs should be configured; if cvs is accessing
a git repository, always set CVS_SERVER=git-cvsserver.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
--------------
Question 1:
There is a surprising shortage of solid information about the
best way(s) restrict what commands can be run by ssh accounts,
both in general and for git specifically. Is
putting git-shell in /etc/passwd the best way? Are there other ways,
just as good or better?
Perhaps someone who really knows could add something to the git-shell.txt
man page describing the possible way(s) to configure an account to
be restricted to git-shell.
--------------
Question 2:
As near as I can tell, git-shell as run by sshd is typically
invoked such that it ends up with an argv with 3 arguments of the
form ("git-shell","-c","command arguments").
But the (argc==2 "cvs server") special case near line 69 of shell.c
appears to allow the middle argument ("-c") to be missing, but
only for "cvs server".
My question is, why was this special case put there? Is a remnant of
an imperfect ad-hoc test framework someone used, or is there a
legitimate configuration where the "-c" is missing?
It seems to me that either this missing "-c" case should be
eliminated, or it should be made more general: If some
configuration of sshd leaves out the "-c", then it probably
leaves it out for anything you try to invoke, not just
"cvs server".
--------------
Hints about testing:
In addition to the test cases that are included in the patch, I tested
this by setting up an extra user account with the following
shell script set as the shell in /etc/passwd (yes, a shell script
is my shell...). This allows me to tweak enviornment variables,
log how it is invoked, maybe tee off the stdin/stdout, etc:
---CUT---
#!/bin/sh
log()
{ echo "$1" >> remote.log
}
log "------------"
log ""
log "cmd:$0"
for arg in "$@" ; do
log "arg:$arg"
done
PATH="/path/to/version/to/test:$PATH"
log "path: $PATH"
#tee input.out | git-shell "$@" | tee output.out
exec git-shell "$@"
---CUT---
But note that you probably do NOT want to route through a
wrapper like this for production...
--
Matthew Ogilvie [mmogilvi_git@miniinfo.net]
Documentation/git-cvsserver.txt | 7 ++-
Documentation/git-shell.txt | 5 +-
shell.c | 1 +
t/t9400-git-cvsserver-server.sh | 88 +++++++++++++++++++++++++++++++++++++++
4 files changed, 97 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt
index 785779e..e32ad7b 100644
--- a/Documentation/git-cvsserver.txt
+++ b/Documentation/git-cvsserver.txt
@@ -113,9 +113,12 @@ cvs -d ":ext;CVS_SERVER=git cvsserver:user@server/path/repo.git" co <HEAD_name>
------
This has the advantage that it will be saved in your 'CVS/Root' files and
you don't need to worry about always setting the correct environment
-variable. SSH users restricted to 'git-shell' don't need to override the default
-with CVS_SERVER (and shouldn't) as 'git-shell' understands `cvs` to mean
+variable. SSH users restricted to 'git-shell' do not need to
+override CVS_SERVER as 'git-cvsserver' because
+'git-shell' understands `cvs` to mean
'git-cvsserver' and pretends that the other end runs the real 'cvs' better.
+But restricted users can still override it for consistency and to avoid
+reconfiguration if they are later promoted to full SSH access.
--
2. For each repo that you want accessible from CVS you need to edit config in
the repo and add the following section.
diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt
index 3f8d973..68cb834 100644
--- a/Documentation/git-shell.txt
+++ b/Documentation/git-shell.txt
@@ -18,8 +18,9 @@ of server-side GIT commands implementing the pull/push functionality.
The commands can be executed only by the '-c' option; the shell is not
interactive.
-Currently, only three commands are permitted to be called, 'git-receive-pack'
-'git-upload-pack' with a single required argument or 'cvs server' (to invoke
+Currently, only four commands are permitted to be called, 'git-receive-pack'
+'git-upload-pack' with a single required argument,
+'git-cvsserver server', or 'cvs server' (to invoke
'git-cvsserver').
Author
diff --git a/shell.c b/shell.c
index e339369..6ed960f 100644
--- a/shell.c
+++ b/shell.c
@@ -40,6 +40,7 @@ static struct commands {
} cmd_list[] = {
{ "git-receive-pack", do_generic_cmd },
{ "git-upload-pack", do_generic_cmd },
+ { "git-cvsserver", do_cvs_cmd },
{ "cvs", do_cvs_cmd },
{ NULL },
};
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 6a37f71..b23a774 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -501,4 +501,92 @@ test_expect_success 'cvs annotate' '
test_cmp ../expect ../actual
'
+#------------
+# access server through git-shell:
+#------------
+
+cd "$WORKDIR"
+test_expect_success 'setup fake_ssh' '
+ cd cvswork &&
+ ( echo "#!/bin/sh" &&
+ echo "echo \"cmd:\$*\" >> fake_ssh_sh.log" &&
+ echo "if test x\"\$1 \$2 \$3\" = x\"-l user machine\" ; then" &&
+ echo " shift ; shift ; shift" &&
+ echo " exec /bin/sh -c \"\$*\"" &&
+ echo "fi" &&
+ echo "echo FAIL" &&
+ echo "exit 1"
+ ) > fake_ssh_sh &&
+ ( echo "#!/bin/sh" &&
+ echo "echo \"cmd:\$*\" >> fake_ssh_git-shell.log" &&
+ echo "if test x\"\$1 \$2 \$3\" = x\"-l user machine\" ; then" &&
+ echo " shift ; shift ; shift" &&
+ echo " exec git-shell -c \"\$*\""
+ echo "fi" &&
+ echo "echo FAIL" &&
+ echo "exit 1"
+ ) > fake_ssh_git-shell &&
+ chmod +x fake_ssh_sh fake_ssh_git-shell
+'
+
+cd "$WORKDIR"
+test_expect_success 'fake_ssh ... sh git-cvsserver' '
+ ( cd cvswork &&
+ CVS_SERVER="git-cvsserver" &&
+ CVS_RSH="./fake_ssh_sh" &&
+ CVSROOT=":ext:user@machine$SERVERDIR" &&
+ export CVS_SERVER CVS_RSH CVSROOT &&
+ GIT_CONFIG="$git_config" cvs -d "$CVSROOT" up -p status.file > ../out &&
+ cmp status.file ../out
+ )
+'
+
+cd "$WORKDIR"
+test_expect_success 'fake_ssh ... sh git cvsserver' '
+ ( cd cvswork &&
+ CVS_SERVER="git cvsserver" &&
+ CVS_RSH="./fake_ssh_sh" &&
+ CVSROOT=":ext:user@machine$SERVERDIR" &&
+ export CVS_SERVER CVS_RSH CVSROOT &&
+ GIT_CONFIG="$git_config" cvs -d "$CVSROOT" up -p status.file > ../out &&
+ cmp status.file ../out
+ )
+'
+
+cd "$WORKDIR"
+test_expect_success 'fake_ssh ... git-shell git-cvsserver' '
+ ( cd cvswork &&
+ CVS_SERVER="git-cvsserver" &&
+ CVS_RSH="./fake_ssh_git-shell" &&
+ CVSROOT=":ext:user@machine$SERVERDIR" &&
+ export CVS_SERVER CVS_RSH CVSROOT &&
+ GIT_CONFIG="$git_config" cvs -d "$CVSROOT" up -p status.file > ../out &&
+ cmp status.file ../out
+ )
+'
+
+cd "$WORKDIR"
+test_expect_success 'fake_ssh ... git-shell git cvsserver' '
+ ( cd cvswork &&
+ CVS_SERVER="git cvsserver" &&
+ CVS_RSH="./fake_ssh_git-shell" &&
+ CVSROOT=":ext:user@machine$SERVERDIR" &&
+ export CVS_SERVER CVS_RSH CVSROOT &&
+ GIT_CONFIG="$git_config" cvs -d "$CVSROOT" up -p status.file > ../out &&
+ cmp status.file ../out
+ )
+'
+
+cd "$WORKDIR"
+test_expect_success 'fake_ssh ... git-shell cvs' '
+ ( cd cvswork &&
+ CVS_SERVER="cvs" &&
+ CVS_RSH="./fake_ssh_git-shell" &&
+ CVSROOT=":ext:user@machine$SERVERDIR" &&
+ export CVS_SERVER CVS_RSH CVSROOT &&
+ GIT_CONFIG="$git_config" cvs -d "$CVSROOT" up -p status.file > ../out &&
+ cmp status.file ../out
+ )
+'
+
test_done
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 10/10] cvsserver doc: emphasize using CVS_SERVER= phrase within CVSROOT
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
In-Reply-To: <1232840601-24696-10-git-send-email-mmogilvi_git@miniinfo.net>
Add information about CVSROOT=":ext;CVS_SERVER=git-cvsserver:..." to
"SYNOPSIS" section. This information was/is already spelled out deep in
the "INSTALLATION" section, but this new method is far superior to
the old backwards-compatible option (separate environment variable),
so try to emphasize it's use for versions of CVS that support it.
Also mention how to connect to a local git repository using
git-cvsserver.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
Documentation/git-cvsserver.txt | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt
index 6f8cd88..d1dc5be 100644
--- a/Documentation/git-cvsserver.txt
+++ b/Documentation/git-cvsserver.txt
@@ -14,6 +14,18 @@ SSH:
export CVS_SERVER=git-cvsserver
'cvs' -d :ext:user@server/path/repo.git co <HEAD_name>
+SSH with newer CVS versions (>= 1.12.11):
+
+[verse]
+export CVSROOT=":ext;CVS_SERVER=git-cvsserver:user@server/path/repo.git"
+'cvs' -d "$CVSROOT" co <HEAD_name>
+
+Local repository:
+
+[verse]
+export CVSROOT=":fork;CVS_SERVER=git-cvsserver:/path/repo.git"
+'cvs' -d "$CVSROOT" co <HEAD_name>
+
pserver (/etc/inetd.conf):
[verse]
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 09/10] Revert "adapt git-cvsserver manpage to dash-free syntax"
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
In-Reply-To: <1232840601-24696-9-git-send-email-mmogilvi_git@miniinfo.net>
This reverts commit da9973c6f9600d90e64aac647f3ed22dfd692f70,
and a couple of other remaining references to "git cvsserver".
When da9973c6f9600 was committed, we did not install git-cvsserver
in $(bindir) by default, but that situation did not last long (see
1df2a1ce806 "Install git-cvsserver in $(bindir)"). Also, a recent
commit (cvsserver: use dashless "git command"s to access plumbing)
fixed an issue with git-cvsserver trying to run dashed forms
without setting up the PATH for it.
The dashed form is arguably better in this case, since it is
required for cvs's ":fork:" connection method (although ":ext:"
usually doesn't need dashes), and it can minimize the need to escape
characters when setting up CVS_SERVER and/or CVSROOT.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
Note: It might conceivably be worth holding off on this patch for a
release, in case someone tries to use a newer man page from the web with
an older install of git, where git-cvsserver still has the PATH bug
mentioned in the commit message above. But I doubt this is really
common enough to worry about.
--
Matthew Ogilvie [mmogilvi_git@miniinfo.net]
Documentation/git-cvsserver.txt | 10 +++++-----
git-cvsserver.perl | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt
index e32ad7b..6f8cd88 100644
--- a/Documentation/git-cvsserver.txt
+++ b/Documentation/git-cvsserver.txt
@@ -11,7 +11,7 @@ SYNOPSIS
SSH:
[verse]
-export CVS_SERVER="git cvsserver"
+export CVS_SERVER=git-cvsserver
'cvs' -d :ext:user@server/path/repo.git co <HEAD_name>
pserver (/etc/inetd.conf):
@@ -22,7 +22,7 @@ cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver
Usage:
[verse]
-'git cvsserver' [options] [pserver|server] [<directory> ...]
+'git-cvsserver' [options] [pserver|server] [<directory> ...]
OPTIONS
-------
@@ -109,7 +109,7 @@ Note: Newer CVS versions (>= 1.12.11) also support specifying
CVS_SERVER directly in CVSROOT like
------
-cvs -d ":ext;CVS_SERVER=git cvsserver:user@server/path/repo.git" co <HEAD_name>
+cvs -d ":ext;CVS_SERVER=git-cvsserver:user@server/path/repo.git" co <HEAD_name>
------
This has the advantage that it will be saved in your 'CVS/Root' files and
you don't need to worry about always setting the correct environment
@@ -161,7 +161,7 @@ allowing access over SSH.
--
------
export CVSROOT=:ext:user@server:/var/git/project.git
- export CVS_SERVER="git cvsserver"
+ export CVS_SERVER=git-cvsserver
------
--
4. For SSH clients that will make commits, make sure their server-side
@@ -286,7 +286,7 @@ To get a checkout with the Eclipse CVS client:
Protocol notes: If you are using anonymous access via pserver, just select that.
Those using SSH access should choose the 'ext' protocol, and configure 'ext'
access on the Preferences->Team->CVS->ExtConnection pane. Set CVS_SERVER to
-"'git cvsserver'". Note that password support is not good when using 'ext',
+'git-cvsserver'. Note that password support is not good when using 'ext',
you will definitely want to have SSH keys setup.
Alternatively, you can just use the non-standard extssh protocol that Eclipse
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index 8e9e659..4b817ce 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -100,7 +100,7 @@ my $work =
$log->info("--------------- STARTING -----------------");
my $usage =
- "Usage: git cvsserver [options] [pserver|server] [<directory> ...]\n".
+ "Usage: git-cvsserver [options] [pserver|server] [<directory> ...]\n".
" --base-path <path> : Prepend to requested CVSROOT\n".
" --strict-paths : Don't allow recursing into subdirectories\n".
" --export-all : Don't check for gitcvs.enabled in config\n".
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 07/10] t3409: use dashless "git commit" instead of "git-commit"
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie
In-Reply-To: <1232840601-24696-7-git-send-email-mmogilvi_git@miniinfo.net>
This is needed to allow test suite to run against a minimal bin
directory instead of GIT_EXEC_PATH.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
Semi-related:
I noticed that there are actually two test cases numbered
t3409: t3409-rebase-hook.sh and t3409-rebase-preserve-merges.sh.
Should one of them be renumbered, or is it good enough as-is? I'm
just pointing this out; I don't intend to change it myself.
--
Matthew Ogilvie [mmogilvi_git@miniinfo.net]
t/t3409-rebase-preserve-merges.sh | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh
index e6c8327..8878771 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -32,14 +32,14 @@ export GIT_AUTHOR_EMAIL
test_expect_success 'setup for merge-preserving rebase' \
'echo First > A &&
git add A &&
- git-commit -m "Add A1" &&
+ git commit -m "Add A1" &&
git checkout -b topic &&
echo Second > B &&
git add B &&
- git-commit -m "Add B1" &&
+ git commit -m "Add B1" &&
git checkout -f master &&
echo Third >> A &&
- git-commit -a -m "Modify A2" &&
+ git commit -a -m "Modify A2" &&
git clone ./. clone1 &&
cd clone1 &&
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* [PATCH 08/10] run test suite without dashed git-commands in PATH
From: Matthew Ogilvie @ 2009-01-24 23:43 UTC (permalink / raw)
To: git; +Cc: Matthew Ogilvie, Johannes.Schindelin
In-Reply-To: <1232840601-24696-8-git-send-email-mmogilvi_git@miniinfo.net>
Exclude GIT_EXEC_PATH from PATH, to emulate the default user environment,
and ensure all the programs (especially scripts) run correctly in
such an environment.
This works by creating a test-bin directory with wrapper scripts for
the programs normally installed in "bin", and only including that
directory in the PATH.
Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net>
---
Valgrind conflict: As I was preparing this email, I noticed that a patch
for running the test suite under valgrind has been under discussion
in the mailing list. The valgrind patch probably conflicts with this
one. I've thought of some possible ways to resolve it:
1. Extend this patch to support valgrind by adding
environment-variable controlled hook to test-bin-wrapper.sh,
and enhance the makefile rules to disable the valgrind hook
for instances of the script that are wrapping other scripts.
(This allows dashless, valgrind, or both.)
2. Or change the valgrind patch to only add executables typically
found in bindir (not GIT_EXEC_PATH) to the symlink directory. To
support dashless by itself, it would need to do a similar symlink
when asked for dashless without valgrind.
3. Or keep the core of both patches, and just fix up the setup
in test-lib.sh to only enable one or the other (never both).
Thoughts?
--
Matthew Ogilvie [mmogilvi_git@miniinfo.net]
.gitignore | 1 +
Makefile | 42 +++++++++++++++++++++++++++++++-----------
t/test-lib.sh | 14 +++++++++++++-
test-bin-wrapper.sh | 12 ++++++++++++
4 files changed, 57 insertions(+), 12 deletions(-)
create mode 100644 test-bin-wrapper.sh
diff --git a/.gitignore b/.gitignore
index d9adce5..13a0d33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -143,6 +143,7 @@ git-write-tree
git-core-*/?*
gitk-wish
gitweb/gitweb.cgi
+test-bin
test-chmtime
test-date
test-delta
diff --git a/Makefile b/Makefile
index b4d9cb4..197a6f0 100644
--- a/Makefile
+++ b/Makefile
@@ -330,6 +330,15 @@ ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
# what 'all' will build but not install in gitexecdir
OTHER_PROGRAMS = git$X gitweb/gitweb.cgi
+# what test wrappers are needed and 'install' will install, in bindir
+BINDIR_PROGRAMS_NEED_X += git
+BINDIR_PROGRAMS_NEED_X += git-upload-pack
+BINDIR_PROGRAMS_NEED_X += git-receive-pack
+BINDIR_PROGRAMS_NEED_X += git-upload-archive
+BINDIR_PROGRAMS_NEED_X += git-shell
+
+BINDIR_PROGRAMS_NO_X += git-cvsserver
+
# Set paths to tools early so that they can be used for version tests.
ifndef SHELL_PATH
SHELL_PATH = /bin/sh
@@ -1356,17 +1365,25 @@ endif
### Testing rules
-TEST_PROGRAMS += test-chmtime$X
-TEST_PROGRAMS += test-ctype$X
-TEST_PROGRAMS += test-date$X
-TEST_PROGRAMS += test-delta$X
-TEST_PROGRAMS += test-genrandom$X
-TEST_PROGRAMS += test-match-trees$X
-TEST_PROGRAMS += test-parse-options$X
-TEST_PROGRAMS += test-path-utils$X
-TEST_PROGRAMS += test-sha1$X
+TEST_PROGRAMS_NEED_X += test-chmtime
+TEST_PROGRAMS_NEED_X += test-ctype
+TEST_PROGRAMS_NEED_X += test-date
+TEST_PROGRAMS_NEED_X += test-delta
+TEST_PROGRAMS_NEED_X += test-genrandom
+TEST_PROGRAMS_NEED_X += test-match-trees
+TEST_PROGRAMS_NEED_X += test-parse-options
+TEST_PROGRAMS_NEED_X += test-path-utils
+TEST_PROGRAMS_NEED_X += test-sha1
+
+TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
-all:: $(TEST_PROGRAMS)
+test_bindir_programs := $(patsubst %,test-bin/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))
+
+all:: $(TEST_PROGRAMS) $(test_bindir_programs)
+
+test-bin/%: test-bin-wrapper.sh
+ @mkdir -p test-bin
+ $(QUIET_GEN)sed -e 's|__GIT_EXEC_PATH__|$(shell pwd)|' -e 's|__PROG__|$(@F)|' < $< > $@ && chmod +x $@
# GNU make supports exporting all variables by "export" without parameters.
# However, the environment gets quite big, and some programs have problems
@@ -1425,11 +1442,13 @@ endif
gitexec_instdir_SQ = $(subst ','\'',$(gitexec_instdir))
export gitexec_instdir
+install_bindir_programs := $(patsubst %,%$X,$(BINDIR_PROGRAMS_NEED_X)) $(BINDIR_PROGRAMS_NO_X)
+
install: all
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
- $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X git-shell$X git-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)'
+ $(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
$(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
ifndef NO_TCLTK
@@ -1533,6 +1552,7 @@ clean:
$(LIB_FILE) $(XDIFF_LIB)
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
$(RM) $(TEST_PROGRAMS)
+ $(RM) -r test-bin
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
$(RM) -r autom4te.cache
$(RM) config.log config.mak.autogen config.mak.append config.status config.cache
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 41d5a59..2f42b5b 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -89,6 +89,8 @@ do
verbose=t; shift ;;
-q|--q|--qu|--qui|--quie|--quiet)
quiet=t; shift ;;
+ --with-dashes)
+ with_dashes=t; shift ;;
--no-color)
color=; shift ;;
--no-python)
@@ -467,8 +469,18 @@ test_done () {
# Test the binaries we have just built. The tests are kept in
# t/ subdirectory and are run in 'trash directory' subdirectory.
TEST_DIRECTORY=$(pwd)
-PATH=$TEST_DIRECTORY/..:$PATH
GIT_EXEC_PATH=$(pwd)/..
+git_bin_dir="$TEST_DIRECTORY/../test-bin"
+if ! test -x "$git_bin_dir/git" ; then
+ if test -z "$with_dashes" ; then
+ say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
+ fi
+ with_dashes=t
+fi
+PATH="$git_bin_dir:$PATH"
+if test -n "$with_dashes" ; then
+ PATH="$TEST_DIRECTORY/..:$PATH"
+fi
GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
unset GIT_CONFIG
GIT_CONFIG_NOSYSTEM=1
diff --git a/test-bin-wrapper.sh b/test-bin-wrapper.sh
new file mode 100644
index 0000000..199d098
--- /dev/null
+++ b/test-bin-wrapper.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# test-bin-wrapper.sh: Template for git executable wrapper scripts
+# to run test suite against sandbox, but with only bindir-installed
+# executables in PATH. The Makefile copies this into various
+# files in test-bin, substituting __GIT_EXEC_PATH__ and __PROG__.
+
+GIT_EXEC_PATH="__GIT_EXEC_PATH__"
+GIT_TEMPLATE_DIR="__GIT_EXEC_PATH__/templates/blt"
+export GIT_EXEC_PATH GIT_TEMPLATE_DIR
+
+exec "${GIT_EXEC_PATH}/__PROG__" "$@"
--
1.6.1.81.g9833d.dirty
^ permalink raw reply related
* Re: [PATCH] mergetool merge/skip/abort
From: Caleb Cushing @ 2009-01-25 0:18 UTC (permalink / raw)
To: Nanako Shiraishi; +Cc: Junio C Hamano, Charles Bailey, git
In-Reply-To: <20090125064539.6117@nanako3.lavabit.com>
> 1. You copy-and-pasted output from format-patch, and have the header
> part in the message body. Charles and Johannes have moved them to the
> Email header.
>
> Their messages are in the form the tool used for patch acceptance
> expects. Yours isn't, and forces Junio to manually edit your message
> before handling it.
I'll get to the rest later...
but I tried sending the patch via email as you said followed this...
verbatim except replacing user@ and p4ssw0rd with my credentials, and
I got an auth error back. currently I've no idea how I would send
stuff from gmail. and I reject inline patches in funtoo because I use
webmail and they are impossible for me to handle easily.
Submitting properly formatted patches via Gmail is simple now that
IMAP support is available. First, edit your ~/.gitconfig to specify your
account settings:
[imap]
folder = "[Gmail]/Drafts"
host = imaps://imap.gmail.com
user = user@gmail.com
pass = p4ssw0rd
port = 993
sslverify = false
Next, ensure that your Gmail settings are correct. In "Settings" the
"Use Unicode (UTF-8) encoding for outgoing messages" should be checked.
Once your commits are ready to send to the mailing list, run the following
command to send the patch emails to your Gmail Drafts folder.
$ git format-patch -M --stdout origin/master | git imap-send
--
Caleb Cushing
http://xenoterracide.blogspot.com
^ permalink raw reply
* Re: [PATCH] Allow cloning an empty repository
From: Miklos Vajna @ 2009-01-25 0:49 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <bd6139dc0901231642v6bd593d3mfefaca3c419a9f0a@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 144 bytes --]
On Sat, Jan 24, 2009 at 01:42:30AM +0100, Sverre Rabbelier <srabbelier@gmail.com> wrote:
> Which means all protocols actually die?
I think so.
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* [PATCH 0/2] Add submodule-support to git archive
From: Lars Hjemli @ 2009-01-25 0:52 UTC (permalink / raw)
To: Junio C Hamano, Johannes Schindelin; +Cc: git
This is a cleaned up version of my previous patches which allows git archive
to include submodule content in the archive output.
The main difference between this series and the previous ones is that the
behaviour of `git archive --submodules` are now predictable; the content
included from submodules is defined by the gitlink entries found when
traversing the <tree-ish> specified on the command line, and the set of
submodules to include are defined by specifying either `--submodules=all` or
`--submodules=checkedout` (which is the default mode of operation, i.e. what
you get by only specifying `--submodules`).
To make the `--submodules` option more userfriendly, any submodule repository
discovered during traversal will be registered as an alternate odb (this
will typically be required to make the inter-repository traversal succeed).
Finally, the option `--submodules=group:<name>` is not yet implemented. I
wanted to get these first two patches published early since they define the
semantics of the --submodules option. Adding a 'group' selector on top is
mostly a question of pulling information out of .gitmodules and .git/config,
i.e. not very exciting (but it will be done ;-)
Lars Hjemli (2):
tree.c: allow read_tree_recursive() to traverse gitlink entries
archive.c: add support for --submodules[=(all|checkedout)]
Documentation/git-archive.txt | 5 ++
archive.c | 81 +++++++++++++++++++++++++-
archive.h | 4 +
builtin-ls-tree.c | 9 +--
cache.h | 1 +
merge-recursive.c | 2 +-
sha1_file.c | 11 +++-
t/t5001-archive-submodules.sh | 129 +++++++++++++++++++++++++++++++++++++++++
tree.c | 28 +++++++++
9 files changed, 259 insertions(+), 11 deletions(-)
create mode 100755 t/t5001-archive-submodules.sh
^ permalink raw reply
* [PATCH 1/2] tree.c: allow read_tree_recursive() to traverse gitlink entries
From: Lars Hjemli @ 2009-01-25 0:52 UTC (permalink / raw)
To: Junio C Hamano, Johannes Schindelin; +Cc: git
In-Reply-To: <1232844726-14902-1-git-send-email-hjemli@gmail.com>
When the callback function invoked from read_tree_recursive() returns
the value `READ_TREE_RECURSIVE` for a gitlink entry, the traversal will
now continue into the tree connected to the gitlinked commit. This
functionality can be used to allow inter-repository operations, but
since the current users of read_tree_recursive() does not yet support
such operations, they have been modified where necessary to make sure
that they never return READ_TREE_RECURSIVE for gitlink entries (hence
no change in behaviour should be introduces by this patch alone).
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
archive.c | 2 +-
builtin-ls-tree.c | 9 ++-------
merge-recursive.c | 2 +-
tree.c | 28 ++++++++++++++++++++++++++++
4 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/archive.c b/archive.c
index 9ac455d..e6de039 100644
--- a/archive.c
+++ b/archive.c
@@ -132,7 +132,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
err = write_entry(args, sha1, path.buf, path.len, mode, NULL, 0);
if (err)
return err;
- return READ_TREE_RECURSIVE;
+ return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
}
buffer = sha1_file_to_archive(path_without_prefix, sha1, mode,
diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c
index 5b63e6e..fca4631 100644
--- a/builtin-ls-tree.c
+++ b/builtin-ls-tree.c
@@ -68,13 +68,8 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
*
* Something similar to this incomplete example:
*
- if (show_subprojects(base, baselen, pathname)) {
- struct child_process ls_tree;
-
- ls_tree.dir = base;
- ls_tree.argv = ls-tree;
- start_command(&ls_tree);
- }
+ if (show_subprojects(base, baselen, pathname))
+ retval = READ_TREE_RECURSIVE;
*
*/
type = commit_type;
diff --git a/merge-recursive.c b/merge-recursive.c
index b97026b..ee853b9 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -237,7 +237,7 @@ static int save_files_dirs(const unsigned char *sha1,
string_list_insert(newpath, &o->current_file_set);
free(newpath);
- return READ_TREE_RECURSIVE;
+ return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
}
static int get_files_dirs(struct merge_options *o, struct tree *tree)
diff --git a/tree.c b/tree.c
index 03e782a..dfe4d5f 100644
--- a/tree.c
+++ b/tree.c
@@ -131,6 +131,34 @@ int read_tree_recursive(struct tree *tree,
if (retval)
return -1;
continue;
+ } else if (S_ISGITLINK(entry.mode)) {
+ int retval;
+ struct strbuf path;
+ unsigned int entrylen;
+ struct commit *commit;
+
+ entrylen = tree_entry_len(entry.path, entry.sha1);
+ strbuf_init(&path, baselen + entrylen + 1);
+ strbuf_add(&path, base, baselen);
+ strbuf_add(&path, entry.path, entrylen);
+ strbuf_addch(&path, '/');
+
+ commit = lookup_commit(entry.sha1);
+ if (!commit)
+ die("Commit %s in submodule path %s not found",
+ sha1_to_hex(entry.sha1), path.buf);
+
+ if (parse_commit(commit))
+ die("Invalid commit %s in submodule path %s",
+ sha1_to_hex(entry.sha1), path.buf);
+
+ retval = read_tree_recursive(commit->tree,
+ path.buf, path.len,
+ stage, match, fn, context);
+ strbuf_release(&path);
+ if (retval)
+ return -1;
+ continue;
}
}
return 0;
--
1.6.1.150.g5e733b
^ permalink raw reply related
* [PATCH 2/2] archive.c: add support for --submodules[=(all|checkedout)]
From: Lars Hjemli @ 2009-01-25 0:52 UTC (permalink / raw)
To: Junio C Hamano, Johannes Schindelin; +Cc: git
In-Reply-To: <1232844726-14902-2-git-send-email-hjemli@gmail.com>
The --submodules option uses the enhanced read_tree_recursive() to
enable inclusion of submodules in the generated archive.
When invoked with `--submodules=all` all gitlink entries will be
traversed, and when invoked with --submodules=checkedout (the default
option) only gitlink entries with a git repo (i.e. checked out sub-
modules) will be traversed.
When a gitlink has been selected for traversal, it is required that all
objects necessary to perform this traversal are available in either the
primary odb or through an alternate odb. To this end, git archive will
insert the object database of the selected gitlink (when checked out)
as an alternate odb, using the new function add_alt_odb(). And since
alternates now can be added after parsing of objects/info/alternates,
the error message in link_alt_odb_entry() has been updated to not
mention this file.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
Documentation/git-archive.txt | 5 ++
archive.c | 81 +++++++++++++++++++++++++-
archive.h | 4 +
cache.h | 1 +
sha1_file.c | 11 +++-
t/t5001-archive-submodules.sh | 129 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 228 insertions(+), 3 deletions(-)
create mode 100755 t/t5001-archive-submodules.sh
diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index 41cbf9c..6068302 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -47,6 +47,11 @@ OPTIONS
--prefix=<prefix>/::
Prepend <prefix>/ to each filename in the archive.
+--submodules[=<spec>]::
+ Include the content of submodules in the archive. The specification
+ of which submodules to include can be either 'checkedout' (default)
+ or 'all'.
+
<extra>::
This can be any options that the archiver backend understand.
See next section.
diff --git a/archive.c b/archive.c
index e6de039..bb0c5c8 100644
--- a/archive.c
+++ b/archive.c
@@ -4,6 +4,7 @@
#include "attr.h"
#include "archive.h"
#include "parse-options.h"
+#include "refs.h"
static char const * const archive_usage[] = {
"git archive [options] <tree-ish> [path...]",
@@ -91,6 +92,70 @@ static void setup_archive_check(struct git_attr_check *check)
check[1].attr = attr_export_subst;
}
+static int include_repository(const char *path)
+{
+ struct stat st;
+ const char *tmp;
+
+ /* Return early if the path does not exist since it is OK to not
+ * checkout submodules.
+ */
+ if (stat(path, &st) && errno == ENOENT)
+ return 1;
+
+ tmp = read_gitfile_gently(path);
+ if (tmp) {
+ path = tmp;
+ if (stat(path, &st))
+ die("Unable to stat submodule gitdir %s: %s (%d)",
+ path, strerror(errno), errno);
+ }
+
+ if (!S_ISDIR(st.st_mode))
+ die("Submodule gitdir %s is not a directory", path);
+
+ if (add_alt_odb(mkpath("%s/objects", path)))
+ die("submodule odb %s could not be added as an alternate",
+ path);
+
+ return 0;
+}
+
+static int check_gitlink(struct archiver_args *args, const unsigned char *sha1,
+ const char *path)
+{
+ switch (args->submodules) {
+ case 0:
+ return 0;
+
+ case SUBMODULES_ALL:
+ /* When all submodules are requested, we try to add any
+ * checked out submodules as alternate odbs. But we don't
+ * really care whether any particular submodule is checked
+ * out or not, we are going to try to traverse it anyways.
+ */
+ include_repository(mkpath("%s.git", path));
+ return READ_TREE_RECURSIVE;
+
+ case SUBMODULES_CHECKEDOUT:
+ /* If a repo is checked out at the gitlink path, we want to
+ * traverse into the submodule. But we ignore the current
+ * HEAD of the checked out submodule and always uses the SHA1
+ * recorded in the gitlink entry since we want the content
+ * of the archive to match the content of the <tree-ish>
+ * specified on the command line.
+ */
+ if (!include_repository(mkpath("%s.git", path)))
+ return READ_TREE_RECURSIVE;
+ else
+ return 0;
+
+ default:
+ die("archive.c: invalid value for args->submodules: %d",
+ args->submodules);
+ }
+}
+
struct archiver_context {
struct archiver_args *args;
write_archive_entry_fn_t write_entry;
@@ -132,7 +197,8 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
err = write_entry(args, sha1, path.buf, path.len, mode, NULL, 0);
if (err)
return err;
- return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
+ return (S_ISDIR(mode) ? READ_TREE_RECURSIVE :
+ check_gitlink(args, sha1, path.buf));
}
buffer = sha1_file_to_archive(path_without_prefix, sha1, mode,
@@ -253,6 +319,7 @@ static int parse_archive_args(int argc, const char **argv,
const char *base = NULL;
const char *remote = NULL;
const char *exec = NULL;
+ const char *submodules = NULL;
int compression_level = -1;
int verbose = 0;
int i;
@@ -262,6 +329,9 @@ static int parse_archive_args(int argc, const char **argv,
OPT_STRING(0, "format", &format, "fmt", "archive format"),
OPT_STRING(0, "prefix", &base, "prefix",
"prepend prefix to each pathname in the archive"),
+ {OPTION_STRING, 0, "submodules", &submodules, "kind",
+ "include submodule content in the archive",
+ PARSE_OPT_OPTARG, NULL, (intptr_t)"checkedout"},
OPT__VERBOSE(&verbose),
OPT__COMPR('0', &compression_level, "store only", 0),
OPT__COMPR('1', &compression_level, "compress faster", 1),
@@ -316,6 +386,15 @@ static int parse_archive_args(int argc, const char **argv,
format, compression_level);
}
}
+
+ if (!submodules)
+ args->submodules = 0;
+ else if (!strcmp(submodules, "checkedout"))
+ args->submodules = SUBMODULES_CHECKEDOUT;
+ else if (!strcmp(submodules, "all"))
+ args->submodules = SUBMODULES_ALL;
+ else
+ die("Invalid submodule kind: %s", submodules);
args->verbose = verbose;
args->base = base;
args->baselen = strlen(base);
diff --git a/archive.h b/archive.h
index 0b15b35..2b078b6 100644
--- a/archive.h
+++ b/archive.h
@@ -11,8 +11,12 @@ struct archiver_args {
const char **pathspec;
unsigned int verbose : 1;
int compression_level;
+ int submodules;
};
+#define SUBMODULES_CHECKEDOUT 1
+#define SUBMODULES_ALL 2
+
typedef int (*write_archive_fn_t)(struct archiver_args *);
typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, const unsigned char *sha1, const char *path, size_t pathlen, unsigned int mode, void *buffer, unsigned long size);
diff --git a/cache.h b/cache.h
index 8d965b8..ea53e4b 100644
--- a/cache.h
+++ b/cache.h
@@ -728,6 +728,7 @@ extern struct alternate_object_database {
char base[FLEX_ARRAY]; /* more */
} *alt_odb_list;
extern void prepare_alt_odb(void);
+extern int add_alt_odb(const char *path);
extern void add_to_alternates_file(const char *reference);
typedef int alt_odb_fn(struct alternate_object_database *, void *);
extern void foreach_alt_odb(alt_odb_fn, void*);
diff --git a/sha1_file.c b/sha1_file.c
index 360f7e5..53d8db7 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -285,8 +285,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
/* Detect cases where alternate disappeared */
if (!is_directory(ent->base)) {
- error("object directory %s does not exist; "
- "check .git/objects/info/alternates.",
+ error("Alternate object directory %s does not exist",
ent->base);
free(ent);
return -1;
@@ -2573,3 +2572,11 @@ int read_pack_header(int fd, struct pack_header *header)
return PH_ERROR_PROTOCOL;
return 0;
}
+
+int add_alt_odb(const char *path)
+{
+ int err = link_alt_odb_entry(path, strlen(path), NULL, 0);
+ if (!err)
+ prepare_packed_git_one((char *)path, 0);
+ return err;
+}
diff --git a/t/t5001-archive-submodules.sh b/t/t5001-archive-submodules.sh
new file mode 100755
index 0000000..14383b3
--- /dev/null
+++ b/t/t5001-archive-submodules.sh
@@ -0,0 +1,129 @@
+#!/bin/sh
+
+test_description='git archive can include submodule content'
+
+. ./test-lib.sh
+
+add_file()
+{
+ git add $1 &&
+ git commit -m "added $1"
+}
+
+add_submodule()
+{
+ mkdir $1 && (
+ cd $1 &&
+ git init &&
+ echo "File $2" >$2 &&
+ add_file $2
+ ) &&
+ add_file $1
+}
+
+test_expect_success 'by default, submodules are not included' '
+ echo "File 1" >1 &&
+ add_file 1 &&
+ add_submodule 2 3 &&
+ add_submodule 4 5 &&
+ cat <<EOF >expected &&
+1
+2/
+4/
+EOF
+ git archive HEAD >normal.tar &&
+ tar -tf normal.tar >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'with --submodules, checked out submodules are included' '
+ cat <<EOF >expected &&
+1
+2/
+2/3
+4/
+4/5
+EOF
+ git archive --submodules HEAD >full.tar &&
+ tar -tf full.tar >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'with --submodules=all, all submodules are included' '
+ git archive --submodules=all HEAD >all.tar &&
+ tar -tf all.tar >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'submodules in submodules are supported' '
+ (cd 4 && add_submodule 6 7) &&
+ add_file 4 &&
+ cat <<EOF >expected &&
+1
+2/
+2/3
+4/
+4/5
+4/6/
+4/6/7
+EOF
+ git archive --submodules HEAD >recursive.tar &&
+ tar -tf recursive.tar >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'packed submodules are supported' '
+ msg=$(cd 2 && git repack -ad && git count-objects) &&
+ test "$msg" = "0 objects, 0 kilobytes" &&
+ git archive --submodules HEAD >packed.tar &&
+ tar -tf packed.tar >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'missing submodule packs triggers an error' '
+ mv 2/.git/objects/pack .git/packdir2 &&
+ test_must_fail git archive --submodules HEAD
+'
+
+test_expect_success '--submodules skips non-checked out submodules' '
+ cat <<EOF >expected &&
+1
+2/
+4/
+4/5
+4/6/
+4/6/7
+EOF
+ rm -rf 2/.git &&
+ git archive --submodules HEAD >partial.tar &&
+ tar -tf partial.tar >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success '--submodules=all fails if gitlinked objects are missing' '
+ test_must_fail git archive --submodules=all HEAD
+'
+
+test_expect_success \
+ '--submodules=all does not require submodules to be checked out' '
+ cat <<EOF >expected &&
+1
+2/
+2/3
+4/
+4/5
+4/6/
+4/6/7
+EOF
+ mv .git/packdir2/* .git/objects/pack/ &&
+ git archive --submodules=all HEAD >all2.tar &&
+ tar -tf all2.tar >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'missing objects in a submodule triggers an error' '
+ find 4/.git/objects -type f | xargs rm &&
+ test_must_fail git archive --submodules HEAD
+'
+
+test_done
--
1.6.1.150.g5e733b
^ permalink raw reply related
* Re: [PATCH] Allow cloning an empty repository
From: Sverre Rabbelier @ 2009-01-25 0:55 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Git Mailinglist, Miklos Vajna
In-Reply-To: <20090125004955.GY21473@genesis.frugalware.org>
Heya,
On Sun, Jan 25, 2009 at 01:49, Miklos Vajna <vmiklos@frugalware.org> wrote:
> On Sat, Jan 24, 2009 at 01:42:30AM +0100, Sverre Rabbelier <srabbelier@gmail.com> wrote:
>> Which means all protocols actually die?
>
> I think so.
Junio, are your concerns address now, since Miklos confirmed that
transport_get_remote_refs always dies?
--
Cheers,
Sverre Rabbelier
^ permalink raw reply
* Re: [PATCH 04/10] git-shell: allow running git-cvsserver, not just cvs
From: Johannes Schindelin @ 2009-01-25 1:53 UTC (permalink / raw)
To: Matthew Ogilvie; +Cc: git
In-Reply-To: <1232840601-24696-5-git-send-email-mmogilvi_git@miniinfo.net>
Hi,
On Sat, 24 Jan 2009, Matthew Ogilvie wrote:
> diff --git a/shell.c b/shell.c
> index e339369..6ed960f 100644
> --- a/shell.c
> +++ b/shell.c
> @@ -40,6 +40,7 @@ static struct commands {
> } cmd_list[] = {
> { "git-receive-pack", do_generic_cmd },
> { "git-upload-pack", do_generic_cmd },
> + { "git-cvsserver", do_cvs_cmd },
> { "cvs", do_cvs_cmd },
> { NULL },
> };
I do not see any value in this.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 08/10] run test suite without dashed git-commands in PATH
From: Johannes Schindelin @ 2009-01-25 1:59 UTC (permalink / raw)
To: Matthew Ogilvie; +Cc: git
In-Reply-To: <1232840601-24696-9-git-send-email-mmogilvi_git@miniinfo.net>
Hi,
On Sat, 24 Jan 2009, Matthew Ogilvie wrote:
> .gitignore | 1 +
> Makefile | 42 +++++++++++++++++++++++++++++++-----------
> t/test-lib.sh | 14 +++++++++++++-
> test-bin-wrapper.sh | 12 ++++++++++++
> 4 files changed, 57 insertions(+), 12 deletions(-)
> create mode 100644 test-bin-wrapper.sh
I am strongly opposed to a patch this big, just for something as 3rd class
as CVS server faking. We already have a big fallout from all that bending
over for Windows support, and I do not like it at all.
Note: I do not even have to look further than the diffstat to see that it
is wrong.
The point is: if cvsserver wants to pretend that it is in a fake bin where
almost none of the other Git programs are, fine, let's do that _in the
test for cvsserver_.
Let's not fsck up the whole test suite just for one user.
Ciao,
Dscho
^ permalink raw reply
* Re: Heads up: major rebase -i -p rework coming up
From: Johannes Schindelin @ 2009-01-25 2:05 UTC (permalink / raw)
To: Thomas Rast; +Cc: git, Stephen Haberman, spearce, Björn Steinbrink
In-Reply-To: <200901242347.23187.trast@student.ethz.ch>
Hi,
On Sat, 24 Jan 2009, Thomas Rast wrote:
> Johannes Schindelin wrote:
> > Worse, the whole concept of "pick <merge-sha1>" just does not fly well.
> [...]
> > - merge $sha1 [$sha1...] was $sha1 "Merge ..."
> >
> > will merge the given list of commits into the current HEAD, for
> > the user's reference and to keep up-to-date what was rewritten, the
> > original merge is shown after the keyword "was" (which is not a valid
> > SHA-1, luckily)
>
> I really like the underlying idea. I'm not even sure if the current
> semantics are well-defined in all cases; an explicit merge command at
> least makes it very clear what is going on.
>
> However, I think the syntax as proposed above is a bit confusing in the
> usual two-parent merge. I couldn't tell whether
>
> merge A was B
>
> was intended to be read as "the merge of A into the current branch" or
> "the merge with sha1 A" right away, and I doubt I'll be able to tell
> without looking in the (rare) cases I have to invoke rebase -i -p.
>
> I can't really come up with a better replacement for 'was', so how about
>
> merge A # was B "Merge..."
>
> which would make it more clear that the "was B..." has no effect
> whatsoever on the merge's semantics.
Hmm. You're right, that is not really intuitive. How about
merge (B) A # Merge...
instead?
> > A - B - - - E
> > \ /
> > C - D
> >
> > could yield this TODO script:
> >
> > pick A
> > pick C
> > pick D
> > goto A'
> > pick B
> > merge D' was E
>
> I kind of wonder if it would be possible to decorate the TODO with
> 'git log --graph' output, to make it easier to follow the history as
> it is built.
I wondered about that, too, and abandoned it as my common operation is cut
& past lines around. The result would look _utterly_ confusing.
Maybe I should have mentioned that to spare you the brain cycles thinking
about --graph...
Ciao,
Dscho
^ permalink raw reply
* Re: Heads up: major rebase -i -p rework coming up
From: Johannes Schindelin @ 2009-01-25 2:23 UTC (permalink / raw)
To: Junio C Hamano
Cc: Stephan Beyer, git, Stephen Haberman, spearce, Thomas Rast,
Björn Steinbrink
In-Reply-To: <7vzlhgl35z.fsf@gitster.siamese.dyndns.org>
Hi,
On Sat, 24 Jan 2009, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> >> - What's with the apostrophe? I seem to remember that you argued it
> >> would be enough to make "A" stand for the original when it is used
> >> for the first time and the second and later use can stand for the
> >> result of the last use (e.g. the "goto A'" above can be simply
> >> spelled as "goto A"), when I suggested to use "mark" in a way
> >> similar to how fast-import language uses it during the sequencer
> >> discussion?
> >>
> >> I am not complaining; I am just being curious why the sudden change
> >> of heart.
> >
> > Very easy explanation. I got convinced by your arguments. Even if I
> > could imagine that I never use the thing without apostrophe, it is
> > good to have an obvious indicator that this is not necessarily the
> > original commit.
>
> Now that does not make much sense to me.
>
> The reason I suggested that 'mark' would give a cleaner semantics was
> because in your earlier design "A" could either stand for the original
> or it could stand for the result of an operation that used "A", and
> there could be more than one operation that uses "A". Explicitly naming
> each result with a mark would give us an unambiguous way to distinguish
> them.
But that is not what rebase -i is about! Either you rewrite a commit, or
you don't. You don't rewrite it multiple times _and_ reference all of the
intermediate steps!
Should you suggest that this is a sane worflow, you would really ask for
trouble.
As it is, "mark" is useless. It would give one and the same thing two
names, one short SHA-1, and one numeric value, and the relationship
between the two -- even if they mean the same! -- would be completely
arbitrary.
> I however do not think you would ever use A twice in the context of
> "rebase -i/-p".
Exactly!
> Cherry-picking the same commit twice to create two copies of them will
> not happen in that context.
Not exactly true, as you could split a patch by
edit abcdefg Patch to be split
edit abcdefg Patch to be split
And removing half of the patch in the first edit (e.g. by "git reset
HEAD^ && git add -e" or something similar).
> While trying to recreate something like this on top of a commit "o", you
> would have to talk about "A" multiple times,...
>
> B---M
> / / \
> ---o---A---C \
> \ \ \
> D---N-------O
>
> ... but even in such a picture, after one "pick A", you would always want
> to refer to the result of the pick, and never the original A.
>
> pick A
> goto A'^
... or goto $ONTO...
> pick D
> merge A' was N
> goto A'
> pick B
> goto A'
> pick C
> merge B' was M
> merge N' was O
>
> So I am inclined to think that "first use refers to the original, second
> and thereafter will refer to the result of the first use" would be a good
> enough semantics for "rebase -i/-p", and you do not need "A" vs "A'" for
> this.
>
> By the way, I think this example shows that your "goto" might need a way
> to refer to the "onto" commit in some way (I just used "A'^" there).
It will use $ONTO.
> On the other hand, if you are aiming to allow users to create (by editing
> the insn file) an arbitrarily different structure like this, starting from
> the same topology:
>
> ---o---B---C---A
> \ \
> A---D-------O
>
> that is, rebasing the upper line of development into one linear sequence
> with different patch order, while rebasing the lower line into another
> linear sequence by rebasing D on top of A, you would need to be able to
> refer to the two different results of "using A", and your "A'" notation
> would not help.
>
> pick B
> pick C
> pick A
> goto B'^
> pick A
> pick D
> merge A' was O
>
> The last "merge A' was O" is done while on the result of applying D on top
> of the result of applying A on the lower line, and wants to call the tip
> of the upper line by referring it as "the result of applying A".
>
> But there are two results from applying A, and I do not think you can
> avoid 'mark', even though you for some reason seem to hate it.
You can, by doing the sane thing and first apply one strand of the two
branches, then going back and applying the other strand. You would not
even once need "goto A'".
> If this kind of transformation is outside the scope of your redesign
> (which I think is a sensible design decision), I do not see why you
> would need "A vs A'".
>
> You either need the full power of 'mark', or "A is original until it is
> used, and then the one and only one result once it is used,"; nothing in
> between like "A vs A'" would make much sense.
Your example seems a little bit constructed to the purpose of showing the
shortcomings of the A' notation.
But it has a shortcoming in and of its own: if you want to apply A for
both branches, it would make a metric ton more sense to apply A before
branching:
---o---A---B---C
\ \
D-------O
Besides, if you would concoct a real obscure situation where you really
needed to apply one and the same patch twice, _and_ refer to both "A'"
(something like
---o---B---A---C----H
\ \ / /
\ E /
\ /
D---A---F
\ /
G
Then you could still do the part B...C first (with the first version of
A'), then D...F (with the second version of A') and be done with it.
Unless you would want anything like
C---A---B
/
---A
which is ugly beyond belief IMO, but in which case you could _still_ do it
with an "edit C; merge A' was B" where you just git cherry-pick A.
So it is possible, even if it needs trickery, which is okay IMHO as this
is not the common case. And I want to optimize for the common case.
Ciao,
Dscho
^ permalink raw reply
* Re: Heads up: major rebase -i -p rework coming up
From: Johannes Schindelin @ 2009-01-25 2:25 UTC (permalink / raw)
To: Thomas Rast; +Cc: git, Stephen Haberman, spearce, Björn Steinbrink
In-Reply-To: <alpine.DEB.1.00.0901250303150.14855@racer>
Hi,
On Sun, 25 Jan 2009, Johannes Schindelin wrote:
> On Sat, 24 Jan 2009, Thomas Rast wrote:
>
> > Johannes Schindelin wrote:
> > > Worse, the whole concept of "pick <merge-sha1>" just does not fly well.
> > [...]
> > > - merge $sha1 [$sha1...] was $sha1 "Merge ..."
> > >
> > > will merge the given list of commits into the current HEAD, for
> > > the user's reference and to keep up-to-date what was rewritten, the
> > > original merge is shown after the keyword "was" (which is not a
> > > valid SHA-1, luckily)
> >
> > I really like the underlying idea. I'm not even sure if the current
> > semantics are well-defined in all cases; an explicit merge command at
> > least makes it very clear what is going on.
> >
> > However, I think the syntax as proposed above is a bit confusing in
> > the usual two-parent merge. I couldn't tell whether
> >
> > merge A was B
> >
> > was intended to be read as "the merge of A into the current branch" or
> > "the merge with sha1 A" right away, and I doubt I'll be able to tell
> > without looking in the (rare) cases I have to invoke rebase -i -p.
> >
> > I can't really come up with a better replacement for 'was', so how
> > about
> >
> > merge A # was B "Merge..."
> >
> > which would make it more clear that the "was B..." has no effect
> > whatsoever on the merge's semantics.
>
> Hmm. You're right, that is not really intuitive. How about
>
> merge (B) A # Merge...
>
> instead?
Or even better:
merge B parent A' # Merge...
?
Ciao,
Dscho
^ 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