20

I generated a patch some time ago using the p4 diff command.

However, now that I want to apply it, I realize that there is no way to apply a patch in Perforce.

Since I did not use the -du option, the patch is in that obscure perforce format and can't be applied with patch(1). The original changes have been lost. Also, that patch is over 300kb long so manual editing isn't really an option.

What are my options ? Are there patch converters, or some Perforce extension allowing the application of these kind of patchs ?

slaphappy
  • 6,894
  • 3
  • 34
  • 59
  • 2
    Related : http://stackoverflow.com/questions/8289306/perforce-diff-to-git – slaphappy Feb 24 '12 at 11:00
  • 1
    you can probably convert with sed. this is also the rough format from gnu diff, so there is probably some reasonable tooling out there, keep hope alive friend. – wowest Oct 17 '12 at 15:45
  • I'm trying to apply a patch saved by [`p4 describe -du`](https://www.perforce.com/perforce/doc.current/manuals/cmdref/p4_describe.html). It gives an error with the unix patch command "Only garbage was found in the patch input." – Colonel Panic Oct 18 '16 at 14:55

3 Answers3

10

Perhaps Perforce's diff output format has changed, but @RumburaK's answer didn't work for me.

I had to modify it to convert the ==== header to diff's +++ and --- header format.

sed -Ee 's|==== (//.*)#[0-9]+(.*)|+++ \1\n--- \1|' < infile.txt > outfile.txt

infile.txt was generated with the following command (where 12335 was a shelved changelist): p4 describe -du -S 12345

outfile.txt was applied with the following command: patch -p3 -l < outfile.txt

Jason Spangler
  • 111
  • 1
  • 6
  • The GNU sed equivalent of `-E` is `-r` (but GNU sed accepts `-E` without documenting it) – Bulletmagnet Aug 18 '17 at 13:53
  • You also need to 'cut off the head' of the describe output. I do this: `p4 describe -du -S | sed -Ee 's|==== //(.*)#[0-9]+(.*)|+++ \1\n--- \1|' | awk '/^+++ /{f=1}f'` – TTimo Apr 06 '23 at 16:14
3

Just found your question after saving some of my changes in a patch and reverting them in order to test some of the original code...

Assuming you're using a decent terminal emulator, this one time operation could take you up to an hour or so.

The good thing is that you can't run into this on a daily basis, as you probably will now use "-du" from now on, at least me I'm sure I will. Just copy and paste the file name as prompted:

$ patch -i cucu.diff 
can't find file to patch at input line 2
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|==== //depot/foo/boo.cpp#1 - /home/who/perforce/foo/boo.cpp ====
--------------------------
File to patch: 

<double-click!> to copy
<middle-click!> to paste

File to patch: /home/who/perforce/foo/boo.cpp <CR>

Perhaps you will have 100 files in the patch... keep clicking :-)

If you're looking for a subst expression (vim, sed):

s/.* - \(.*\) ====/+++: \1/

But - beware if you added sources (whole files, p4 add) their content probably won't be printed in the diff - in which case nobody will be able to re-patch them in...

RumburaK
  • 1,985
  • 1
  • 21
  • 30
1

Another answer:The p4 diff2 command supports a -u flag to generate diffs in GNU diff format.

From p4 help diff2:

The -u flag uses the GNU diff -u format and displays only files that differ. The file names and dates are in Perforce syntax, but the output can be used by the patch program.

Jason Spangler
  • 111
  • 1
  • 6
  • This solution would seem to work only when comparing two files that are in the repository. How can I get a GNU patch for the diff between my working file and the one in the repository? – Arch D. Robison Sep 15 '16 at 18:32
  • p4 diff supports a unified diff option, ```-du[n] (unified)``` for working vs repository file diffs, but it isn't fully in GNU diff -u format. In the past, I've used it and then edited the diff output to make it work with GNU patch. – Jason Spangler Sep 17 '16 at 18:12