I'm attempting to use git-p4 under Cygwin. The "clone" and "rebase" parts of the workflow appear to be working correctly, but I am unable to "submit". I'm guessing it may have something to do with a line-ending convention. I've looked at this git-p4 issue and its linked items, but manipulations of line-ending and whitespace configuration are so far unsuccessful. Items of note in my configuration:
(1) I'm using the bash shell function trick to get paths to work correctly:
$ type p4
p4 is a function
p4 ()
{
P4=`which p4`;
PWD=$(cygpath -wa .) "${P4}" "$@"
}
(2) I've tried all settings for git's autocrlf
value -- result is failure regardless of (true,false,input). Currently attempting "false" as that makes the most sense when diff-ing against the depot.
(3) I've also played with the p4 clientspec's lineend values; currently attempting "unix", b/c of Cygwin and the P4 sandbox server running under OSX.
The test is simple. The repo contains one file, foo1. The depot version looks like (output using od -c
):
0000000 f o o 1 \n \n
0000006
The locally-git-committed version looks like:
0000000 f o o 1 i s t h e o n e !
0000020 \n \n
0000022
I've added some additional diagnostic output to the applyCommit()
method in git-p4. That in conjunction with running submit using --verbose:
$ git p4 submit --verbose
Reading pipe: git name-rev HEAD
Reading pipe: ['git', 'config', 'git-p4.allowSubmit']
Reading pipe: git rev-parse --symbolic --remotes
Reading pipe: git rev-parse p4/master
Reading pipe: git cat-file commit ce414288d1b5d52dbad20c1a29f1875cfff7c281
Reading pipe: git cat-file commit HEAD~0
Reading pipe: git cat-file commit HEAD~1
Reading pipe: ['git', 'config', 'git-p4.conflict']
Origin branch is remotes/p4/master
Reading pipe: ['git', 'config', '--bool', 'git-p4.useclientspec']
Opening pipe: ['p4', '-G', 'where', '//depot/foo/...']
Perforce checkout for depot path //depot/foo/ located at c:\git\foo\
Synchronizing p4 checkout...
... - file(s) up-to-date.
Opening pipe: p4 -G opened ...
Reading pipe: ['git', 'rev-list', '--no-merges', 'remotes/p4/master..master']
Reading pipe: ['git', 'config', '--bool', 'git-p4.skipUserNameCheck']
Reading pipe: ['git', 'config', 'git-p4.detectRenames']
Reading pipe: ['git', 'config', 'git-p4.detectCopies']
Reading pipe: ['git', 'config', '--bool', 'git-p4.detectCopiesHarder']
Reading pipe: ['git', 'show', '-s', '--format=format:%h %s', '2303176ae8c575313616ae2c4a35358258742598']
Applying 2303176 updating foo1
Opening pipe: p4 -G users
Reading pipe: ['git', 'log', '--max-count=1', '--format=%ae', '2303176ae8c575313616ae2c4a35358258742598']
Reading pipe: git diff-tree -r "2303176ae8c575313616ae2c4a35358258742598^" "2303176ae8c575313616ae2c4a35358258742598"
//depot/foo/foo1#1 - opened for edit
Sanity: git diff-tree --full-index -p "2303176ae8c575313616ae2c4a35358258742598" | git apply --verbose --check -
Checking patch foo1...
error: while searching for:
foo1
error: patch failed: foo1:1
error: foo1: patch does not apply
Unfortunately applying the change failed!
Reading pipe: ['git', 'config', '--bool', 'git-p4.attemptRCSCleanup']
//depot/foo/foo1#1 - was edit, reverted
Note the "Sanity:" diagnostic line. This is the value of tryPatchCmd
that fails within the applyCommit()
method. If I execute the first part of the statement at the bash command line, I see:
2303176ae8c575313616ae2c4a35358258742598
diff --git a/foo1 b/foo1
index 630baf44b0874b3319c2814399f0b03106912183..4c23e4512b3347ec31068e464b64cbd99851cc9a 100644
--- a/foo1
+++ b/foo1
@@ -1,2 +1,2 @@
-foo1
+foo1 is the one!
Piping this to the second part of the command results in no error. I am perplexed as to why the command fails when executed using os.system()
in the Python script but succeeds otherwise. Thoughts?
I believe I've solved this. The problem was two-fold. First cardinal sin -- not reading the manual carefully. The documentation in the Submit section states:
Submitting changes from a Git repository back to the p4 repository requires a separate p4 client workspace. This should be specified using the P4CLIENT environment variable or the Git configuration variable git-p4.client. The p4 client must exist, but the client root will be created and populated if it does not already exist.
It took some time to get this through my head that this actually meant two physical working copies -- one for git, one for p4. The git-p4 script was choking on trying to perform git and p4 operations in the same folder, and such in-place operations don't play well with Perforce's checkout model. I discovered this by performing the same test workflow on a Mac, which errored [more clearly] with "cannot clobber writable file". By twiddling "clobber" in the p4 clientspec I was able to get the submit in both Mac and Cygwin to work, and that put me on the right trail.
There's a detailed walkthrough on setting up the dual workspace structure at this Perforce page.
Second: interestingly, I still appear to require --ignore-whitespace
as part of the git apply
logic in the Cygwin environment. That's a git-p4
hack I am willing to live with.