Skip to content

Commit a899d50

Browse files
committed
Merge branch 'ls/p4-keep-empty-commits'
"git p4" used to import Perforce CLs that touch only paths outside the client spec as empty commits. It has been corrected to ignore them instead, with a new configuration git-p4.keepEmptyCommits as a backward compatibility knob. * ls/p4-keep-empty-commits: git-p4: add option to keep empty commits
2 parents 897b185 + 4ae048e commit a899d50

File tree

3 files changed

+165
-17
lines changed

3 files changed

+165
-17
lines changed

Documentation/git-p4.txt

+4
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,10 @@ git-p4.largeFilePush::
549549
Boolean variable which defines if large files are automatically
550550
pushed to a server.
551551

552+
git-p4.keepEmptyCommits::
553+
A changelist that contains only excluded files will be imported
554+
as an empty commit if this boolean option is set to true.
555+
552556
Submit variables
553557
~~~~~~~~~~~~~~~~
554558
git-p4.detectRenames::

git-p4.py

+27-17
Original file line numberDiff line numberDiff line change
@@ -2556,12 +2556,6 @@ def streamP4Files(self, files):
25562556
filesToDelete = []
25572557

25582558
for f in files:
2559-
# if using a client spec, only add the files that have
2560-
# a path in the client
2561-
if self.clientSpecDirs:
2562-
if self.clientSpecDirs.map_in_client(f['path']) == "":
2563-
continue
2564-
25652559
filesForCommit.append(f)
25662560
if f['action'] in self.delete_actions:
25672561
filesToDelete.append(f)
@@ -2632,25 +2626,41 @@ def streamTag(self, gitStream, labelName, labelDetails, commit, epoch):
26322626
gitStream.write(description)
26332627
gitStream.write("\n")
26342628

2629+
def inClientSpec(self, path):
2630+
if not self.clientSpecDirs:
2631+
return True
2632+
inClientSpec = self.clientSpecDirs.map_in_client(path)
2633+
if not inClientSpec and self.verbose:
2634+
print('Ignoring file outside of client spec: {0}'.format(path))
2635+
return inClientSpec
2636+
2637+
def hasBranchPrefix(self, path):
2638+
if not self.branchPrefixes:
2639+
return True
2640+
hasPrefix = [p for p in self.branchPrefixes
2641+
if p4PathStartsWith(path, p)]
2642+
if hasPrefix and self.verbose:
2643+
print('Ignoring file outside of prefix: {0}'.format(path))
2644+
return hasPrefix
2645+
26352646
def commit(self, details, files, branch, parent = ""):
26362647
epoch = details["time"]
26372648
author = details["user"]
26382649

26392650
if self.verbose:
2640-
print "commit into %s" % branch
2641-
2642-
# start with reading files; if that fails, we should not
2643-
# create a commit.
2644-
new_files = []
2645-
for f in files:
2646-
if [p for p in self.branchPrefixes if p4PathStartsWith(f['path'], p)]:
2647-
new_files.append (f)
2648-
else:
2649-
sys.stderr.write("Ignoring file outside of prefix: %s\n" % f['path'])
2651+
print('commit into {0}'.format(branch))
26502652

26512653
if self.clientSpecDirs:
26522654
self.clientSpecDirs.update_client_spec_path_cache(files)
26532655

2656+
files = [f for f in files
2657+
if self.inClientSpec(f['path']) and self.hasBranchPrefix(f['path'])]
2658+
2659+
if not files and not gitConfigBool('git-p4.keepEmptyCommits'):
2660+
print('Ignoring revision {0} as it would produce an empty commit.'
2661+
.format(details['change']))
2662+
return
2663+
26542664
self.gitStream.write("commit %s\n" % branch)
26552665
self.gitStream.write("mark :%s\n" % details["change"])
26562666
self.committedChanges.add(int(details["change"]))
@@ -2674,7 +2684,7 @@ def commit(self, details, files, branch, parent = ""):
26742684
print "parent %s" % parent
26752685
self.gitStream.write("from %s\n" % parent)
26762686

2677-
self.streamP4Files(new_files)
2687+
self.streamP4Files(files)
26782688
self.gitStream.write("\n")
26792689

26802690
change = int(details["change"])

t/t9826-git-p4-keep-empty-commits.sh

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#!/bin/sh
2+
3+
test_description='Clone repositories and keep empty commits'
4+
5+
. ./lib-git-p4.sh
6+
7+
test_expect_success 'start p4d' '
8+
start_p4d
9+
'
10+
11+
test_expect_success 'Create a repo' '
12+
client_view "//depot/... //client/..." &&
13+
(
14+
cd "$cli" &&
15+
16+
mkdir -p subdir &&
17+
18+
>subdir/file1.txt &&
19+
p4 add subdir/file1.txt &&
20+
p4 submit -d "Add file 1" &&
21+
22+
>file2.txt &&
23+
p4 add file2.txt &&
24+
p4 submit -d "Add file 2" &&
25+
26+
>subdir/file3.txt &&
27+
p4 add subdir/file3.txt &&
28+
p4 submit -d "Add file 3" &&
29+
30+
>file4.txt &&
31+
p4 add file4.txt &&
32+
p4 submit -d "Add file 4" &&
33+
34+
p4 delete subdir/file3.txt &&
35+
p4 submit -d "Remove file 3" &&
36+
37+
p4 delete file4.txt &&
38+
p4 submit -d "Remove file 4"
39+
)
40+
'
41+
42+
test_expect_success 'Clone repo root path with all history' '
43+
client_view "//depot/... //client/..." &&
44+
test_when_finished cleanup_git &&
45+
(
46+
cd "$git" &&
47+
git init . &&
48+
git p4 clone --use-client-spec --destination="$git" //depot@all &&
49+
cat >expect <<-\EOF &&
50+
Remove file 4
51+
[git-p4: depot-paths = "//depot/": change = 6]
52+
53+
Remove file 3
54+
[git-p4: depot-paths = "//depot/": change = 5]
55+
56+
Add file 4
57+
[git-p4: depot-paths = "//depot/": change = 4]
58+
59+
Add file 3
60+
[git-p4: depot-paths = "//depot/": change = 3]
61+
62+
Add file 2
63+
[git-p4: depot-paths = "//depot/": change = 2]
64+
65+
Add file 1
66+
[git-p4: depot-paths = "//depot/": change = 1]
67+
68+
EOF
69+
git log --format=%B >actual &&
70+
test_cmp expect actual
71+
)
72+
'
73+
74+
test_expect_success 'Clone repo subdir with all history but keep empty commits' '
75+
client_view "//depot/subdir/... //client/subdir/..." &&
76+
test_when_finished cleanup_git &&
77+
(
78+
cd "$git" &&
79+
git init . &&
80+
git config git-p4.keepEmptyCommits true &&
81+
git p4 clone --use-client-spec --destination="$git" //depot@all &&
82+
cat >expect <<-\EOF &&
83+
Remove file 4
84+
[git-p4: depot-paths = "//depot/": change = 6]
85+
86+
Remove file 3
87+
[git-p4: depot-paths = "//depot/": change = 5]
88+
89+
Add file 4
90+
[git-p4: depot-paths = "//depot/": change = 4]
91+
92+
Add file 3
93+
[git-p4: depot-paths = "//depot/": change = 3]
94+
95+
Add file 2
96+
[git-p4: depot-paths = "//depot/": change = 2]
97+
98+
Add file 1
99+
[git-p4: depot-paths = "//depot/": change = 1]
100+
101+
EOF
102+
git log --format=%B >actual &&
103+
test_cmp expect actual
104+
)
105+
'
106+
107+
test_expect_success 'Clone repo subdir with all history' '
108+
client_view "//depot/subdir/... //client/subdir/..." &&
109+
test_when_finished cleanup_git &&
110+
(
111+
cd "$git" &&
112+
git init . &&
113+
git p4 clone --use-client-spec --destination="$git" --verbose //depot@all &&
114+
cat >expect <<-\EOF &&
115+
Remove file 3
116+
[git-p4: depot-paths = "//depot/": change = 5]
117+
118+
Add file 3
119+
[git-p4: depot-paths = "//depot/": change = 3]
120+
121+
Add file 1
122+
[git-p4: depot-paths = "//depot/": change = 1]
123+
124+
EOF
125+
git log --format=%B >actual &&
126+
test_cmp expect actual
127+
)
128+
'
129+
130+
test_expect_success 'kill p4d' '
131+
kill_p4d
132+
'
133+
134+
test_done

0 commit comments

Comments
 (0)