@@ -11,113 +11,99 @@ commit_message() {
11
11
git log --pretty=format:%s -1 " $1 "
12
12
}
13
13
14
+ # There are a few bugs in the rebase with regards to the subtree strategy, and
15
+ # this test script tries to document them. First, the following commit history
16
+ # is generated (the onelines are shown, time flows from left to right):
17
+ #
18
+ # master1 - master2 - master3
19
+ # \
20
+ # README ---------------------- Add subproject master - master4 - files_subtree/master5
21
+ #
22
+ # Where the merge moves the files master[123].t into the subdirectory
23
+ # files_subtree/ and master4 as well as files_subtree/master5 add files to that
24
+ # directory directly.
25
+ #
26
+ # Then, in subsequent test cases, `git filter-branch` is used to distill just
27
+ # the commits that touch files_subtree/. To give it a final pre-rebase touch,
28
+ # an empty commit is added on top. The pre-rebase commit history looks like
29
+ # this:
30
+ #
31
+ # Add subproject master - master4 - files_subtree/master5 - Empty commit
32
+ #
33
+ # where the root commit adds three files: master1.t, master2.t and master3.t.
34
+ #
35
+ # This commit history is then rebased onto `master3` with the
36
+ # `-Xsubtree=files_subtree` option in three different ways:
37
+ #
38
+ # 1. using `--preserve-merges`
39
+ # 2. using `--preserve-merges` and --keep-empty
40
+ # 3. without specifying a rebase backend
41
+
14
42
test_expect_success ' setup' '
15
43
test_commit README &&
16
- mkdir files &&
17
- (
18
- cd files &&
19
- git init &&
20
- test_commit master1 &&
21
- test_commit master2 &&
22
- test_commit master3
23
- ) &&
24
- git fetch files master &&
25
- git branch files-master FETCH_HEAD &&
26
- git read-tree --prefix=files_subtree files-master &&
27
- git checkout -- files_subtree &&
28
- tree=$(git write-tree) &&
29
- head=$(git rev-parse HEAD) &&
30
- rev=$(git rev-parse --verify files-master^0) &&
31
- commit=$(git commit-tree -p $head -p $rev -m "Add subproject master" $tree) &&
32
- git update-ref HEAD $commit &&
33
- (
34
- cd files_subtree &&
35
- test_commit master4
36
- ) &&
37
- test_commit files_subtree/master5
38
- '
39
44
40
- # FAILURE: Does not preserve master4.
41
- test_expect_failure REBASE_P \
42
- ' Rebase -Xsubtree --preserve-merges --onto commit 4' '
43
- reset_rebase &&
44
- git checkout -b rebase-preserve-merges-4 master &&
45
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
46
- git commit -m "Empty commit" --allow-empty &&
47
- git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&
48
- verbose test "$(commit_message HEAD~)" = "files_subtree/master4"
45
+ git init files &&
46
+ test_commit -C files master1 &&
47
+ test_commit -C files master2 &&
48
+ test_commit -C files master3 &&
49
+
50
+ : perform subtree merge into files_subtree/ &&
51
+ git fetch files refs/heads/master:refs/heads/files-master &&
52
+ git merge -s ours --no-commit --allow-unrelated-histories \
53
+ files-master &&
54
+ git read-tree --prefix=files_subtree -u files-master &&
55
+ git commit -m "Add subproject master" &&
56
+
57
+ : add two extra commits to rebase &&
58
+ test_commit -C files_subtree master4 &&
59
+ test_commit files_subtree/master5 &&
60
+
61
+ git checkout -b to-rebase &&
62
+ git fast-export --no-data HEAD -- files_subtree/ |
63
+ sed -e "s%\([0-9a-f]\{40\} \)files_subtree/%\1%" |
64
+ git fast-import --force --quiet &&
65
+ git reset --hard &&
66
+ git commit -m "Empty commit" --allow-empty
49
67
'
50
68
51
- # FAILURE: Does not preserve master5.
52
- test_expect_failure REBASE_P \
53
- ' Rebase -Xsubtree --preserve-merges --onto commit 5' '
69
+ # FAILURE: Does not preserve master4.
70
+ test_expect_failure REBASE_P ' Rebase -Xsubtree --preserve-merges --onto commit' '
54
71
reset_rebase &&
55
- git checkout -b rebase-preserve-merges-5 master &&
56
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
57
- git commit -m "Empty commit" --allow-empty &&
72
+ git checkout -b rebase-preserve-merges to-rebase &&
58
73
git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&
74
+ verbose test "$(commit_message HEAD~)" = "master4" &&
59
75
verbose test "$(commit_message HEAD)" = "files_subtree/master5"
60
76
'
61
77
62
78
# FAILURE: Does not preserve master4.
63
- test_expect_failure REBASE_P \
64
- ' Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' '
65
- reset_rebase &&
66
- git checkout -b rebase-keep-empty-4 master &&
67
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
68
- git commit -m "Empty commit" --allow-empty &&
69
- git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
70
- verbose test "$(commit_message HEAD~2)" = "files_subtree/master4"
71
- '
72
-
73
- # FAILURE: Does not preserve master5.
74
- test_expect_failure REBASE_P \
75
- ' Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' '
76
- reset_rebase &&
77
- git checkout -b rebase-keep-empty-5 master &&
78
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
79
- git commit -m "Empty commit" --allow-empty &&
80
- git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
81
- verbose test "$(commit_message HEAD~)" = "files_subtree/master5"
82
- '
83
-
84
- # FAILURE: Does not preserve Empty.
85
- test_expect_failure REBASE_P \
86
- ' Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' '
79
+ test_expect_failure REBASE_P ' Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '
87
80
reset_rebase &&
88
- git checkout -b rebase-keep-empty-empty master &&
89
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
90
- git commit -m "Empty commit" --allow-empty &&
81
+ git checkout -b rebase-keep-empty to-rebase &&
91
82
git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
83
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
84
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
92
85
verbose test "$(commit_message HEAD)" = "Empty commit"
93
86
'
94
87
95
- # FAILURE: fatal: Could not parse object
96
- test_expect_failure ' Rebase -Xsubtree --onto commit 4' '
88
+ test_expect_success ' Rebase -Xsubtree --keep-empty --onto commit' '
97
89
reset_rebase &&
98
- git checkout -b rebase-onto-4 master &&
99
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
100
- git commit -m "Empty commit" --allow-empty &&
101
- git rebase -Xsubtree=files_subtree --onto files-master master &&
102
- verbose test "$(commit_message HEAD~2)" = "files_subtree/master4"
90
+ git checkout -b rebase-onto to-rebase &&
91
+ test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --onto files-master master &&
92
+ : first pick results in no changes &&
93
+ git rebase --continue &&
94
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
95
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
96
+ verbose test "$(commit_message HEAD)" = "Empty commit"
103
97
'
104
98
105
- # FAILURE: fatal: Could not parse object
106
- test_expect_failure ' Rebase -Xsubtree --onto commit 5' '
107
- reset_rebase &&
108
- git checkout -b rebase-onto-5 master &&
109
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
110
- git commit -m "Empty commit" --allow-empty &&
111
- git rebase -Xsubtree=files_subtree --onto files-master master &&
112
- verbose test "$(commit_message HEAD~)" = "files_subtree/master5"
113
- '
114
- # FAILURE: fatal: Could not parse object
115
- test_expect_failure ' Rebase -Xsubtree --onto empty commit' '
99
+ test_expect_success ' Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' '
116
100
reset_rebase &&
117
- git checkout -b rebase-onto-empty master &&
118
- git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
119
- git commit -m "Empty commit" --allow-empty &&
120
- git rebase -Xsubtree=files_subtree --onto files-master master &&
101
+ git checkout -b rebase-merges-onto to-rebase &&
102
+ test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root &&
103
+ : first pick results in no changes &&
104
+ git rebase --continue &&
105
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
106
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
121
107
verbose test "$(commit_message HEAD)" = "Empty commit"
122
108
'
123
109
0 commit comments