* Re: [PATCH resend] Do not create commits whose message contains NUL
From: Drew Northup @ 2012-01-01 16:27 UTC (permalink / raw)
To: Jeff King; +Cc: Nguyễn Thái Ngọc Duy, git
In-Reply-To: <20111213175932.GA1663@sigill.intra.peff.net>
On Tue, 2011-12-13 at 12:59 -0500, Jeff King wrote:
> It looks like we already have a check for is_utf8, and this is not
> failing that check. I guess because is_utf8 takes a NUL-terminated
> buffer, so it simply sees the truncated result (i.e., depending on
> endianness, "foo" in utf16 is something like "f\0o\0o\0", so we check
> only "f"). We could make is_utf8 take a length parameter to be more
> accurate, and then it would catch this.
>
> However, I think that's not quite what we want. We only check is_utf8 if
> the encoding field is not set. And really, we want to reject NULs no
> matter _which_ encoding they've set, because git simply doesn't handle
> them properly.
I had already started experimenting with automatically detecting decent
UTF-16 a long while back so that compatible platforms could handle it
appropriately in terms of creating diffs and dealing with newline
munging between platforms. There is no 100% sure-fire check for UTF-16
if you don't already suspect it is possibly UTF-16. If we really want to
check for possible UTF-16 specifically I can scrape out the check I
wrote up and send it along.
The is_utf8 check was not written to detect 100% valid UTF-8 per-se. It
seems to me that it was written as part of the "is this a binary or not"
check in the add/commit path. I have thought for some time that
specifying buffer length in that whole code path would be a good idea
(but I thought that somebody else had taken up that battle while I was
busy dealing with other problems elsewhere), if for no other reason it
would force it to deal with NULs more intelligently.
--
-Drew Northup
________________________________________________
"As opposed to vegetable or mineral error?"
-John Pescatore, SANS NewsBites Vol. 12 Num. 59
^ permalink raw reply
* Re: How to deal with historic tar-balls
From: Philip Oakley @ 2012-01-01 18:30 UTC (permalink / raw)
To: Tomas Carnecky, nn6eumtr; +Cc: Git List
In-Reply-To: <4EFFA868.50605@dbservice.com>
From: "Tomas Carnecky" <tom@dbservice.com> Sent: Sunday, January 01, 2012
12:27 AM
>On 12/31/11 8:04 PM, nn6eumtr wrote:
>> I have a number of older projects that I want to bring into a git
>> repository. They predate a lot of the popular scm systems, so they are
>> primarily a collection of tarballs today.
I'm doing a similar thing with a set of zip files. I grouped mine into
batches for easier checking and putting on to separate branches. Planning
your branch requirements is probably the biggest task, and will depend on
how you hope to use the new repo.
>> I'm fairly new to git so I have a couple questions related to this:
>>
>> - What is the best approach for bringing them in? Do I just create a
>> repository, then unpack the files, commit them, clean out the
>> directory unpack the next tarball, and repeat until everything is loaded?
Essentially yes; Obviously if you have an organisation in mind then you can
introduce maintenance branches etc as you develop the import.
If it is simply to create a nice history that isn't really looked at, then a
simple linear model is OK. If you need to keep old mintenance versions and
obtain diffs with newer versions then look at the various branching models
and populate appropriately.
>>
>> - Do I need to pay special attention to files that are renamed/removed
>> from version to version?
No; It is only if you use those file dates to determine the implied date for
the commit.
>>
>> - If the timestamps change on a file but the actual content does not,
>> will git treat it as a non-change once it realizes the content hasn't
>> changed?
Correct. In fact git doesn't record the time stamps anyway. It simply
records the content, and structure, of the snapshot.
>>
>> - Last, if after loading the repository I find another version of the
>> files that predates those I've loaded, or are intermediate between two
>> commits I've already loaded, is there a way to go say that commit B is
>> actually the ancestor of commit C? (i.e. a->>c becomes a->>b->>c if you
>> were to visualize the commit timeline or do diffs) Or do I just reload
>> the tarballs in order to achieve this?
You can use 'grafts' as a mechanism to re-arrange the commit order, and/or
join partial repos, and then use git filter-branch to re-write the lot as a
single cohesive repo. But this 'hack' does re-write all the commit SHA1
values, so you should minimise the number of times that happens...
It is worth capturing your import sequence as a script so that you can wash
/ rinse / repeat as often as needed to get a result you like.
> There is a script which will import sources from multiple tarballs,
> creating a commit with the contents of each tarball. It's in the git
> repository under contrib/fast-import/import-tars.perl.
I wasn't aware of those scripts. I'll be having a look at the zip import
script for my needs.
My extra problem is that almost all my zips have an extra top level
directory that changes its name for every zip (but some don't..). The TLD
changes confuses the git rename detection if I don't remove them before
committing. Fortunately it's an internal development project with no formal
releases so creating the history is a bit of a personal project which
doesn't affect ongoing development (which is the crunch question for
fidelity of the repo you create).
> tom
Philip
^ permalink raw reply
* Re: How to deal with historic tar-balls
From: Dirk Süsserott @ 2012-01-01 19:04 UTC (permalink / raw)
To: Tomas Carnecky; +Cc: nn6eumtr, git
In-Reply-To: <4EFFA868.50605@dbservice.com>
Am 01.01.2012 01:27 schrieb Tomas Carnecky:
> On 12/31/11 8:04 PM, nn6eumtr wrote:
>> I have a number of older projects that I want to bring into a git
>> repository. They predate a lot of the popular scm systems, so they are
>> primarily a collection of tarballs today.
>>
>> I'm fairly new to git so I have a couple questions related to this:
>>
>> - What is the best approach for bringing them in? Do I just create a
>> repository, then unpack the files, commit them, clean out the
>> directory unpack the next tarball, and repeat until everything is loaded?
>>
>> - Do I need to pay special attention to files that are renamed/removed
>> from version to version?
>>
>> - If the timestamps change on a file but the actual content does not,
>> will git treat it as a non-change once it realizes the content hasn't
>> changed?
>>
>> - Last, if after loading the repository I find another version of the
>> files that predates those I've loaded, or are intermediate between two
>> commits I've already loaded, is there a way to go say that commit B is
>> actually the ancestor of commit C? (i.e. a->c becomes a->b->c if you
>> were to visualize the commit timeline or do diffs) Or do I just reload
>> the tarballs in order to achieve this?
>
> There is a script which will import sources from multiple tarballs,
> creating a commit with the contents of each tarball. It's in the git
> repository under contrib/fast-import/import-tars.perl.
>
> tom
@tom: True. I didn't know about that script, but it should work.
@nn6eumtr: Basically your workflow is perfect. But let me give you some
explanation:
git init
foreach archive in *.tar; do
tar xf $archive
git add --all .
git commit -m "Added $archive"
# now remove everything except for the .git directory
# with regular shell commands (rm -rf *). Also remove
# any dot-files (and the tarball itself, if it's in the
# current directory).
done
Notice the '--all' switch to 'git add': Normally, 'git add .' adds all
files that match the given pattern '.', i.e. all files in the current
directory (and below, it's recursive). The '--all' switch together with
the pattern '.' adds or updates all files already known to git *AND*
adds the files not yet known *AND* removes the files that are no longer
in the working tree. That's exactly what you want.
Consider archive1.tar with files A, B, C:
git add --all . # will add A, B, and C
Now remove A, B, C, and unpack archive2.tar. Assume it has files B, C,
D. A was deleted, B was changed, C is unchanged, D is new.
git add --all . # will remove A, add B, leave C, add D.
git will notice that C hasn't changed its content (timestamp doesn't
matter).
Without the '--all' switch, git would simply add B and D.
There is no problem re-arranging the history after your import (see "git
rebase --help", especially the --interactive section), but then you
probably will have conflicts and have to resolve them. I'd suggest to
re-start the import instead.
Please note that "for archive in *.tar" will pick the tarballs in
lexicographical order. That might not be your intention.
HTH,
Dirk
^ permalink raw reply
* Re: [PATCH 2/2] git-svn, perl/Git.pm: extend and use Git->prompt method for querying users
From: Sven Strickroth @ 2012-01-01 19:45 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Jeff King, Jakub Narebski
In-Reply-To: <7vpqf8z8a6.fsf@alter.siamese.dyndns.org>
Am 28.12.2011 22:38 schrieb Junio C Hamano:
> I am however not sure if the second patch in this series is a good thing
> in the current shape. For GUI users who do not have a terminal, earlier
> they couldn't respond to these questions but now they can, so in that
> narrow sense we are not going backwards.
> But for people who use *_ASKPASS and are working from the terminal, it is
> a regression to ask these non-password questions using *_ASKPASS. Most
> likely, these helpers that are designed for password entry will hide what
> is typed, and I also wouldn't be surprised if some of them have fairly low
> input-length restriction that may be shorter than a long-ish pathname that
> users might want to give as an answer, which they could do in the terminal
> based interaction but will become impossible with this patch.
I'm still for the second patch to be applied (maybe w/o the certificate
filename prompt), too, because this makes git-svn behave the save way as
git-core does (especially asking for username).
Do you think that ppl. mainly using the terminal have *_ASKPASS set?
Most GUIs I know do set it automatically.
I agree that a new interface is needed (working on a patch), but before
we hurry, we should make git-core and git-svn behave the same way.
Btw. git-svn also does not honour git-credentials.
--
Best regards,
Sven Strickroth
ClamAV, a GPL anti-virus toolkit http://www.clamav.net
PGP key id F5A9D4C4 @ any key-server
^ permalink raw reply
* Re: [PATCH 2/2] git-svn, perl/Git.pm: extend and use Git->prompt method for querying users
From: Sven Strickroth @ 2012-01-01 19:57 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Jakub Narebski
In-Reply-To: <7v8vlrwzw9.fsf@alter.siamese.dyndns.org>
Am 01.01.2012 10:11 schrieb Junio C Hamano:
> I do not think Peff means the dialog must ask these three items at the
> same time. The point is that other codepaths know they need to ask them
> and would benefit if they can instruct the dialog external helper to ask
> them in a single interaction. So if your callsite does not ask them
> together, it is OK. You can keep asking them separately in two dialog
> interactions.
Sure. This is possible with my proposed interface.
Two parameters should be sufficient, since we get the path to the
repository from the CWD.
TYPE: 'text' (default), 'pass', 'userpass' (username + password in one
dialog), 'filename'
PROMPT
Am I missing something?
--
Best regards,
Sven Strickroth
ClamAV, a GPL anti-virus toolkit http://www.clamav.net
PGP key id F5A9D4C4 @ any key-server
^ permalink raw reply
* Re: How to deal with historic tar-balls
From: Philip Oakley @ 2012-01-01 20:54 UTC (permalink / raw)
To: Tomas Carnecky, nn6eumtr; +Cc: Git List
In-Reply-To: <B375E525C4704EA8807B5A59257B690B@PhilipOakley>
From: "Philip Oakley" <philipoakley@iee.org> Sent: Sunday, January 01, 2012
6:30 PM
> From: "Tomas Carnecky" <tom@dbservice.com> Sent: Sunday, January 01, 2012
> 12:27 AM
>>On 12/31/11 8:04 PM, nn6eumtr wrote:
>>> I have a number of older projects that I want to bring into a git
>>> repository. They predate a lot of the popular scm systems, so they are
>>> primarily a collection of tarballs today.
> I'm doing a similar thing with a set of zip files. I grouped mine into
> batches for easier checking and putting on to separate branches. Planning
> your branch requirements is probably the biggest task, and will depend on
> how you hope to use the new repo.
>
<snip>
>> There is a script which will import sources from multiple tarballs,
>> creating a commit with the contents of each tarball. It's in the git
>> repository under contrib/fast-import/import-tars.perl.
> I wasn't aware of those scripts. I'll be having a look at the zip import
> script for my needs.
Is there a mechanism for either having fast-import respect a .gitignore,
or determining if a given file/path should be ignored?
My zips contain a lot of compile by-products that should be excluded from
the repo.
> My extra problem is that almost all my zips have an extra top level
> directory that changes its name for every zip (but some don't..). The TLD
> changes confuses the git rename detection if I don't remove them before
> committing. Fortunately it's an internal development project with no
> formal
> releases so creating the history is a bit of a personal project which
> doesn't affect ongoing development (which is the crunch question for
> fidelity of the repo you create).
>
>> tom
> Philip
^ permalink raw reply
* Re: [PATCH 2/2] git-svn, perl/Git.pm: extend and use Git->prompt method for querying users
From: Sven Strickroth @ 2012-01-01 20:55 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Jakub Narebski
In-Reply-To: <4F00BAA6.9050104@tu-clausthal.de>
Following you can find my first proposal, based upon patch 1. It's only the
perl part, because I haven't checked out Peffs git_prompt patch(es) and to
avoid double work.
ATM I'm unsure about the 'username' type, but I think it's quite necessary
to make git-svn behave like git-core in case of asking for a username. A type
'userpass' (username and password in one dialog) isn't mentioned here, because
it's not necessary for the git-svn part, but we should also specify/document it
if we want to use it in the future.
Btw. happy new year! ;)
---
git-svn.perl | 24 +++++++------------
perl/Git.pm | 70 ++++++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 58 insertions(+), 36 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 26d3559..54cf77f 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -4356,17 +4356,16 @@ sub ssl_server_trust {
map $cert_info->$_, qw(hostname valid_from valid_until
issuer_dname fingerprint);
my $choice;
-prompt:
- print STDERR $may_save ?
+ my $prompt = $may_save ?
"(R)eject, accept (t)emporarily or accept (p)ermanently? " :
"(R)eject or accept (t)emporarily? ";
- STDERR->flush;
- $choice = lc(substr(<STDIN> || 'R', 0, 1));
- if ($choice =~ /^t$/i) {
+prompt:
+ $choice = lc(substr(Git->prompt($prompt) || 'R', 0, 1));
+ if ($choice eq "t") {
$cred->may_save(undef);
- } elsif ($choice =~ /^r$/i) {
+ } elsif ($choice eq "r") {
return -1;
- } elsif ($may_save && $choice =~ /^p$/i) {
+ } elsif ($may_save && $choice eq "p") {
$cred->may_save($may_save);
} else {
goto prompt;
@@ -4378,10 +4377,7 @@ prompt:
sub ssl_client_cert {
my ($cred, $realm, $may_save, $pool) = @_;
$may_save = undef if $_no_auth_cache;
- print STDERR "Client certificate filename: ";
- STDERR->flush;
- chomp(my $filename = <STDIN>);
- $cred->cert_file($filename);
+ $cred->cert_file(Git->prompt("Client certificate filename: ", 'filename'));
$cred->may_save($may_save);
$SVN::_Core::SVN_NO_ERROR;
}
@@ -4404,9 +4400,7 @@ sub username {
if (defined $_username) {
$username = $_username;
} else {
- print STDERR "Username: ";
- STDERR->flush;
- chomp($username = <STDIN>);
+ $username = Git->prompt("Username: ", 'username');
}
$cred->username($username);
$cred->may_save($may_save);
@@ -4415,7 +4409,7 @@ sub username {
sub _read_password {
my ($prompt, $realm) = @_;
- my $password = Git->prompt($prompt);
+ my $password = Git->prompt($prompt, 'pass');
$password;
}
diff --git a/perl/Git.pm b/perl/Git.pm
index ba9a5f2..17ddf40 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -512,52 +512,80 @@ C<git --html-path>). Useful mostly only internally.
sub html_path { command_oneline('--html-path') }
-=item prompt ( PROMPT )
+=item prompt ( PROMPT , TYPE )
Query user C<PROMPT> and return answer from user.
-If an external helper is specified via GIT_ASKPASS or SSH_ASKPASS, it
-is used to interact with the user; otherwise the prompt is given to
-and the answer is read from the terminal.
+If an external helper is specified via GIT_DIALOG, GIT_ASKPASS or
+SSH_ASKPASS, it is used to interact with the user; otherwise the
+prompt is given to and the answer is read from the terminal.
+
+Possible values for C<TYPE>:
+- '' or 'text': prompt for normal text (only GIT_DIALOG)
+- 'username': prompt for username (behaves exactly as 'text', but also
+ uses *_ASKPASS)
+- 'pass': prompt for password, echoing of what is typed is disabled on
+ the terminal, GUI tool shows asterisks.
+- 'filename': prompt for a filename, GUI tool migh provide file chooser
+ (only GIT_DIALOG)
=cut
sub prompt {
- my ($self, $prompt) = _maybe_self(@_);
+ my ($self, $prompt, $type) = _maybe_self(@_);
+ $type = 'text' unless ($type);
+ my $useAskPass = ($type eq 'pass' || $type eq 'username');
my $ret;
if (!defined $ret) {
- $ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
+ $ret = _promptgitdialog($ENV{'GIT_DIALOG'}, $prompt, $type);
}
- if (!defined $ret) {
- $ret = _prompt($ENV{'SSH_ASKPASS'}, $prompt);
+ if ($useAskPass && !defined $ret) {
+ $ret = _promptaskpass($ENV{'GIT_ASKPASS'}, $prompt);
+ }
+ if ($useAskPass && !defined $ret) {
+ $ret = _promptaskpass($ENV{'SSH_ASKPASS'}, $prompt);
}
if (!defined $ret) {
$ret = '';
print STDERR $prompt;
STDERR->flush;
- require Term::ReadKey;
- Term::ReadKey::ReadMode('noecho');
- while (defined(my $key = Term::ReadKey::ReadKey(0))) {
- last if $key =~ /[\012\015]/; # \n\r
- $ret .= $key;
+ if ($type eq 'pass') {
+ require Term::ReadKey;
+ Term::ReadKey::ReadMode('noecho');
+ while (defined(my $key = Term::ReadKey::ReadKey(0))) {
+ last if $key =~ /[\012\015]/; # \n\r
+ $ret .= $key;
+ }
+ Term::ReadKey::ReadMode('restore');
+ print STDERR "\n";
+ STDERR->flush;
+ } else {
+ chomp($ret = <STDIN>);
}
- Term::ReadKey::ReadMode('restore');
- print STDERR "\n";
- STDERR->flush;
}
return $ret;
}
-sub _prompt {
+sub _promptgitdialog {
+ my ($gitdialog, $prompt, $type) = @_;
+ return undef unless ($askpass);
+ my $ret;
+ open my $fh, "-|", $gitdialog, $type, $prompt
+ or return undef;
+ $ret = <$fh>;
+ $ret =~ s/\r?\n$//; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected
+ close ($fh);
+ return $ret;
+}
+
+sub _promptaskpass {
my ($askpass, $prompt) = @_;
- unless ($askpass) {
- return undef;
- }
+ return undef unless ($askpass);
my $ret;
open my $fh, "-|", $askpass, $prompt
or return undef;
$ret = <$fh>;
- $ret =~ s/[\012\015]//g; # \n\r
+ $ret =~ s/\r?\n$//; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected
close ($fh);
return $ret;
}
--
--
Best regards,
Sven Strickroth
ClamAV, a GPL anti-virus toolkit http://www.clamav.net
PGP key id F5A9D4C4 @ any key-server
^ permalink raw reply related
* Re: Possible submodule or submodule documentation issue
From: Bill Zaumen @ 2012-01-02 3:53 UTC (permalink / raw)
To: Jens Lehmann; +Cc: git, Junio C Hamano
In-Reply-To: <4F00780C.7090801@web.de>
On Sun, 2012-01-01 at 16:13 +0100, Jens Lehmann wrote:
> Am 29.12.2011 03:50, schrieb Bill Zaumen:
> > So what about clarifying
> the docs: ...
Clarifying the docs is a good solution given that a possibly large
number of existing repositories are dependent on the current behavior.
One way of explaining it is to say that "git first appends a
'/' to the superproject's origin URL if that URL does not already
end in a '/'. Relative URLs for submodules' origin repository are
resolved relative to this modified URL." Then the reader can simply
apply the normal URL rules.
I think either is OK - it's simply a judgment call as to which
explanation is easiest for a typical git user to understand.
^ permalink raw reply
* Re: git alias question
From: Michael Horowitz @ 2012-01-02 5:57 UTC (permalink / raw)
To: Jakub Narebski; +Cc: David Aguilar, Dave Borowitz, git, Junio C Hamano
In-Reply-To: <m3zke8e2vh.fsf@localhost.localdomain>
Nice, works perfectly! Didn't notice that was there, guess last time
I looked, I was using an older version. I see it is in the git config
man page and all now.
Thanks,
Mike
On Sat, Dec 31, 2011 at 6:30 PM, Jakub Narebski <jnareb@gmail.com> wrote:
>
> Michael Horowitz <michael.horowitz@ieee.org> writes:
>
> > The log operation does seem to make the most sense as the mechanism to
> > search for the results. Making it work with difftool would work...
> > Not sure if "--log" to difftool or some other options as suggested in
> > the other thread would be most consistent UI-wise as stated, but
> > either would work for me.
> >
> > On a separate note, some environment variable like GIT_PREFIX with the
> > CWD would make the alias functionality more flexible.
>
> 1f5d271 (setup: Provide GIT_PREFIX to built-ins, 2011-05-25) is
> present in v1.7.7; 7cf16a1 (handle_alias: provide GIT_PREFIX to
> !alias, 2011-04-27) is in 1.7.6
>
> --
> Jakub Narebski
^ permalink raw reply
* Re: What's the best way to push/fetch replace refs?
From: Slawomir Testowy @ 2012-01-02 6:16 UTC (permalink / raw)
To: Christian Couder; +Cc: git
In-Reply-To: <CAP8UFD3KSjdZz1q+QYsH4JpRkiavtTbT1WqQSdxqCaxc24j=Rg@mail.gmail.com>
2011/12/30 Christian Couder <christian.couder@gmail.com>:
> On Fri, Dec 30, 2011 at 12:59 PM, Slawomir Testowy
> <slawomir.testowy@gmail.com> wrote:
>>
>> # I also added "fetch = +refs/replace/*:refs/replace/*" to [remote
>> "origin"] in "b" and this also seems to work.
>
> Yeah, the simplest is probably to just add "fetch =
> +refs/replace/*:refs/replace/*" to the remote(s) you want to get the
> replace refs from, and "push = +refs/replace/*:refs/replace/*" to the
> remote(s) you want to push the replace refs to.
>
> Regards,
> Christian.
Thanks Christian, I thought maybe there is some magic "git clone
--get-also-replace-refs" or something. I'm asking because I'm about to
tell people how to clone my repository and some of them don't know Git
at all so I wanted to find out the simplest/best way to fetch replace refs.
Thanks.
^ permalink raw reply
* Odd remote: error: packfile ./objects/pack/pack-FOO.pack cannot be accessed
From: Sudarshan Wadkar @ 2012-01-02 9:18 UTC (permalink / raw)
To: git
In-Reply-To: <CAOoYcj2pnNtK3RshcJFwiXK356cZz6M38-NG1_uORjknyhdAKQ@mail.gmail.com>
I have a simple post-receive hook as follows :
#!/bin/bash
# using bash and not simple sh
# simply checkout the master branch to notBare path, use tools from
that portion to deploy further
notBareRepo='/home/sudhi/repo/notBare/myproj-master'
GIT_WORK_TREE="$notBareRepo" git reset --hard master
#end post-receive
But when I push, I get this odd error from remote
$ git push --verbose --mirror
ssh://wadkar@192.168.1.177:7185/~wadkar/repo/bare/myproj.git
Pushing to ssh://wadkar@192.168.1.177:7185/~wadkar/repo/bare/myproj.git
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 323 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: error: packfile
./objects/pack/pack-17900952dc824651db15369a341eec8d3e8f39d2.pack
cannot be accessed
remote: HEAD is now at 4d5a6f1 Investigate and report odd error
To ssh://wadkar@192.168.1.177:7185/~wadkar/repo/bare/myproj.git
d066a2f..4d5a6f1 master -> master
This happens even if I do a fresh clone on remote server as:
$ cd repo/bare; git clone --mirror wadkar@my_ip_address:myproj
Local " git fsck " reports few dangling blobs but nothing
fancy/serious. Remote git version is 1.7.4.1 on a CentOS 5.7, while
the local is same (1.7.4.1) on a Ubuntu 11.04.
1. How bad is the situation?
2. Have I done something wrong, or this is not my doing?
3. The checked out version in repo/notBare is fine, and seems to be
working (I can pass my unit-tests). Should I be worried?
4. If not, then can I ignore this particular error and move on?
-Sudarshan Wadkar
"Success is getting what you want. Happiness is wanting what you get."
- Dale Carnegie
"It's always our decision who we are"
- Robert Solomon in Waking Life
"The truth is the truth, so all you can do is live with it."
--Systematic Chaos
^ permalink raw reply
* Re: [PATCH 1/2] daemon: add tests
From: Jonathan Nieder @ 2012-01-02 9:25 UTC (permalink / raw)
To: Clemens Buchacher
Cc: git, Junio C Hamano, Jeff King, Erik Faye-Lund, Ilari Liusvaara,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1318803076-4229-1-git-send-email-drizzd@aon.at>
(+cc: Erik, Ilari, Duy)
Hi,
Clemens Buchacher wrote:
> [Subject: daemon: add tests]
Can't believe I missed this. That seems like a worthy cause ---
can someone remind me why this is dropped, or if there are any
tweaks I can help with to get it picked up again?
Patch left unsnipped for convenience of people cc-ed.
Jonathan
> The semantics of the git daemon tests are similar to the http
> transport tests. In fact, they are only a slightly modified copy
> of t5550, plus the newly added remote error tests.
>
> All daemon tests will be skipped unless the environment variable
> GIT_TEST_DAEMON is set.
>
> Signed-off-by: Clemens Buchacher <drizzd@aon.at>
> ---
>
> This patch is based on jk/daemon-msgs.
>
> t/lib-daemon.sh | 52 +++++++++++++++++
> t/t5570-git-daemon.sh | 148 +++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 200 insertions(+), 0 deletions(-)
> create mode 100644 t/lib-daemon.sh
> create mode 100755 t/t5570-git-daemon.sh
>
> diff --git a/t/lib-daemon.sh b/t/lib-daemon.sh
> new file mode 100644
> index 0000000..30a89ea
> --- /dev/null
> +++ b/t/lib-daemon.sh
> @@ -0,0 +1,52 @@
> +#!/bin/sh
> +
> +if test -z "$GIT_TEST_DAEMON"
> +then
> + skip_all="Daemon testing disabled (define GIT_TEST_DAEMON to enable)"
> + test_done
> +fi
> +
> +LIB_DAEMON_PORT=${LIB_DAEMON_PORT-'8121'}
> +
> +DAEMON_PID=
> +DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo
> +DAEMON_URL=git://127.0.0.1:$LIB_DAEMON_PORT
> +
> +start_daemon() {
> + if test -n "$DAEMON_PID"
> + then
> + error "start_daemon already called"
> + fi
> +
> + mkdir -p "$DAEMON_DOCUMENT_ROOT_PATH"
> +
> + trap 'code=$?; stop_daemon; (exit $code); die' EXIT
> +
> + say >&3 "Starting git daemon ..."
> + git daemon --listen=127.0.0.1 --port="$LIB_DAEMON_PORT" \
> + --reuseaddr --verbose \
> + --base-path="$DAEMON_DOCUMENT_ROOT_PATH" \
> + "$@" "$DAEMON_DOCUMENT_ROOT_PATH" \
> + >&3 2>&4 &
> + DAEMON_PID=$!
> +}
> +
> +stop_daemon() {
> + if test -z "$DAEMON_PID"
> + then
> + return
> + fi
> +
> + trap 'die' EXIT
> +
> + # kill git-daemon child of git
> + say >&3 "Stopping git daemon ..."
> + pkill -P "$DAEMON_PID"
> + wait "$DAEMON_PID"
> + ret=$?
> + if test $ret -ne 143
> + then
> + error "git daemon exited with status: $ret"
> + fi
> + DAEMON_PID=
> +}
> diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh
> new file mode 100755
> index 0000000..aa5771a
> --- /dev/null
> +++ b/t/t5570-git-daemon.sh
> @@ -0,0 +1,148 @@
> +#!/bin/sh
> +
> +test_description='test fetching over git protocol'
> +. ./test-lib.sh
> +
> +. "$TEST_DIRECTORY"/lib-daemon.sh
> +start_daemon
> +
> +test_expect_success 'setup repository' '
> + echo content >file &&
> + git add file &&
> + git commit -m one
> +'
> +
> +test_expect_success 'create git-accessible bare repository' '
> + mkdir "$DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
> + (cd "$DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
> + git --bare init &&
> + : >git-daemon-export-ok
> + ) &&
> + git remote add public "$DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
> + git push public master:master
> +'
> +
> +test_expect_success 'clone git repository' '
> + git clone $DAEMON_URL/repo.git clone &&
> + test_cmp file clone/file
> +'
> +
> +test_expect_success 'fetch changes via git protocol' '
> + echo content >>file &&
> + git commit -a -m two &&
> + git push public &&
> + (cd clone && git pull) &&
> + test_cmp file clone/file
> +'
> +
> +test_expect_failure 'remote detects correct HEAD' '
> + git push public master:other &&
> + (cd clone &&
> + git remote set-head -d origin &&
> + git remote set-head -a origin &&
> + git symbolic-ref refs/remotes/origin/HEAD > output &&
> + echo refs/remotes/origin/master > expect &&
> + test_cmp expect output
> + )
> +'
> +
> +test_expect_success 'prepare pack objects' '
> + cp -R "$DAEMON_DOCUMENT_ROOT_PATH"/repo.git "$DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git &&
> + (cd "$DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git &&
> + git --bare repack &&
> + git --bare prune-packed
> + )
> +'
> +
> +test_expect_success 'fetch notices corrupt pack' '
> + cp -R "$DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$DAEMON_DOCUMENT_ROOT_PATH"/repo_bad1.git &&
> + (cd "$DAEMON_DOCUMENT_ROOT_PATH"/repo_bad1.git &&
> + p=`ls objects/pack/pack-*.pack` &&
> + chmod u+w $p &&
> + printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc
> + ) &&
> + mkdir repo_bad1.git &&
> + (cd repo_bad1.git &&
> + git --bare init &&
> + test_must_fail git --bare fetch $DAEMON_URL/repo_bad1.git &&
> + test 0 = `ls objects/pack/pack-*.pack | wc -l`
> + )
> +'
> +
> +test_expect_success 'fetch notices corrupt idx' '
> + cp -R "$DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
> + (cd "$DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
> + p=`ls objects/pack/pack-*.idx` &&
> + chmod u+w $p &&
> + printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc
> + ) &&
> + mkdir repo_bad2.git &&
> + (cd repo_bad2.git &&
> + git --bare init &&
> + test_must_fail git --bare fetch $DAEMON_URL/repo_bad2.git &&
> + test 0 = `ls objects/pack | wc -l`
> + )
> +'
> +
> +test_remote_error()
> +{
> + do_export=YesPlease
> + while test $# -gt 0
> + do
> + case $1 in
> + -x)
> + shift
> + chmod -X "$DAEMON_DOCUMENT_ROOT_PATH/repo.git"
> + ;;
> + -n)
> + shift
> + do_export=
> + ;;
> + *)
> + break
> + esac
> + done
> +
> + if test $# -ne 3
> + then
> + error "invalid number of arguments"
> + fi
> +
> + cmd=$1
> + repo=$2
> + msg=$3
> +
> + if test -x "$DAEMON_DOCUMENT_ROOT_PATH/$repo"
> + then
> + if test -n "$do_export"
> + then
> + : >"$DAEMON_DOCUMENT_ROOT_PATH/$repo/git-daemon-export-ok"
> + else
> + rm -f "$DAEMON_DOCUMENT_ROOT_PATH/$repo/git-daemon-export-ok"
> + fi
> + fi
> +
> + test_must_fail git "$cmd" "$DAEMON_URL/$repo" 2>output &&
> + echo "fatal: remote error: $msg: /$repo" >expect &&
> + test_cmp expect output
> + ret=$?
> + chmod +X "$DAEMON_DOCUMENT_ROOT_PATH/repo.git"
> + (exit $ret)
> +}
> +
> +msg="access denied or repository not exported"
> +test_expect_success 'clone non-existent' "test_remote_error clone nowhere.git '$msg'"
> +test_expect_success 'push disabled' "test_remote_error push repo.git '$msg'"
> +test_expect_success 'read access denied' "test_remote_error -x fetch repo.git '$msg'"
> +test_expect_success 'not exported' "test_remote_error -n fetch repo.git '$msg'"
> +
> +stop_daemon
> +start_daemon --informative-errors
> +
> +test_expect_success 'clone non-existent' "test_remote_error clone nowhere.git 'no such repository'"
> +test_expect_success 'push disabled' "test_remote_error push repo.git 'service not enabled'"
> +test_expect_success 'read access denied' "test_remote_error -x fetch repo.git 'no such repository'"
> +test_expect_success 'not exported' "test_remote_error -n fetch repo.git 'repository not exported'"
> +
> +stop_daemon
> +test_done
> --
> 1.7.7
>
>
^ permalink raw reply
* Re: How to deal with historic tar-balls
From: Philip Oakley @ 2012-01-02 10:07 UTC (permalink / raw)
To: Philip Oakley, Tomas Carnecky, nn6eumtr; +Cc: Git List
In-Reply-To: <B375E525C4704EA8807B5A59257B690B@PhilipOakley>
From: "Philip Oakley" <philipoakley@iee.org>: Sunday, January 01, 2012 6:30
PM
> From: "Tomas Carnecky" <tom@dbservice.com> : Sunday, January 01, 2012
> 12:27 AM
>>On 12/31/11 8:04 PM, nn6eumtr wrote:
>>> I have a number of older projects that I want to bring into a git
>>> repository. They predate a lot of the popular scm systems, so they are
>>> primarily a collection of tarballs today.
>> There is a script which will import sources from multiple tarballs,
>> creating a commit with the contents of each tarball. It's in the git
>> repository under contrib/fast-import/import-tars.perl.
> I wasn't aware of those scripts. I'll be having a look at the zip import
> script for my needs.
>
>> tom
> Philip
>
I had a look at the script but Python isn't part of the Msysgit install, so
the example wouldn't run.
Also I couldn't see how the "fast_import.write(" method was being created -
my ignorance of Python? Otherwise I could look at scripting it.
Philip
^ permalink raw reply
* [BUG] gitweb generates wrong links in grep search results (git_search_files)
From: Thomas Perl @ 2012-01-02 13:29 UTC (permalink / raw)
To: git
Hi,
I think I found a bug in gitweb when grep'ing for text in a branch
different from "master". Here's how to reproduce it:
1. Have a project with a master branch and a branch different from master
2. Start gitweb for that project (e.g. using "git instaweb") and open
it in a web browser
3. Switch to the non-master branch (e.g.
http://127.0.0.1:1234/?p=.git;a=shortlog;h=refs/heads/mynonmasterbranch)
4. In the top right search box, select "grep" in the combo box and
enter a text that only appears in the non-master branch
5. Submit the search by pressing enter, you should be at:
http://127.0.0.1:1234/?p=.git&a=search&h=refs%2Fheads%2Fmynonmasterbranch&st=grep&s=somesearchtext
ACTUAL RESULT
In that list of results, you should now see some files matching the
search - note that the links for the file names and the line numbers
go to e.g. http://127.0.0.1:1234/?p=.git;a=blob;f=somefile.txt for a
file "somefile.txt". The links therefore go to the master branch,
while the search results refer to the non-master branch.
EXPECTED RESULT
The link should (presumably) go to
http://127.0.0.1:1234/?p=.git;a=blob;hb=refs%2Fheads%2Fmynonmasterbranch;f=somefile.txt
so that when the link is clicked, the right file (somefile.txt in
mynonmasterbranch) is shown.
I also investigated a bit in where the problem happens, and nailed it
down to: gitweb/gitweb.perl, sub git_search_files, line 5871 in commit
17b4e93d5b849293e6a3659bbc4075ed8a6e97e2 (current master tip of
https://github.com/gitster/git). I haven't looked at the intrinsics of
the "href" sub, but I believe that it should somehow get the "h"
parameter from the original page and incorporate it into the final
link (as "hb" parameter?) to the file. The same fix that is applied
there then also needs to be applied at line 5891 (same commit, same
file).
No patch, because after several tries, I didn't get it to work, my
Perl foo might not be up to the task, and I believe that someone more
familiar with gitweb's code base might have an easier time to fix
this.
Thanks,
Thomas
^ permalink raw reply
* Re: How to deal with historic tar-balls
From: Dirk Süsserott @ 2012-01-02 18:26 UTC (permalink / raw)
To: Philip Oakley; +Cc: Tomas Carnecky, nn6eumtr, Git List
In-Reply-To: <4C50794C7EED42A0B1A25ABD77CE7DB0@PhilipOakley>
Am 02.01.2012 11:07 schrieb Philip Oakley:
> From: "Philip Oakley" <philipoakley@iee.org>: Sunday, January 01, 2012
> 6:30 PM
>> From: "Tomas Carnecky" <tom@dbservice.com> : Sunday, January 01, 2012
>> 12:27 AM
>>> On 12/31/11 8:04 PM, nn6eumtr wrote:
>>>> I have a number of older projects that I want to bring into a git
>>>> repository. They predate a lot of the popular scm systems, so they are
>>>> primarily a collection of tarballs today.
>>> There is a script which will import sources from multiple tarballs,
>>> creating a commit with the contents of each tarball. It's in the git
>>> repository under contrib/fast-import/import-tars.perl.
>> I wasn't aware of those scripts. I'll be having a look at the zip import
>> script for my needs.
>>
>>> tom
>> Philip
>>
> I had a look at the script but Python isn't part of the Msysgit install,
> so the example wouldn't run.
>
> Also I couldn't see how the "fast_import.write(" method was being
> created - my ignorance of Python? Otherwise I could look at scripting it.
>
> Philip
Philip,
I'm not a Python guy, but I think fast_import.write() writes sth. to
whatever the popen() call in line 24 returned:
fast_import = popen('git fast-import --quiet', 'w')
I guess it returns a filehandle and 'git fast-import' reads its data
from stdin. My guess is, that -- instead of writing to that pipe -- you
could as well write everything to a temporary file and finally call
git fast-import < $tempfile
But that's only a guess.
Dirk
^ permalink raw reply
* Re: [PATCH 1/2] daemon: add tests
From: Clemens Buchacher @ 2012-01-02 19:47 UTC (permalink / raw)
To: Jonathan Nieder
Cc: git, Junio C Hamano, Jeff King, Erik Faye-Lund, Ilari Liusvaara,
Nguyễn Thái Ngọc Duy
In-Reply-To: <20120102092508.GA10977@elie.hsd1.il.comcast.net>
On Mon, Jan 02, 2012 at 03:25:08AM -0600, Jonathan Nieder wrote:
>
> > [Subject: daemon: add tests]
>
> Can't believe I missed this. That seems like a worthy cause ---
> can someone remind me why this is dropped, or if there are any
> tweaks I can help with to get it picked up again?
We were discussing some open issues with patch 2/2, which was based
on the tests. I later abandoned the idea for that patch. But the
tests should be ok by themselves.
Clemens
^ permalink raw reply
* [PATCH 0/6] git-p4: view spec improvements
From: Pete Wyckoff @ 2012-01-02 23:05 UTC (permalink / raw)
To: git; +Cc: Gary Gibbons
Gary found and fixed a few bothersome problems with how
git-p4 parses the View lines in client specifications.
I got the itch to fix other issues, and ended up writing
a battery of test cases and redoing the view spec code
entirely.
Patch summary:
1. Add 22 test cases for client view spec handling,
most of which are expected to fail. Test review
welcome.
2-4. Fix issues with unsupported wildcards, incorrect
sorting, and add support for single-file maps.
5. Rewrite view spec code, fixing the rest of the tests.
This is new python that could use some review.
6. Update docs. This depends on pw/p4-docs-and-tests that
is in next.
Gary Gibbons (3):
git-p4: fix test for unsupported P4 Client Views
git-p4: sort client views by reverse View number
git-p4: support single file p4 client view maps
Pete Wyckoff (3):
git-p4: test client view handling
git-p4: rewrite view handling
git-p4: view spec documentation
Documentation/git-p4.txt | 40 ++++--
contrib/fast-import/git-p4 | 316 ++++++++++++++++++++++++++++++++---------
t/t9809-git-p4-client-view.sh | 290 +++++++++++++++++++++++++++++++++++++
3 files changed, 564 insertions(+), 82 deletions(-)
create mode 100755 t/t9809-git-p4-client-view.sh
--
1.7.8.1.407.gd70cb
^ permalink raw reply
* [PATCH 1/6] git-p4: test client view handling
From: Pete Wyckoff @ 2012-01-02 23:05 UTC (permalink / raw)
To: git; +Cc: Gary Gibbons
In-Reply-To: <1325545554-16540-1-git-send-email-pw@padd.com>
Test many aspects of processing p4 client views with the
git-p4 option --use-client-spec. 16 out of 22 tests are
currently broken.
Signed-off-by: Pete Wyckoff <pw@padd.com>
---
t/t9809-git-p4-client-view.sh | 290 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 290 insertions(+), 0 deletions(-)
create mode 100755 t/t9809-git-p4-client-view.sh
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
new file mode 100755
index 0000000..4259fb3
--- /dev/null
+++ b/t/t9809-git-p4-client-view.sh
@@ -0,0 +1,290 @@
+#!/bin/sh
+
+test_description='git-p4 client view'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+#
+# Construct a client with this list of View lines
+#
+client_view() {
+ (
+ cat <<-EOF &&
+ Client: client
+ Description: client
+ Root: $cli
+ View:
+ EOF
+ for arg ; do
+ printf "\t$arg\n"
+ done
+ ) | p4 client -i
+}
+
+#
+# Verify these files exist, exactly. Caller creates
+# a list of files in file "files".
+#
+check_files_exist() {
+ ok=0 &&
+ num=${#@} &&
+ for arg ; do
+ test_path_is_file "$arg" &&
+ ok=$(($ok + 1))
+ done &&
+ test $ok -eq $num &&
+ test_line_count = $num files
+}
+
+#
+# Sync up the p4 client, make sure the given files (and only
+# those) exist.
+#
+client_verify() {
+ (
+ cd "$cli" &&
+ p4 sync &&
+ find . -type f ! -name files >files &&
+ check_files_exist "$@"
+ )
+}
+
+#
+# Make sure the named files, exactly, exist.
+#
+git_verify() {
+ (
+ cd "$git" &&
+ git ls-files >files &&
+ check_files_exist "$@"
+ )
+}
+
+# //depot
+# - dir1
+# - file11
+# - file12
+# - dir2
+# - file21
+# - file22
+test_expect_success 'init depot' '
+ (
+ cd "$cli" &&
+ for d in 1 2 ; do
+ mkdir -p dir$d &&
+ for f in 1 2 ; do
+ echo dir$d/file$d$f >dir$d/file$d$f &&
+ p4 add dir$d/file$d$f &&
+ p4 submit -d "dir$d/file$d$f"
+ done
+ done &&
+ find . -type f ! -name files >files &&
+ check_files_exist dir1/file11 dir1/file12 \
+ dir2/file21 dir2/file22
+ )
+'
+
+# double % for printf
+test_expect_failure 'unsupported view wildcard %%n' '
+ client_view "//depot/%%%%1/sub/... //client/sub/%%%%1/..." &&
+ test_when_finished cleanup_git &&
+ test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
+'
+
+test_expect_failure 'unsupported view wildcard *' '
+ client_view "//depot/*/bar/... //client/*/bar/..." &&
+ test_when_finished cleanup_git &&
+ test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
+'
+
+test_expect_success 'wildcard ... only supported at end of spec' '
+ client_view "//depot/.../file11 //client/.../file11" &&
+ test_when_finished cleanup_git &&
+ test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
+'
+
+test_expect_failure 'basic map' '
+ client_view "//depot/dir1/... //client/cli1/..." &&
+ files="cli1/file11 cli1/file12" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_failure 'client view with no mappings' '
+ client_view &&
+ client_verify &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify
+'
+
+test_expect_failure 'single file map' '
+ client_view "//depot/dir1/file11 //client/file11" &&
+ files="file11" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_failure 'later mapping takes precedence (entire repo)' '
+ client_view "//depot/dir1/... //client/cli1/..." \
+ "//depot/... //client/cli2/..." &&
+ files="cli2/dir1/file11 cli2/dir1/file12
+ cli2/dir2/file21 cli2/dir2/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_failure 'later mapping takes precedence (partial repo)' '
+ client_view "//depot/dir1/... //client/..." \
+ "//depot/dir2/... //client/..." &&
+ files="file21 file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+# Reading the view backwards,
+# dir2 goes to cli12
+# dir1 cannot go to cli12 since it was filled by dir2
+# dir1 also does not go to cli3, since the second rule
+# noticed that it matched, but was already filled
+test_expect_failure 'depot path matching rejected client path' '
+ client_view "//depot/dir1/... //client/cli3/..." \
+ "//depot/dir1/... //client/cli12/..." \
+ "//depot/dir2/... //client/cli12/..." &&
+ files="cli12/file21 cli12/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+# since both have the same //client/..., the exclusion
+# rule keeps everything out
+test_expect_failure 'exclusion wildcard, client rhs same (odd)' '
+ client_view "//depot/... //client/..." \
+ "-//depot/dir2/... //client/..." &&
+ client_verify &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify
+'
+
+test_expect_success 'exclusion wildcard, client rhs different (normal)' '
+ client_view "//depot/... //client/..." \
+ "-//depot/dir2/... //client/dir2/..." &&
+ files="dir1/file11 dir1/file12" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_failure 'exclusion single file' '
+ client_view "//depot/... //client/..." \
+ "-//depot/dir2/file22 //client/file22" &&
+ files="dir1/file11 dir1/file12 dir2/file21" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_failure 'overlay wildcard' '
+ client_view "//depot/dir1/... //client/cli/..." \
+ "+//depot/dir2/... //client/cli/...\n" &&
+ files="cli/file11 cli/file12 cli/file21 cli/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_failure 'overlay single file' '
+ client_view "//depot/dir1/... //client/cli/..." \
+ "+//depot/dir2/file21 //client/cli/file21" &&
+ files="cli/file11 cli/file12 cli/file21" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_failure 'exclusion with later inclusion' '
+ client_view "//depot/... //client/..." \
+ "-//depot/dir2/... //client/dir2/..." \
+ "//depot/dir2/... //client/dir2incl/..." &&
+ files="dir1/file11 dir1/file12 dir2incl/file21 dir2incl/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_failure 'quotes on rhs only' '
+ client_view "//depot/dir1/... \"//client/cdir 1/...\"" &&
+ client_verify "cdir 1/file11" "cdir 1/file12" &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify "cdir 1/file11" "cdir 1/file12"
+'
+
+#
+# Rename directories to test quoting in depot-side mappings
+# //depot
+# - "dir 1"
+# - file11
+# - file12
+# - "dir 2"
+# - file21
+# - file22
+#
+test_expect_success 'rename files to introduce spaces' '
+ client_view "//depot/... //client/..." &&
+ client_verify dir1/file11 dir1/file12 \
+ dir2/file21 dir2/file22 &&
+ (
+ cd "$cli" &&
+ p4 open dir1/... &&
+ p4 move dir1/... "dir 1"/... &&
+ p4 open dir2/... &&
+ p4 move dir2/... "dir 2"/... &&
+ p4 submit -d "rename with spaces"
+ ) &&
+ client_verify "dir 1/file11" "dir 1/file12" \
+ "dir 2/file21" "dir 2/file22"
+'
+
+test_expect_failure 'quotes on lhs only' '
+ client_view "\"//depot/dir 1/...\" //client/cdir1/..." &&
+ files="cdir1/file11 cdir1/file12" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ client_verify $files
+'
+
+test_expect_failure 'quotes on both sides' '
+ client_view "\"//depot/dir 1/...\" \"//client/cdir 1/...\"" &&
+ client_verify "cdir 1/file11" "cdir 1/file12" &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify "cdir 1/file11" "cdir 1/file12"
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
--
1.7.8.1.407.gd70cb
^ permalink raw reply related
* [PATCH 2/6] git-p4: fix test for unsupported P4 Client Views
From: Pete Wyckoff @ 2012-01-02 23:05 UTC (permalink / raw)
To: git; +Cc: Gary Gibbons
In-Reply-To: <1325545554-16540-1-git-send-email-pw@padd.com>
From: Gary Gibbons <ggibbons@perforce.com>
Change re method in test for unsupported Client View types
(containing %% or *) anywhere in the string rather than
at the begining.
[pw: two tests now succeed]
Signed-off-by: Gary Gibbons <ggibbons@perforce.com>
Signed-off-by: Pete Wyckoff <pw@padd.com>
---
contrib/fast-import/git-p4 | 5 ++++-
t/t9809-git-p4-client-view.sh | 4 ++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index d3c3ad8..c144c89 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -1889,9 +1889,12 @@ class P4Sync(Command, P4UserMap):
# p4 has these %%1 to %%9 arguments in specs to
# reorder paths; which we can't handle (yet :)
- if re.match('%%\d', v) != None:
+ if re.search('%%\d', v) != None:
print "Sorry, can't handle %%n arguments in client specs"
sys.exit(1)
+ if re.search('\*', v) != None:
+ print "Sorry, can't handle * mappings in client specs"
+ sys.exit(1)
if v.startswith('"'):
start = 1
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 4259fb3..cbf2213 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -89,13 +89,13 @@ test_expect_success 'init depot' '
'
# double % for printf
-test_expect_failure 'unsupported view wildcard %%n' '
+test_expect_success 'unsupported view wildcard %%n' '
client_view "//depot/%%%%1/sub/... //client/sub/%%%%1/..." &&
test_when_finished cleanup_git &&
test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
'
-test_expect_failure 'unsupported view wildcard *' '
+test_expect_success 'unsupported view wildcard *' '
client_view "//depot/*/bar/... //client/*/bar/..." &&
test_when_finished cleanup_git &&
test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
--
1.7.8.1.407.gd70cb
^ permalink raw reply related
* [PATCH 3/6] git-p4: sort client views by reverse View number
From: Pete Wyckoff @ 2012-01-02 23:05 UTC (permalink / raw)
To: git; +Cc: Gary Gibbons
In-Reply-To: <1325545554-16540-1-git-send-email-pw@padd.com>
From: Gary Gibbons <ggibbons@perforce.com>
Correct view sorting to support the Perforce order,
where client views are ordered and later views
override earlier view mappings.
[pw: one test now succeeds]
Signed-off-by: Gary Gibbons <ggibbons@perforce.com>
Signed-off-by: Pete Wyckoff <pw@padd.com>
---
contrib/fast-import/git-p4 | 11 +++++++++--
t/t9809-git-p4-client-view.sh | 2 +-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index c144c89..2fd4d3b 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -1924,10 +1924,17 @@ class P4Sync(Command, P4UserMap):
else:
include = len(v)
- temp[v] = (include, cv)
+ # store the View #number for sorting
+ # and the View string itself (this last for documentation)
+ temp[v] = (include, cv, int(k[4:]),k)
self.clientSpecDirs = temp.items()
- self.clientSpecDirs.sort( lambda x, y: abs( y[1][0] ) - abs( x[1][0] ) )
+ # Perforce ViewNN with higher #numbers override those with lower
+ # reverse sort on the View #number
+ self.clientSpecDirs.sort( lambda x, y: y[1][2] - x[1][2] )
+ if self.verbose:
+ for val in self.clientSpecDirs:
+ print "clientSpecDirs: %s %s" % (val[0],val[1])
def run(self, args):
self.depotPaths = []
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index cbf2213..06652cb 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -133,7 +133,7 @@ test_expect_failure 'single file map' '
git_verify $files
'
-test_expect_failure 'later mapping takes precedence (entire repo)' '
+test_expect_success 'later mapping takes precedence (entire repo)' '
client_view "//depot/dir1/... //client/cli1/..." \
"//depot/... //client/cli2/..." &&
files="cli2/dir1/file11 cli2/dir1/file12
--
1.7.8.1.407.gd70cb
^ permalink raw reply related
* [PATCH 4/6] git-p4: support single file p4 client view maps
From: Pete Wyckoff @ 2012-01-02 23:05 UTC (permalink / raw)
To: git; +Cc: Gary Gibbons
In-Reply-To: <1325545554-16540-1-git-send-email-pw@padd.com>
From: Gary Gibbons <ggibbons@perforce.com>
Perforce client views can map individual files,
mapping one //depot file path to one //client file path.
These mappings contain no meta/masking characters.
This patch add support for these file maps to
the currently supported '...' view mappings.
[pw: one test now suceeds]
Signed-off-by: Gary Gibbons <ggibbons@perforce.com>
Signed-off-by: Pete Wyckoff <pw@padd.com>
---
contrib/fast-import/git-p4 | 29 ++++++++++++++++++++---------
t/t9809-git-p4-client-view.sh | 2 +-
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index 2fd4d3b..8f28e0a 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -1217,6 +1217,7 @@ class P4Sync(Command, P4UserMap):
self.cloneExclude = []
self.useClientSpec = False
self.clientSpecDirs = []
+ self.haveSingleFileClientViews = False
if gitConfig("git-p4.syncFromOrigin") == "false":
self.syncWithOrigin = False
@@ -1274,6 +1275,16 @@ class P4Sync(Command, P4UserMap):
# will end up putting all foo/branch files into
# branch/foo/
for val in self.clientSpecDirs:
+ if self.haveSingleFileClientViews and len(path) == abs(val[1][0]) and path == val[0]:
+ # since 'path' is a depot file path, if it matches the LeftMap,
+ # then the View is a single file mapping, so use the entire rightMap
+ # first two tests above avoid the last == test for common cases
+ path = val[1][1]
+ # now strip out the client (//client/...)
+ path = re.sub("^(//[^/]+/)", '', path)
+ # the rest is local client path
+ return path
+
if path.startswith(val[0]):
# replace the depot path with the client path
path = path.replace(val[0], val[1][1])
@@ -1905,19 +1916,19 @@ class P4Sync(Command, P4UserMap):
# save the "client view"; i.e the RHS of the view
# line that tells the client where to put the
# files for this view.
- cv = v[index+3:].strip() # +3 to remove previous '...'
- # if the client view doesn't end with a
- # ... wildcard, then we're going to mess up the
- # output directory, so fail gracefully.
- if not cv.endswith('...'):
- print 'Sorry, client view in "%s" needs to end with wildcard' % (k)
- sys.exit(1)
- cv=cv[:-3]
+ # check for individual file mappings - those which have no '...'
+ if index < 0 :
+ v,cv = v.strip().split()
+ v = v[start:]
+ self.haveSingleFileClientViews = True
+ else:
+ cv = v[index+3:].strip() # +3 to remove previous '...'
+ cv=cv[:-3]
+ v = v[start:index]
# now save the view; +index means included, -index
# means it should be filtered out.
- v = v[start:index]
if v.startswith("-"):
v = v[1:]
include = -len(v)
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 06652cb..1cc83c5 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -191,7 +191,7 @@ test_expect_success 'exclusion wildcard, client rhs different (normal)' '
git_verify $files
'
-test_expect_failure 'exclusion single file' '
+test_expect_success 'exclusion single file' '
client_view "//depot/... //client/..." \
"-//depot/dir2/file22 //client/file22" &&
files="dir1/file11 dir1/file12 dir2/file21" &&
--
1.7.8.1.407.gd70cb
^ permalink raw reply related
* [PATCH 5/6] git-p4: rewrite view handling
From: Pete Wyckoff @ 2012-01-02 23:05 UTC (permalink / raw)
To: git; +Cc: Gary Gibbons
In-Reply-To: <1325545554-16540-1-git-send-email-pw@padd.com>
The old code was not very complete or robust. Redo it.
This new code should be useful for a few possible additions
in the future:
- support for * and %%n wildcards
- allowing ... inside paths
- representing branch specs (not just client specs)
- tracking changes to views
Mark the remaining 12 tests in t9809 as fixed.
Signed-off-by: Pete Wyckoff <pw@padd.com>
---
contrib/fast-import/git-p4 | 335 ++++++++++++++++++++++++++++++-----------
t/t9809-git-p4-client-view.sh | 24 ++--
2 files changed, 258 insertions(+), 101 deletions(-)
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index 8f28e0a..3e1aa27 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -1169,6 +1169,218 @@ class P4Submit(Command, P4UserMap):
return True
+class View(object):
+ """Represent a p4 view ("p4 help views"), and map files in a
+ repo according to the view."""
+
+ class Path(object):
+ """A depot or client path, possibly containing wildcards.
+ The only one supported is ... at the end, currently.
+ Initialize with the full path, with //depot or //client."""
+
+ def __init__(self, path, is_depot):
+ self.path = path
+ self.is_depot = is_depot
+ self.find_wildcards()
+ # remember the prefix bit, useful for relative mappings
+ m = re.match("(//[^/]+/)", self.path)
+ if not m:
+ die("Path %s does not start with //prefix/" % self.path)
+ prefix = m.group(1)
+ if not self.is_depot:
+ # strip //client/ on client paths
+ self.path = self.path[len(prefix):]
+
+ def find_wildcards(self):
+ """Make sure wildcards are valid, and set up internal
+ variables."""
+
+ self.ends_triple_dot = False
+ # There are three wildcards allowed in p4 views
+ # (see "p4 help views"). This code knows how to
+ # handle "..." (only at the end), but cannot deal with
+ # "%%n" or "*". Only check the depot_side, as p4 should
+ # validate that the client_side matches too.
+ if re.search(r'%%[1-9]', self.path):
+ die("Can't handle %%n wildcards in view: %s" % self.path)
+ if self.path.find("*") >= 0:
+ die("Can't handle * wildcards in view: %s" % self.path)
+ triple_dot_index = self.path.find("...")
+ if triple_dot_index >= 0:
+ if not self.path.endswith("..."):
+ die("Can handle ... wildcard only at end of path: %s" %
+ self.path)
+ self.ends_triple_dot = True
+
+ def ensure_compatible(self, other_path):
+ """Make sure the wildcards agree."""
+ if self.ends_triple_dot != other_path.ends_triple_dot:
+ die("Both paths must end with ... if either does;\n" +
+ "paths: %s %s" % (self.path, other_path.path))
+
+ def match_wildcards(self, test_path):
+ """See if this test_path matches us, and fill in the value
+ of the wildcards if so. Returns a tuple of
+ (True|False, wildcards[]). For now, only the ... at end
+ is supported, so at most one wildcard."""
+ if self.ends_triple_dot:
+ dotless = self.path[:-3]
+ if test_path.startswith(dotless):
+ wildcard = test_path[len(dotless):]
+ return (True, [ wildcard ])
+ else:
+ if test_path == self.path:
+ return (True, [])
+ return (False, [])
+
+ def match(self, test_path):
+ """Just return if it matches; don't bother with the wildcards."""
+ b, _ = self.match_wildcards(test_path)
+ return b
+
+ def fill_in_wildcards(self, wildcards):
+ """Return the relative path, with the wildcards filled in
+ if there are any."""
+ if self.ends_triple_dot:
+ return self.path[:-3] + wildcards[0]
+ else:
+ return self.path
+
+ class Mapping(object):
+ def __init__(self, depot_side, client_side, overlay, exclude):
+ # depot_side is without the trailing /... if it had one
+ self.depot_side = View.Path(depot_side, is_depot=True)
+ self.client_side = View.Path(client_side, is_depot=False)
+ self.overlay = overlay # started with "+"
+ self.exclude = exclude # started with "-"
+ assert not (self.overlay and self.exclude)
+ self.depot_side.ensure_compatible(self.client_side)
+
+ def __str__(self):
+ c = " "
+ if self.overlay:
+ c = "+"
+ if self.exclude:
+ c = "-"
+ return "View.Mapping: %s%s -> %s" % \
+ (c, self.depot_side, self.client_side)
+
+ def map_depot_to_client(self, depot_path):
+ """Calculate the client path if using this mapping on the
+ given depot path; does not consider the effect of other
+ mappings in a view. Even excluded mappings are returned."""
+ matches, wildcards = self.depot_side.match_wildcards(depot_path)
+ if not matches:
+ return ""
+ client_path = self.client_side.fill_in_wildcards(wildcards)
+ return client_path
+
+ #
+ # View methods
+ #
+ def __init__(self):
+ self.mappings = []
+
+ def append(self, view_line):
+ """Parse a view line, splitting it into depot and client
+ sides. Append to self.mappings, preserving order."""
+
+ # Split the view line into exactly two words. P4 enforces
+ # structure on these lines that simplifies this quite a bit.
+ #
+ # Either or both words may be double-quoted.
+ # Single quotes do not matter.
+ # Double-quote marks cannot occur inside the words.
+ # A + or - prefix is also inside the quotes.
+ # There are no quotes unless they contain a space.
+ # The line is already white-space stripped.
+ # The two words are separated by a single space.
+ #
+ if view_line[0] == '"':
+ # First word is double quoted. Find its end.
+ close_quote_index = view_line.find('"', 1)
+ if close_quote_index <= 0:
+ die("No first-word closing quote found: %s" % view_line)
+ depot_side = view_line[1:close_quote_index]
+ # skip closing quote and space
+ rhs_index = close_quote_index + 1 + 1
+ else:
+ space_index = view_line.find(" ")
+ if space_index <= 0:
+ die("No word-splitting space found: %s" % view_line)
+ depot_side = view_line[0:space_index]
+ rhs_index = space_index + 1
+
+ if view_line[rhs_index] == '"':
+ # Second word is double quoted. Make sure there is a
+ # double quote at the end too.
+ if not view_line.endswith('"'):
+ die("View line with rhs quote should end with one: %s" %
+ view_line)
+ # skip the quotes
+ client_side = view_line[rhs_index+1:-1]
+ else:
+ client_side = view_line[rhs_index:]
+
+ # prefix + means overlay on previous mapping
+ overlay = False
+ if depot_side.startswith("+"):
+ overlay = True
+ depot_side = depot_side[1:]
+
+ # prefix - means exclude this path
+ exclude = False
+ if depot_side.startswith("-"):
+ exclude = True
+ depot_side = depot_side[1:]
+
+ m = View.Mapping(depot_side, client_side, overlay, exclude)
+ self.mappings.append(m)
+
+ def map_in_client(self, depot_path):
+ """Return the relative location in the client where this
+ depot file should live. Returns "" if the file should
+ not be mapped in the client."""
+
+ paths_filled = []
+ client_path = ""
+
+ # look at later entries first
+ for m in self.mappings[::-1]:
+
+ # see where will this path end up in the client
+ p = m.map_depot_to_client(depot_path)
+
+ if p == "":
+ # Depot path does not belong in client. Must remember
+ # this, as previous items should not cause files to
+ # exist in this path either. Remember that the list is
+ # being walked from the end, which has higher precedence.
+ # Overlap mappings do not exclude previous mappings.
+ if not m.overlay:
+ paths_filled.append(m.client_side)
+
+ else:
+ # This mapping matched; no need to search any further.
+ # But, the mapping could be rejected if the client path
+ # has already been claimed by an earlier mapping.
+ already_mapped_in_client = False
+ for f in paths_filled:
+ # this is View.Path.match
+ if f.match(p):
+ already_mapped_in_client = True
+ break
+ if not already_mapped_in_client:
+ # Include this file, unless it is from a line that
+ # explicitly said to exclude it.
+ if not m.exclude:
+ client_path = p
+
+ # a match, even if rejected, always stops the search
+ break
+
+ return client_path
+
class P4Sync(Command, P4UserMap):
delete_actions = ( "delete", "move/delete", "purge" )
@@ -1216,8 +1428,7 @@ class P4Sync(Command, P4UserMap):
self.p4BranchesInGit = []
self.cloneExclude = []
self.useClientSpec = False
- self.clientSpecDirs = []
- self.haveSingleFileClientViews = False
+ self.clientSpecDirs = None
if gitConfig("git-p4.syncFromOrigin") == "false":
self.syncWithOrigin = False
@@ -1268,30 +1479,7 @@ class P4Sync(Command, P4UserMap):
def stripRepoPath(self, path, prefixes):
if self.useClientSpec:
-
- # if using the client spec, we use the output directory
- # specified in the client. For example, a view
- # //depot/foo/branch/... //client/branch/foo/...
- # will end up putting all foo/branch files into
- # branch/foo/
- for val in self.clientSpecDirs:
- if self.haveSingleFileClientViews and len(path) == abs(val[1][0]) and path == val[0]:
- # since 'path' is a depot file path, if it matches the LeftMap,
- # then the View is a single file mapping, so use the entire rightMap
- # first two tests above avoid the last == test for common cases
- path = val[1][1]
- # now strip out the client (//client/...)
- path = re.sub("^(//[^/]+/)", '', path)
- # the rest is local client path
- return path
-
- if path.startswith(val[0]):
- # replace the depot path with the client path
- path = path.replace(val[0], val[1][1])
- # now strip out the client (//client/...)
- path = re.sub("^(//[^/]+/)", '', path)
- # the rest is all path
- return path
+ return self.clientSpecDirs.map_in_client(path)
if self.keepRepoPath:
prefixes = [re.sub("^(//[^/]+/).*", r'\1', prefixes[0])]
@@ -1441,19 +1629,17 @@ class P4Sync(Command, P4UserMap):
filesToDelete = []
for f in files:
- includeFile = True
- for val in self.clientSpecDirs:
- if f['path'].startswith(val[0]):
- if val[1][0] <= 0:
- includeFile = False
- break
+ # if using a client spec, only add the files that have
+ # a path in the client
+ if self.clientSpecDirs:
+ if self.clientSpecDirs.map_in_client(f['path']) == "":
+ continue
- if includeFile:
- filesForCommit.append(f)
- if f['action'] in self.delete_actions:
- filesToDelete.append(f)
- else:
- filesToRead.append(f)
+ filesForCommit.append(f)
+ if f['action'] in self.delete_actions:
+ filesToDelete.append(f)
+ else:
+ filesToRead.append(f)
# deleted files...
for f in filesToDelete:
@@ -1892,60 +2078,31 @@ class P4Sync(Command, P4UserMap):
def getClientSpec(self):
- specList = p4CmdList( "client -o" )
- temp = {}
- for entry in specList:
- for k,v in entry.iteritems():
- if k.startswith("View"):
-
- # p4 has these %%1 to %%9 arguments in specs to
- # reorder paths; which we can't handle (yet :)
- if re.search('%%\d', v) != None:
- print "Sorry, can't handle %%n arguments in client specs"
- sys.exit(1)
- if re.search('\*', v) != None:
- print "Sorry, can't handle * mappings in client specs"
- sys.exit(1)
-
- if v.startswith('"'):
- start = 1
- else:
- start = 0
- index = v.find("...")
-
- # save the "client view"; i.e the RHS of the view
- # line that tells the client where to put the
- # files for this view.
-
- # check for individual file mappings - those which have no '...'
- if index < 0 :
- v,cv = v.strip().split()
- v = v[start:]
- self.haveSingleFileClientViews = True
- else:
- cv = v[index+3:].strip() # +3 to remove previous '...'
- cv=cv[:-3]
- v = v[start:index]
-
- # now save the view; +index means included, -index
- # means it should be filtered out.
- if v.startswith("-"):
- v = v[1:]
- include = -len(v)
- else:
- include = len(v)
+ specList = p4CmdList("client -o")
+ if len(specList) != 1:
+ die('Output from "client -o" is %d lines, expecting 1' %
+ len(specList))
+
+ # dictionary of all client parameters
+ entry = specList[0]
+
+ # just the keys that start with "View"
+ view_keys = [ k for k in entry.keys() if k.startswith("View") ]
+
+ # hold this new View
+ view = View()
- # store the View #number for sorting
- # and the View string itself (this last for documentation)
- temp[v] = (include, cv, int(k[4:]),k)
+ # append the lines, in order, to the view
+ for view_num in range(len(view_keys)):
+ k = "View%d" % view_num
+ if k not in view_keys:
+ die("Expected view key %s missing" % k)
+ view.append(entry[k])
- self.clientSpecDirs = temp.items()
- # Perforce ViewNN with higher #numbers override those with lower
- # reverse sort on the View #number
- self.clientSpecDirs.sort( lambda x, y: y[1][2] - x[1][2] )
+ self.clientSpecDirs = view
if self.verbose:
- for val in self.clientSpecDirs:
- print "clientSpecDirs: %s %s" % (val[0],val[1])
+ for i, m in enumerate(self.clientSpecDirs.mappings):
+ print "clientSpecDirs %d: %s" % (i, str(m))
def run(self, args):
self.depotPaths = []
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 1cc83c5..c9471d5 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -107,7 +107,7 @@ test_expect_success 'wildcard ... only supported at end of spec' '
test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
'
-test_expect_failure 'basic map' '
+test_expect_success 'basic map' '
client_view "//depot/dir1/... //client/cli1/..." &&
files="cli1/file11 cli1/file12" &&
client_verify $files &&
@@ -116,7 +116,7 @@ test_expect_failure 'basic map' '
git_verify $files
'
-test_expect_failure 'client view with no mappings' '
+test_expect_success 'client view with no mappings' '
client_view &&
client_verify &&
test_when_finished cleanup_git &&
@@ -124,7 +124,7 @@ test_expect_failure 'client view with no mappings' '
git_verify
'
-test_expect_failure 'single file map' '
+test_expect_success 'single file map' '
client_view "//depot/dir1/file11 //client/file11" &&
files="file11" &&
client_verify $files &&
@@ -144,7 +144,7 @@ test_expect_success 'later mapping takes precedence (entire repo)' '
git_verify $files
'
-test_expect_failure 'later mapping takes precedence (partial repo)' '
+test_expect_success 'later mapping takes precedence (partial repo)' '
client_view "//depot/dir1/... //client/..." \
"//depot/dir2/... //client/..." &&
files="file21 file22" &&
@@ -159,7 +159,7 @@ test_expect_failure 'later mapping takes precedence (partial repo)' '
# dir1 cannot go to cli12 since it was filled by dir2
# dir1 also does not go to cli3, since the second rule
# noticed that it matched, but was already filled
-test_expect_failure 'depot path matching rejected client path' '
+test_expect_success 'depot path matching rejected client path' '
client_view "//depot/dir1/... //client/cli3/..." \
"//depot/dir1/... //client/cli12/..." \
"//depot/dir2/... //client/cli12/..." &&
@@ -172,7 +172,7 @@ test_expect_failure 'depot path matching rejected client path' '
# since both have the same //client/..., the exclusion
# rule keeps everything out
-test_expect_failure 'exclusion wildcard, client rhs same (odd)' '
+test_expect_success 'exclusion wildcard, client rhs same (odd)' '
client_view "//depot/... //client/..." \
"-//depot/dir2/... //client/..." &&
client_verify &&
@@ -201,7 +201,7 @@ test_expect_success 'exclusion single file' '
git_verify $files
'
-test_expect_failure 'overlay wildcard' '
+test_expect_success 'overlay wildcard' '
client_view "//depot/dir1/... //client/cli/..." \
"+//depot/dir2/... //client/cli/...\n" &&
files="cli/file11 cli/file12 cli/file21 cli/file22" &&
@@ -211,7 +211,7 @@ test_expect_failure 'overlay wildcard' '
git_verify $files
'
-test_expect_failure 'overlay single file' '
+test_expect_success 'overlay single file' '
client_view "//depot/dir1/... //client/cli/..." \
"+//depot/dir2/file21 //client/cli/file21" &&
files="cli/file11 cli/file12 cli/file21" &&
@@ -221,7 +221,7 @@ test_expect_failure 'overlay single file' '
git_verify $files
'
-test_expect_failure 'exclusion with later inclusion' '
+test_expect_success 'exclusion with later inclusion' '
client_view "//depot/... //client/..." \
"-//depot/dir2/... //client/dir2/..." \
"//depot/dir2/... //client/dir2incl/..." &&
@@ -232,7 +232,7 @@ test_expect_failure 'exclusion with later inclusion' '
git_verify $files
'
-test_expect_failure 'quotes on rhs only' '
+test_expect_success 'quotes on rhs only' '
client_view "//depot/dir1/... \"//client/cdir 1/...\"" &&
client_verify "cdir 1/file11" "cdir 1/file12" &&
test_when_finished cleanup_git &&
@@ -266,7 +266,7 @@ test_expect_success 'rename files to introduce spaces' '
"dir 2/file21" "dir 2/file22"
'
-test_expect_failure 'quotes on lhs only' '
+test_expect_success 'quotes on lhs only' '
client_view "\"//depot/dir 1/...\" //client/cdir1/..." &&
files="cdir1/file11 cdir1/file12" &&
client_verify $files &&
@@ -275,7 +275,7 @@ test_expect_failure 'quotes on lhs only' '
client_verify $files
'
-test_expect_failure 'quotes on both sides' '
+test_expect_success 'quotes on both sides' '
client_view "\"//depot/dir 1/...\" \"//client/cdir 1/...\"" &&
client_verify "cdir 1/file11" "cdir 1/file12" &&
test_when_finished cleanup_git &&
--
1.7.8.1.407.gd70cb
^ permalink raw reply related
* [PATCH 6/6] git-p4: view spec documentation
From: Pete Wyckoff @ 2012-01-02 23:05 UTC (permalink / raw)
To: git; +Cc: Gary Gibbons
In-Reply-To: <1325545554-16540-1-git-send-email-pw@padd.com>
Signed-off-by: Pete Wyckoff <pw@padd.com>
---
Documentation/git-p4.txt | 40 +++++++++++++++++++++++++++-------------
1 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt
index f97b1c5..84f5b91 100644
--- a/Documentation/git-p4.txt
+++ b/Documentation/git-p4.txt
@@ -230,12 +230,7 @@ git repository:
--use-client-spec::
Use a client spec to find the list of interesting files in p4.
- The client spec is discovered using 'p4 client -o' which checks
- the 'P4CLIENT' environment variable and returns a mapping of
- depot files to workspace files. Note that a depot path is
- still required, but files found in the path that match in
- the client spec view will be laid out according to the client
- spec.
+ See the "CLIENT SPEC" section below.
Clone options
~~~~~~~~~~~~~
@@ -304,6 +299,27 @@ p4 revision specifier on the end:
See 'p4 help revisions' for the full syntax of p4 revision specifiers.
+CLIENT SPEC
+-----------
+The p4 client specification is maintained with the 'p4 client' command
+and contains among other fields, a View that specifies how the depot
+is mapped into the client repository. Git-p4 can consult the client
+spec when given the '--use-client-spec' option or useClientSpec
+variable.
+
+The full syntax for a p4 view is documented in 'p4 help views'. Git-p4
+knows only a subset of the view syntax. It understands multi-line
+mappings, overlays with '+', exclusions with '-' and double-quotes
+around whitespace. Of the possible wildcards, git-p4 only handles
+'...', and only when it is at the end of the path. Git-p4 will complain
+if it encounters an unhandled wildcard.
+
+The name of the client can be given to git-p4 in multiple ways. The
+variable 'git-p4.client' takes precedence if it exists. Otherwise,
+normal p4 mechanisms of determining the client are used: environment
+variable P4CLIENT, a file referenced by P4CONFIG, or the local host name.
+
+
BRANCH DETECTION
----------------
P4 does not have the same concept of a branch as git. Instead,
@@ -387,9 +403,7 @@ git-p4.host::
git-p4.client::
Client specified as an option to all p4 commands, with
- '-c <client>'. This can also be used as a way to find
- the client spec for the 'useClientSpec' option.
- The environment variable 'P4CLIENT' can be used instead.
+ '-c <client>', including the client spec.
Clone and sync variables
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -417,10 +431,10 @@ git config --add git-p4.branchList main:branchB
-------------
git-p4.useClientSpec::
- Specify that the p4 client spec to be used to identify p4 depot
- paths of interest. This is equivalent to specifying the option
- '--use-client-spec'. The variable 'git-p4.client' can be used
- to specify the name of the client.
+ Specify that the p4 client spec should be used to identify p4
+ depot paths of interest. This is equivalent to specifying the
+ option '--use-client-spec'. See the "CLIENT SPEC" section above.
+ This variable is a boolean, not the name of a p4 client.
Submit variables
~~~~~~~~~~~~~~~~
--
1.7.8.1.407.gd70cb
^ permalink raw reply related
* Stashing individual files
From: Chris Leong @ 2012-01-02 23:32 UTC (permalink / raw)
To: git
Hi all,
Thanks for making such a wonderful product. I find the stash command
really useful, but it doesn't work very well when I just need to
temporarily revert one or two files. I know that there is the
interactive command, but if you have modified a large number of files,
then it takes quite a bit of effort. Is there any way I can define an
alias, stashfiles, so that I can just type git stashfiles file1 file2?
Also, please consider adding such a feature into a future version.
Thanks,
Chris
^ permalink raw reply
* Git ghost references
From: Chris Leong @ 2012-01-02 23:42 UTC (permalink / raw)
To: git
I seem to have a "ghost reference" - ie. I can check out a reference
that doesn't appear to exist. Does anyone know what might cause this?
~/gaf-cvs (project-membership)$ g show-ref | grep production
~/gaf-cvs (project-membership)$ g gc --prune=now
Counting objects: 117306, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (25270/25270), done.
Writing objects: 100% (117306/117306), done.
Total 117306 (delta 83839), reused 117283 (delta 83820)
~/gaf-cvs (project-membership)$ g co production
Note: checking out 'production'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at ae5b621... Merge branch 'master' of git.freelancer.com:production
~/gaf-cvs ((no branch))$
^ 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