git-p4: add option to keep empty commits
A changelist that contains only excluded files due to a client spec was imported as an empty commit. Fix that issue by ignoring these commits. Add option "git-p4.keepEmptyCommits" to make the previous behavior available. Signed-off-by: Lars Schneider <larsxschneider@gmail.com> Helped-by: Pete Harlan Acked-by: Luke Diamand <luke@diamand.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Lars Schneider committed
Dec 8, 2015 at 10:36 UTC
4ae048e67e5f0d786b9febc438433d95f18e5937
3 files changed
+165
-17
Documentation/git-p4.txt
+4
@@ -510,6 +510,10 @@ git-p4.useClientSpec::
510
option '--use-client-spec'. See the "CLIENT SPEC" section above.
511
This variable is a boolean, not the name of a p4 client.
512
513
+git-p4.keepEmptyCommits::
514
+ A changelist that contains only excluded files will be imported
515
+ as an empty commit if this boolean option is set to true.
516
+
517
Submit variables
518
~~~~~~~~~~~~~~~~
519
git-p4.detectRenames::
git-p4.py
+27
-17
@@ -2235,12 +2235,6 @@ class P4Sync(Command, P4UserMap):
2235
filesToDelete = []
2236
2237
for f in files:
2238
- # if using a client spec, only add the files that have
2239
- # a path in the client
2240
- if self.clientSpecDirs:
2241
- if self.clientSpecDirs.map_in_client(f['path']) == "":
2242
- continue
2243
-
2238
filesForCommit.append(f)
2239
if f['action'] in self.delete_actions:
2240
filesToDelete.append(f)
@@ -2308,25 +2302,41 @@ class P4Sync(Command, P4UserMap):
2302
gitStream.write(description)
2303
gitStream.write("\n")
2304
2305
+ def inClientSpec(self, path):
2306
+ if not self.clientSpecDirs:
2307
+ return True
2308
+ inClientSpec = self.clientSpecDirs.map_in_client(path)
2309
+ if not inClientSpec and self.verbose:
2310
+ print('Ignoring file outside of client spec: {0}'.format(path))
2311
+ return inClientSpec
2312
+
2313
+ def hasBranchPrefix(self, path):
2314
+ if not self.branchPrefixes:
2315
+ return True
2316
+ hasPrefix = [p for p in self.branchPrefixes
2317
+ if p4PathStartsWith(path, p)]
2318
+ if hasPrefix and self.verbose:
2319
+ print('Ignoring file outside of prefix: {0}'.format(path))
2320
+ return hasPrefix
2321
+
2322
def commit(self, details, files, branch, parent = ""):
2323
epoch = details["time"]
2324
author = details["user"]
2325
2326
if self.verbose:
2316
- print "commit into %s" % branch
2317
-
2318
- # start with reading files; if that fails, we should not
2319
- # create a commit.
2320
- new_files = []
2321
- for f in files:
2322
- if [p for p in self.branchPrefixes if p4PathStartsWith(f['path'], p)]:
2323
- new_files.append (f)
2324
- else:
2325
- sys.stderr.write("Ignoring file outside of prefix: %s\n" % f['path'])
2327
+ print('commit into {0}'.format(branch))
2328
2329
if self.clientSpecDirs:
2330
self.clientSpecDirs.update_client_spec_path_cache(files)
2331
2332
+ files = [f for f in files
2333
+ if self.inClientSpec(f['path']) and self.hasBranchPrefix(f['path'])]
2334
+
2335
+ if not files and not gitConfigBool('git-p4.keepEmptyCommits'):
2336
+ print('Ignoring revision {0} as it would produce an empty commit.'
2337
+ .format(details['change']))
2338
+ return
2339
+
2340
self.gitStream.write("commit %s\n" % branch)
2341
# gitStream.write("mark :%s\n" % details["change"])
2342
self.committedChanges.add(int(details["change"]))
@@ -2350,7 +2360,7 @@ class P4Sync(Command, P4UserMap):
2360
print "parent %s" % parent
2361
self.gitStream.write("from %s\n" % parent)
2362
2353
- self.streamP4Files(new_files)
2363
+ self.streamP4Files(files)
2364
self.gitStream.write("\n")
2365
2366
change = int(details["change"])
t/t9826-git-p4-keep-empty-commits.sh
new
+134
@@ -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