Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 9d7d446

Browse files
Pete Wyckoffgitster
authored andcommitted
git p4: submit files with wildcards
There are four wildcard characters in p4. Files with these characters can be added to p4 repos using the "-f" option. They are stored in %xx notation, and when checked out, p4 converts them back to normal. When adding files with wildcards in git, the submit path must be careful to use the encoded names in some places, and it must use "-f" to add them. All other p4 commands that operate on the client directory expect encoded filenames as arguments. Support for wildcards in the clone/sync path was added in 084f630 (git-p4: decode p4 wildcard characters, 2011-02-19), but that change did not handle the submit path. There was a problem with wildcards in the sync path too. Commit 084f630 (git-p4: decode p4 wildcard characters, 2011-02-19) handled files with p4 wildcards that were added or modified in p4. Do this for deleted files, and also in branch detection checks, too. Reported-by: Luke Diamand <[email protected]> Signed-off-by: Pete Wyckoff <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b6ad6dc commit 9d7d446

File tree

3 files changed

+185
-28
lines changed

3 files changed

+185
-28
lines changed

git-p4.py

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -133,25 +133,29 @@ def p4_system(cmd):
133133
subprocess.check_call(real_cmd, shell=expand)
134134

135135
def p4_integrate(src, dest):
136-
p4_system(["integrate", "-Dt", src, dest])
136+
p4_system(["integrate", "-Dt", wildcard_encode(src), wildcard_encode(dest)])
137137

138138
def p4_sync(f, *options):
139-
p4_system(["sync"] + list(options) + [f])
139+
p4_system(["sync"] + list(options) + [wildcard_encode(f)])
140140

141141
def p4_add(f):
142-
p4_system(["add", f])
142+
# forcibly add file names with wildcards
143+
if wildcard_present(f):
144+
p4_system(["add", "-f", f])
145+
else:
146+
p4_system(["add", f])
143147

144148
def p4_delete(f):
145-
p4_system(["delete", f])
149+
p4_system(["delete", wildcard_encode(f)])
146150

147151
def p4_edit(f):
148-
p4_system(["edit", f])
152+
p4_system(["edit", wildcard_encode(f)])
149153

150154
def p4_revert(f):
151-
p4_system(["revert", f])
155+
p4_system(["revert", wildcard_encode(f)])
152156

153-
def p4_reopen(type, file):
154-
p4_system(["reopen", "-t", type, file])
157+
def p4_reopen(type, f):
158+
p4_system(["reopen", "-t", type, wildcard_encode(f)])
155159

156160
#
157161
# Canonicalize the p4 type and return a tuple of the
@@ -248,7 +252,7 @@ def setP4ExecBit(file, mode):
248252
def getP4OpenedType(file):
249253
# Returns the perforce file type for the given file.
250254

251-
result = p4_read_pipe(["opened", file])
255+
result = p4_read_pipe(["opened", wildcard_encode(file)])
252256
match = re.match(".*\((.+)\)\r?$", result)
253257
if match:
254258
return match.group(1)
@@ -658,6 +662,34 @@ def getClientRoot():
658662

659663
return entry["Root"]
660664

665+
#
666+
# P4 wildcards are not allowed in filenames. P4 complains
667+
# if you simply add them, but you can force it with "-f", in
668+
# which case it translates them into %xx encoding internally.
669+
#
670+
def wildcard_decode(path):
671+
# Search for and fix just these four characters. Do % last so
672+
# that fixing it does not inadvertently create new %-escapes.
673+
# Cannot have * in a filename in windows; untested as to
674+
# what p4 would do in such a case.
675+
if not platform.system() == "Windows":
676+
path = path.replace("%2A", "*")
677+
path = path.replace("%23", "#") \
678+
.replace("%40", "@") \
679+
.replace("%25", "%")
680+
return path
681+
682+
def wildcard_encode(path):
683+
# do % first to avoid double-encoding the %s introduced here
684+
path = path.replace("%", "%25") \
685+
.replace("*", "%2A") \
686+
.replace("#", "%23") \
687+
.replace("@", "%40")
688+
return path
689+
690+
def wildcard_present(path):
691+
return path.translate(None, "*#@%") != path
692+
661693
class Command:
662694
def __init__(self):
663695
self.usage = "usage: %prog [options]"
@@ -1187,7 +1219,8 @@ def applyCommit(self, id):
11871219
del(os.environ["P4DIFF"])
11881220
diff = ""
11891221
for editedFile in editedFiles:
1190-
diff += p4_read_pipe(['diff', '-du', editedFile])
1222+
diff += p4_read_pipe(['diff', '-du',
1223+
wildcard_encode(editedFile)])
11911224

11921225
newdiff = ""
11931226
for newFile in filesToAdd:
@@ -1697,23 +1730,6 @@ def __init__(self):
16971730
if gitConfig("git-p4.syncFromOrigin") == "false":
16981731
self.syncWithOrigin = False
16991732

1700-
#
1701-
# P4 wildcards are not allowed in filenames. P4 complains
1702-
# if you simply add them, but you can force it with "-f", in
1703-
# which case it translates them into %xx encoding internally.
1704-
# Search for and fix just these four characters. Do % last so
1705-
# that fixing it does not inadvertently create new %-escapes.
1706-
#
1707-
def wildcard_decode(self, path):
1708-
# Cannot have * in a filename in windows; untested as to
1709-
# what p4 would do in such a case.
1710-
if not self.isWindows:
1711-
path = path.replace("%2A", "*")
1712-
path = path.replace("%23", "#") \
1713-
.replace("%40", "@") \
1714-
.replace("%25", "%")
1715-
return path
1716-
17171733
# Force a checkpoint in fast-import and wait for it to finish
17181734
def checkpoint(self):
17191735
self.gitStream.write("checkpoint\n\n")
@@ -1781,6 +1797,7 @@ def splitFilesIntoBranches(self, commit):
17811797
fnum = fnum + 1
17821798

17831799
relPath = self.stripRepoPath(path, self.depotPaths)
1800+
relPath = wildcard_decode(relPath)
17841801

17851802
for branch in self.knownBranches.keys():
17861803

@@ -1798,7 +1815,7 @@ def splitFilesIntoBranches(self, commit):
17981815

17991816
def streamOneP4File(self, file, contents):
18001817
relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)
1801-
relPath = self.wildcard_decode(relPath)
1818+
relPath = wildcard_decode(relPath)
18021819
if verbose:
18031820
sys.stderr.write("%s\n" % relPath)
18041821

@@ -1867,6 +1884,7 @@ def streamOneP4File(self, file, contents):
18671884

18681885
def streamOneP4Deletion(self, file):
18691886
relPath = self.stripRepoPath(file['path'], self.branchPrefixes)
1887+
relPath = wildcard_decode(relPath)
18701888
if verbose:
18711889
sys.stderr.write("delete %s\n" % relPath)
18721890
self.gitStream.write("D %s\n" % relPath)

t/t9800-git-p4-basic.sh

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,112 @@ test_expect_success 'wildcard files git p4 clone' '
163163
)
164164
'
165165

166+
test_expect_success 'wildcard files submit back to p4, add' '
167+
test_when_finished cleanup_git &&
168+
git p4 clone --dest="$git" //depot &&
169+
(
170+
cd "$git" &&
171+
echo git-wild-hash >git-wild#hash &&
172+
echo git-wild-star >git-wild\*star &&
173+
echo git-wild-at >git-wild@at &&
174+
echo git-wild-percent >git-wild%percent &&
175+
git add git-wild* &&
176+
git commit -m "add some wildcard filenames" &&
177+
git config git-p4.skipSubmitEdit true &&
178+
git p4 submit
179+
) &&
180+
(
181+
cd "$cli" &&
182+
test_path_is_file git-wild#hash &&
183+
test_path_is_file git-wild\*star &&
184+
test_path_is_file git-wild@at &&
185+
test_path_is_file git-wild%percent
186+
)
187+
'
188+
189+
test_expect_success 'wildcard files submit back to p4, modify' '
190+
test_when_finished cleanup_git &&
191+
git p4 clone --dest="$git" //depot &&
192+
(
193+
cd "$git" &&
194+
echo new-line >>git-wild#hash &&
195+
echo new-line >>git-wild\*star &&
196+
echo new-line >>git-wild@at &&
197+
echo new-line >>git-wild%percent &&
198+
git add git-wild* &&
199+
git commit -m "modify the wildcard files" &&
200+
git config git-p4.skipSubmitEdit true &&
201+
git p4 submit
202+
) &&
203+
(
204+
cd "$cli" &&
205+
test_line_count = 2 git-wild#hash &&
206+
test_line_count = 2 git-wild\*star &&
207+
test_line_count = 2 git-wild@at &&
208+
test_line_count = 2 git-wild%percent
209+
)
210+
'
211+
212+
test_expect_success 'wildcard files submit back to p4, copy' '
213+
test_when_finished cleanup_git &&
214+
git p4 clone --dest="$git" //depot &&
215+
(
216+
cd "$git" &&
217+
cp file2 git-wild-cp#hash &&
218+
git add git-wild-cp#hash &&
219+
cp git-wild\*star file-wild-3 &&
220+
git add file-wild-3 &&
221+
git commit -m "wildcard copies" &&
222+
git config git-p4.detectCopies true &&
223+
git config git-p4.detectCopiesHarder true &&
224+
git config git-p4.skipSubmitEdit true &&
225+
git p4 submit
226+
) &&
227+
(
228+
cd "$cli" &&
229+
test_path_is_file git-wild-cp#hash &&
230+
test_path_is_file file-wild-3
231+
)
232+
'
233+
234+
test_expect_success 'wildcard files submit back to p4, rename' '
235+
test_when_finished cleanup_git &&
236+
git p4 clone --dest="$git" //depot &&
237+
(
238+
cd "$git" &&
239+
git mv git-wild@at file-wild-4 &&
240+
git mv file-wild-3 git-wild-cp%percent &&
241+
git commit -m "wildcard renames" &&
242+
git config git-p4.detectRenames true &&
243+
git config git-p4.skipSubmitEdit true &&
244+
git p4 submit
245+
) &&
246+
(
247+
cd "$cli" &&
248+
test_path_is_missing git-wild@at &&
249+
test_path_is_file git-wild-cp%percent
250+
)
251+
'
252+
253+
test_expect_success 'wildcard files submit back to p4, delete' '
254+
test_when_finished cleanup_git &&
255+
git p4 clone --dest="$git" //depot &&
256+
(
257+
cd "$git" &&
258+
git rm git-wild* &&
259+
git commit -m "delete the wildcard files" &&
260+
git config git-p4.skipSubmitEdit true &&
261+
git p4 submit
262+
) &&
263+
(
264+
cd "$cli" &&
265+
test_path_is_missing git-wild#hash &&
266+
test_path_is_missing git-wild\*star &&
267+
test_path_is_missing git-wild@at &&
268+
test_path_is_missing git-wild%percent
269+
)
270+
'
271+
166272
test_expect_success 'clone bare' '
167273
git p4 clone --dest="$git" --bare //depot &&
168274
test_when_finished cleanup_git &&

t/t9809-git-p4-client-view.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,39 @@ test_expect_success 'subdir clone, submit rename' '
374374
)
375375
'
376376

377+
# see t9800 for the non-client-spec case, and the rest of the wildcard tests
378+
test_expect_success 'wildcard files submit back to p4, client-spec case' '
379+
client_view "//depot/... //client/..." &&
380+
test_when_finished cleanup_git &&
381+
git p4 clone --use-client-spec --dest="$git" //depot/dir1 &&
382+
(
383+
cd "$git" &&
384+
echo git-wild-hash >dir1/git-wild#hash &&
385+
echo git-wild-star >dir1/git-wild\*star &&
386+
echo git-wild-at >dir1/git-wild@at &&
387+
echo git-wild-percent >dir1/git-wild%percent &&
388+
git add dir1/git-wild* &&
389+
git commit -m "add some wildcard filenames" &&
390+
git config git-p4.skipSubmitEditCheck true &&
391+
git p4 submit
392+
) &&
393+
(
394+
cd "$cli" &&
395+
test_path_is_file dir1/git-wild#hash &&
396+
test_path_is_file dir1/git-wild\*star &&
397+
test_path_is_file dir1/git-wild@at &&
398+
test_path_is_file dir1/git-wild%percent
399+
) &&
400+
(
401+
# delete these carefully, cannot just do "p4 delete"
402+
# on files with wildcards; but git-p4 knows how
403+
cd "$git" &&
404+
git rm dir1/git-wild* &&
405+
git commit -m "clean up the wildcards" &&
406+
git p4 submit
407+
)
408+
'
409+
377410
test_expect_success 'reinit depot' '
378411
(
379412
cd "$cli" &&

0 commit comments

Comments
 (0)