Commit 2270ca9f8feecf93fe39a02a6fbde90a22c1a665

David Turner 2017-03-03T13:27:47

rebase: ignore untracked files in submodules An untracked file in a submodule should not prevent a rebase from starting. Even if the submodule's SHA is changed, and that file would conflict with a new tracked file, it's still OK to start the rebase and discover the conflict later. Signed-off-by: David Turner <dturner@twosigma.com>

diff --git a/src/rebase.c b/src/rebase.c
index 09941a2..bf1d086 100644
--- a/src/rebase.c
+++ b/src/rebase.c
@@ -546,7 +546,9 @@ static int rebase_ensure_not_dirty(
 	}
 
 	if (check_workdir) {
-		if ((error = git_diff_index_to_workdir(&diff, repo, index, NULL)) < 0)
+		git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
+		diff_opts.ignore_submodules = GIT_SUBMODULE_IGNORE_UNTRACKED;
+		if ((error = git_diff_index_to_workdir(&diff, repo, index, &diff_opts)) < 0)
 			goto done;
 
 		if (git_diff_num_deltas(diff) > 0) {
diff --git a/tests/rebase/submodule.c b/tests/rebase/submodule.c
new file mode 100644
index 0000000..7a38ab8
--- /dev/null
+++ b/tests/rebase/submodule.c
@@ -0,0 +1,65 @@
+#include "clar_libgit2.h"
+#include "git2/checkout.h"
+#include "git2/rebase.h"
+#include "posix.h"
+#include "signature.h"
+
+#include <fcntl.h>
+
+static git_repository *repo;
+static git_signature *signature;
+
+// Fixture setup and teardown
+void test_rebase_submodule__initialize(void)
+{
+	repo = cl_git_sandbox_init("rebase-submodule");
+	cl_git_pass(git_signature_new(&signature,
+		"Rebaser", "rebaser@rebaser.rb", 1405694510, 0));
+}
+
+void test_rebase_submodule__cleanup(void)
+{
+	git_signature_free(signature);
+	cl_git_sandbox_cleanup();
+}
+
+void test_rebase_submodule__init_untracked(void)
+{
+	git_rebase *rebase;
+	git_reference *branch_ref, *upstream_ref;
+	git_annotated_commit *branch_head, *upstream_head;
+	git_buf untracked_path = GIT_BUF_INIT;
+	FILE *fp;
+	git_submodule *submodule;
+	git_config *config;
+
+	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/asparagus"));
+	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
+
+	cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref));
+	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));
+
+	git_repository_config(&config, repo);
+
+	cl_git_pass(git_config_set_string(config, "submodule.my-submodule.url", git_repository_path(repo)));
+
+	git_config_free(config);
+
+	cl_git_pass(git_submodule_lookup(&submodule, repo, "my-submodule"));
+	cl_git_pass(git_submodule_update(submodule, 1, NULL));
+
+	git_buf_printf(&untracked_path, "%s/my-submodule/untracked", git_repository_workdir(repo));
+	fp = fopen(git_buf_cstr(&untracked_path), "w");
+	fprintf(fp, "An untracked file in a submodule should not block a rebase\n");
+	fclose(fp);
+	git_buf_free(&untracked_path);
+
+	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));
+
+	git_submodule_free(submodule);
+	git_annotated_commit_free(branch_head);
+	git_annotated_commit_free(upstream_head);
+	git_reference_free(branch_ref);
+	git_reference_free(upstream_ref);
+	git_rebase_free(rebase);
+}
diff --git a/tests/resources/rebase-submodule/.gitmodules b/tests/resources/rebase-submodule/.gitmodules
new file mode 100644
index 0000000..f36de77
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "my-submodule"]
+	path = my-submodule
+	url = bogus
diff --git a/tests/resources/rebase-submodule/.gitted/HEAD b/tests/resources/rebase-submodule/.gitted/HEAD
new file mode 100644
index 0000000..cb089cd
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/tests/resources/rebase-submodule/.gitted/ORIG_HEAD b/tests/resources/rebase-submodule/.gitted/ORIG_HEAD
new file mode 100644
index 0000000..a1ccbb4
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/ORIG_HEAD
@@ -0,0 +1 @@
+5fdf086684daae0a8bc61a81afe178edc1e556e7
diff --git a/tests/resources/rebase-submodule/.gitted/config b/tests/resources/rebase-submodule/.gitted/config
new file mode 100644
index 0000000..af2095f
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/config
@@ -0,0 +1,9 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+[branch "asparagus"]
+	rebase = true
+[branch "master"]
+	rebase = true
diff --git a/tests/resources/rebase-submodule/.gitted/description b/tests/resources/rebase-submodule/.gitted/description
new file mode 100644
index 0000000..498b267
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
diff --git a/tests/resources/rebase-submodule/.gitted/index b/tests/resources/rebase-submodule/.gitted/index
new file mode 100644
index 0000000..b63efab
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/index differ
diff --git a/tests/resources/rebase-submodule/.gitted/info/exclude b/tests/resources/rebase-submodule/.gitted/info/exclude
new file mode 100644
index 0000000..a5196d1
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/tests/resources/rebase-submodule/.gitted/info/refs b/tests/resources/rebase-submodule/.gitted/info/refs
new file mode 100644
index 0000000..230a649
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/info/refs
@@ -0,0 +1,4 @@
+c64ea52df5b31efd7b73769418dc9e25b8803d25	refs/heads/asparagus
+c64ea52df5b31efd7b73769418dc9e25b8803d25	refs/remotes/origin/HEAD
+c64ea52df5b31efd7b73769418dc9e25b8803d25	refs/remotes/origin/asparagus
+02a35db3f24db554b757b3009bc782784267c743	refs/remotes/origin/master
diff --git a/tests/resources/rebase-submodule/.gitted/objects/01/971e2453a407e4b9f6c865e2c37f4db21da294 b/tests/resources/rebase-submodule/.gitted/objects/01/971e2453a407e4b9f6c865e2c37f4db21da294
new file mode 100644
index 0000000..308b386
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/objects/01/971e2453a407e4b9f6c865e2c37f4db21da294
@@ -0,0 +1 @@
+xUAj0Юu@Xfd%4Rj"t|>ZA[o)G2R1䠭 qbth&Bԗoi?M<"Z̨ELdY\cڒsu`dhO]K}_XO;E<[(U{R1J
\ No newline at end of file
diff --git a/tests/resources/rebase-submodule/.gitted/objects/17/f8ae8ebdd08a4bb272f61b897b308ad42b1b12 b/tests/resources/rebase-submodule/.gitted/objects/17/f8ae8ebdd08a4bb272f61b897b308ad42b1b12
new file mode 100644
index 0000000..79e4c48
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/objects/17/f8ae8ebdd08a4bb272f61b897b308ad42b1b12
@@ -0,0 +1 @@
+x-Kn0D)xMȢYvP'jqXt@=3p0qFeҤv&"[^;HHzb6Sq3*1zGmpK|=.yGw:Ǻ"
*CNel:eO.Uϵ9mփ5De$+xo}RC
\ No newline at end of file
diff --git a/tests/resources/rebase-submodule/.gitted/objects/42/cdad903aef3e7b614675e6584a8be417941911 b/tests/resources/rebase-submodule/.gitted/objects/42/cdad903aef3e7b614675e6584a8be417941911
new file mode 100644
index 0000000..99b5e6d
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/42/cdad903aef3e7b614675e6584a8be417941911 differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/4b/7c5650008b2e747fe1809eeb5a1dde0e80850a b/tests/resources/rebase-submodule/.gitted/objects/4b/7c5650008b2e747fe1809eeb5a1dde0e80850a
new file mode 100644
index 0000000..0163985
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/4b/7c5650008b2e747fe1809eeb5a1dde0e80850a differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/5b/1e8bccf7787e942aecf61912f94a2c274f85a5 b/tests/resources/rebase-submodule/.gitted/objects/5b/1e8bccf7787e942aecf61912f94a2c274f85a5
new file mode 100644
index 0000000..d4776d8
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/5b/1e8bccf7787e942aecf61912f94a2c274f85a5 differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/68/af1fc7407fd9addf1701a87eb1c95c7494c598 b/tests/resources/rebase-submodule/.gitted/objects/68/af1fc7407fd9addf1701a87eb1c95c7494c598
new file mode 100644
index 0000000..6aaf79f
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/68/af1fc7407fd9addf1701a87eb1c95c7494c598 differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/68/f6182f4c85d39e1309d97c7e456156dc9c0096 b/tests/resources/rebase-submodule/.gitted/objects/68/f6182f4c85d39e1309d97c7e456156dc9c0096
new file mode 100644
index 0000000..ed1de3a
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/68/f6182f4c85d39e1309d97c7e456156dc9c0096 differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/7c/71f7606bd3bfb25d063c970804e7fc00b9605b b/tests/resources/rebase-submodule/.gitted/objects/7c/71f7606bd3bfb25d063c970804e7fc00b9605b
new file mode 100644
index 0000000..ef923e7
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/7c/71f7606bd3bfb25d063c970804e7fc00b9605b differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/7c/7bf85e978f1d18c0566f702d2cb7766b9c8d4f b/tests/resources/rebase-submodule/.gitted/objects/7c/7bf85e978f1d18c0566f702d2cb7766b9c8d4f
new file mode 100644
index 0000000..fe8b157
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/objects/7c/7bf85e978f1d18c0566f702d2cb7766b9c8d4f
@@ -0,0 +1 @@
+xN0Dd'	\V\~/1rw5m|0tntƺ%kcnua:K,^W55<i:q^33qe\ ӝKR
&ڡȶJ,Nי#|VhNwDžԙԺ{Y}RYa)
\ No newline at end of file
diff --git a/tests/resources/rebase-submodule/.gitted/objects/a7/b066537e6be7109abfe4ff97b675d4e077da20 b/tests/resources/rebase-submodule/.gitted/objects/a7/b066537e6be7109abfe4ff97b675d4e077da20
new file mode 100644
index 0000000..54f9b66
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/a7/b066537e6be7109abfe4ff97b675d4e077da20 differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/ab/6cf22b4c67a274aa8d31b5877d92341e8c2a9c b/tests/resources/rebase-submodule/.gitted/objects/ab/6cf22b4c67a274aa8d31b5877d92341e8c2a9c
new file mode 100644
index 0000000..5acdf36
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/ab/6cf22b4c67a274aa8d31b5877d92341e8c2a9c differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/c4/e6cca3ec6ae0148ed231f97257df8c311e015f b/tests/resources/rebase-submodule/.gitted/objects/c4/e6cca3ec6ae0148ed231f97257df8c311e015f
new file mode 100644
index 0000000..2bbf28f
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/objects/c4/e6cca3ec6ae0148ed231f97257df8c311e015f
@@ -0,0 +1 @@
+x%P1n0WCNEN7:*pԒ/WmI$=^^._?~|C6yTȄA(#1e鴓.(Hto@̸K-as1r6)&)8ŷTa<0ׇJ٢[K5IJcq͓쌫r_ۇ"u^@7~X)2	G,fR`B43vQH֩uab SwcJq)fƔOv;
\ No newline at end of file
diff --git a/tests/resources/rebase-submodule/.gitted/objects/f3/6de77de6f53dddafeb024ecaf375e45c3d9ddd b/tests/resources/rebase-submodule/.gitted/objects/f3/6de77de6f53dddafeb024ecaf375e45c3d9ddd
new file mode 100644
index 0000000..cd330a7
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/f3/6de77de6f53dddafeb024ecaf375e45c3d9ddd differ
diff --git a/tests/resources/rebase-submodule/.gitted/objects/ff/b36e513f5fdf8a6ba850a20142676a2ac4807d b/tests/resources/rebase-submodule/.gitted/objects/ff/b36e513f5fdf8a6ba850a20142676a2ac4807d
new file mode 100644
index 0000000..f655d12
Binary files /dev/null and b/tests/resources/rebase-submodule/.gitted/objects/ff/b36e513f5fdf8a6ba850a20142676a2ac4807d differ
diff --git a/tests/resources/rebase-submodule/.gitted/packed-refs b/tests/resources/rebase-submodule/.gitted/packed-refs
new file mode 100644
index 0000000..44ac842
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled fully-peeled 
+c64ea52df5b31efd7b73769418dc9e25b8803d25 refs/heads/asparagus
diff --git a/tests/resources/rebase-submodule/.gitted/refs/heads/asparagus b/tests/resources/rebase-submodule/.gitted/refs/heads/asparagus
new file mode 100644
index 0000000..e6adde8
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/refs/heads/asparagus
@@ -0,0 +1 @@
+17f8ae8ebdd08a4bb272f61b897b308ad42b1b12
diff --git a/tests/resources/rebase-submodule/.gitted/refs/heads/master b/tests/resources/rebase-submodule/.gitted/refs/heads/master
new file mode 100644
index 0000000..2523d49
--- /dev/null
+++ b/tests/resources/rebase-submodule/.gitted/refs/heads/master
@@ -0,0 +1 @@
+01971e2453a407e4b9f6c865e2c37f4db21da294
diff --git a/tests/resources/rebase-submodule/asparagus.txt b/tests/resources/rebase-submodule/asparagus.txt
new file mode 100644
index 0000000..ffb36e5
--- /dev/null
+++ b/tests/resources/rebase-submodule/asparagus.txt
@@ -0,0 +1,10 @@
+ASPARAGUS SOUP.
+
+Take four large bunches of asparagus, scrape it nicely, cut off one inch
+of the tops, and lay them in water, chop the stalks and put them on the
+fire with a piece of bacon, a large onion cut up, and pepper and salt;
+add two quarts of water, boil them till the stalks are quite soft, then
+pulp them through a sieve, and strain the water to it, which must be put
+back in the pot; put into it a chicken cut up, with the tops of
+asparagus which had been laid by, boil it until these last articles are
+sufficiently done, thicken with flour, butter and milk, and serve it up.
diff --git a/tests/resources/rebase-submodule/beef.txt b/tests/resources/rebase-submodule/beef.txt
new file mode 100644
index 0000000..68f6182
--- /dev/null
+++ b/tests/resources/rebase-submodule/beef.txt
@@ -0,0 +1,22 @@
+BEEF SOUP.
+
+Take the hind shin of beef, cut off all the flesh off the leg-bone,
+which must be taken away entirely, or the soup will be greasy. Wash the
+meat clean and lay it in a pot, sprinkle over it one small
+table-spoonful of pounded black pepper, and two of salt; three onions
+the size of a hen's egg, cut small, six small carrots scraped and cut
+up, two small turnips pared and cut into dice; pour on three quarts of
+water, cover the pot close, and keep it gently and steadily boiling five
+hours, which will leave about three pints of clear soup; do not let the
+pot boil over, but take off the scum carefully, as it rises. When it has
+boiled four hours, put in a small bundle of thyme and parsley, and a
+pint of celery cut small, or a tea-spoonful of celery seed pounded.
+These latter ingredients would lose their delicate flavour if boiled too
+much. Just before you take it up, brown it in the following manner: put
+a small table-spoonful of nice brown sugar into an iron skillet, set it
+on the fire and stir it till it melts and looks very dark, pour into it
+a ladle full of the soup, a little at a time; stirring it all the while.
+Strain this browning and mix it well with the soup; take out the bundle
+of thyme and parsley, put the nicest pieces of meat in your tureen, and
+pour on the soup and vegetables; put in some toasted bread cut in dice,
+and serve it up.
diff --git a/tests/resources/rebase-submodule/bouilli.txt b/tests/resources/rebase-submodule/bouilli.txt
new file mode 100644
index 0000000..4b7c565
--- /dev/null
+++ b/tests/resources/rebase-submodule/bouilli.txt
@@ -0,0 +1,18 @@
+SOUP WITH BOUILLI.
+
+Take the nicest part of the thick brisket of beef, about eight pounds,
+put it into a pot with every thing directed for the other soup; make it
+exactly in the same way, only put it on an hour sooner, that you may
+have time to prepare the bouilli; after it has boiled five hours, take
+out the beef, cover up the soup and set it near the fire that it may
+keep hot. Take the skin off the beef, have the yelk of an egg well
+beaten, dip a feather in it and wash the top of your beef, sprinkle over
+it the crumb of stale bread finely grated, put it in a Dutch oven
+previously heated, put the top on with coals enough to brown, but not
+burn the beef; let it stand nearly an hour, and prepare your gravy
+thus:--Take a sufficient quantity of soup and the vegetables boiled in
+it; add to it a table-spoonful of red wine, and two of mushroom catsup,
+thicken with a little bit of butter and a little brown flour; make it
+very hot, pour it in your dish, and put the beef on it. Garnish it with
+green pickle, cut in thin slices, serve up the soup in a tureen with
+bits of toasted bread.
diff --git a/tests/resources/rebase-submodule/gravy.txt b/tests/resources/rebase-submodule/gravy.txt
new file mode 100644
index 0000000..c4e6cca
--- /dev/null
+++ b/tests/resources/rebase-submodule/gravy.txt
@@ -0,0 +1,8 @@
+GRAVY SOUP.
+
+Get eight pounds of coarse lean beef--wash it clean and lay it in your
+pot, put in the same ingredients as for the shin soup, with the same
+quantity of water, and follow the process directed for that. Strain the
+soup through a sieve, and serve it up clear, with nothing more than
+toasted bread in it; two table-spoonsful of mushroom catsup will add a
+fine flavour to the soup.
diff --git a/tests/resources/rebase-submodule/my-submodule b/tests/resources/rebase-submodule/my-submodule
new file mode 160000
index 0000000..efad0b1
--- /dev/null
+++ b/tests/resources/rebase-submodule/my-submodule
@@ -0,0 +1 @@
+Subproject commit efad0b11c47cb2f0220cbd6f5b0f93bb99064b00
diff --git a/tests/resources/rebase-submodule/oyster.txt b/tests/resources/rebase-submodule/oyster.txt
new file mode 100644
index 0000000..68af1fc
--- /dev/null
+++ b/tests/resources/rebase-submodule/oyster.txt
@@ -0,0 +1,13 @@
+OYSTER SOUP.
+
+Wash and drain two quarts of oysters, put them on with three quarts of
+water, three onions chopped up, two or three slices of lean ham, pepper
+and salt; boil it till reduced one-half, strain it through a sieve,
+return the liquid into the pot, put in one quart of fresh oysters, boil
+it till they are sufficiently done, and thicken the soup with four
+spoonsful of flour, two gills of rich cream, and the yelks of six new
+laid eggs beaten well; boil it a few minutes after the thickening is put
+in. Take care that it does not curdle, and that the flour is not in
+lumps; serve it up with the last oysters that were put in. If the
+flavour of thyme be agreeable, you may put in a little, but take care
+that it does not boil in it long enough to discolour the soup.
diff --git a/tests/resources/rebase-submodule/veal.txt b/tests/resources/rebase-submodule/veal.txt
new file mode 100644
index 0000000..a7b0665
--- /dev/null
+++ b/tests/resources/rebase-submodule/veal.txt
@@ -0,0 +1,18 @@
+VEAL SOUP.
+
+Put into a pot three quarts of water, three onions cut small, one
+spoonful of black pepper pounded, and two of salt, with two or three
+slices of lean ham; let it boil steadily two hours; skim it
+occasionally, then put into it a shin of veal, let it boil two hours
+longer; take out the slices of ham, and skim off the grease if any
+should rise, take a gill of good cream, mix with it two table-spoonsful
+of flour very nicely, and the yelks of two eggs beaten well, strain this
+mixture, and add some chopped parsley; pour some soup on by degrees,
+stir it well, and pour it into the pot, continuing to stir until it has
+boiled two or three minutes to take off the raw taste of the eggs. If
+the cream be not perfectly sweet, and the eggs quite new, the thickening
+will curdle in the soup. For a change you may put a dozen ripe tomatos
+in, first taking off their skins, by letting them stand a few minutes in
+hot water, when they may be easily peeled. When made in this way you
+must thicken it with the flour only. Any part of the veal may be used,
+but the shin or knuckle is the nicest.