Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit afc5124

Browse files
authored
Merge pull request libgit2#4539 from pks-t/pks/diff_renames_with_rewrites
diff_tform: fix rename detection with rewrite/delete pair
2 parents 952cf71 + ce7080a commit afc5124

9 files changed

+255
-20
lines changed

src/diff_tform.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,10 @@ static bool is_rename_target(
686686
break;
687687
}
688688
if (FLAG_SET(opts, GIT_DIFF_FIND_RENAMES_FROM_REWRITES) &&
689-
delta->similarity < opts->rename_from_rewrite_threshold)
689+
delta->similarity < opts->rename_from_rewrite_threshold) {
690+
delta->flags |= GIT_DIFF_FLAG__TO_SPLIT;
690691
break;
692+
}
691693

692694
return false;
693695

tests/diff/rename.c

Lines changed: 249 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ void test_diff_rename__cleanup(void)
1616
cl_git_sandbox_cleanup();
1717
}
1818

19+
#define INITIAL_COMMIT "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2"
20+
#define COPY_RENAME_COMMIT "2bc7f351d20b53f1c72c16c4b036e491c478c49a"
21+
#define REWRITE_COPY_COMMIT "1c068dee5790ef1580cfc4cd670915b48d790084"
22+
#define RENAME_MODIFICATION_COMMIT "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13"
23+
#define REWRITE_DELETE_COMMIT "84d8efa38af7ace2b302de0adbda16b1f1cd2e1b"
24+
#define DELETE_RENAME_COMMIT "be053a189b0bbde545e0a3f59ce00b46ad29ce0d"
25+
1926
/*
2027
* Renames repo has:
2128
*
@@ -36,12 +43,22 @@ void test_diff_rename__cleanup(void)
3643
* ikeepsix.txt -> ikeepsix.txt (reorder sections in file)
3744
* sixserving.txt -> sixserving.txt (whitespace change - not just indent)
3845
* sevencities.txt -> songof7cities.txt (rename, small text changes)
46+
* commit 84d8efa38af7ace2b302de0adbda16b1f1cd2e1b
47+
* songof7cities.txt -> songof7citie.txt (major rewrite, <20% match)
48+
* ikeepsix.txt -> (deleted)
49+
* untimely.txt (no change)
50+
* sixserving.txt (no change)
51+
* commit be053a189b0bbde545e0a3f59ce00b46ad29ce0d
52+
* ikeepsix.txt -> (deleted)
53+
* songof7cities.txt -> ikeepsix.txt (rename, 100% match)
54+
* untimely.txt (no change)
55+
* sixserving.txt (no change)
3956
*/
4057

4158
void test_diff_rename__match_oid(void)
4259
{
43-
const char *old_sha = "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2";
44-
const char *new_sha = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
60+
const char *old_sha = INITIAL_COMMIT;
61+
const char *new_sha = COPY_RENAME_COMMIT;
4562
git_tree *old_tree, *new_tree;
4663
git_diff *diff;
4764
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
@@ -139,8 +156,8 @@ void test_diff_rename__match_oid(void)
139156

140157
void test_diff_rename__checks_options_version(void)
141158
{
142-
const char *old_sha = "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2";
143-
const char *new_sha = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
159+
const char *old_sha = INITIAL_COMMIT;
160+
const char *new_sha = COPY_RENAME_COMMIT;
144161
git_tree *old_tree, *new_tree;
145162
git_diff *diff;
146163
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
@@ -171,9 +188,9 @@ void test_diff_rename__checks_options_version(void)
171188

172189
void test_diff_rename__not_exact_match(void)
173190
{
174-
const char *sha0 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
175-
const char *sha1 = "1c068dee5790ef1580cfc4cd670915b48d790084";
176-
const char *sha2 = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13";
191+
const char *sha0 = COPY_RENAME_COMMIT;
192+
const char *sha1 = REWRITE_COPY_COMMIT;
193+
const char *sha2 = RENAME_MODIFICATION_COMMIT;
177194
git_tree *old_tree, *new_tree;
178195
git_diff *diff;
179196
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
@@ -433,7 +450,7 @@ void test_diff_rename__test_small_files(void)
433450

434451
void test_diff_rename__working_directory_changes(void)
435452
{
436-
const char *sha0 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
453+
const char *sha0 = COPY_RENAME_COMMIT;
437454
const char *blobsha = "66311f5cfbe7836c27510a3ba2f43e282e2c8bba";
438455
git_oid id;
439456
git_tree *tree;
@@ -592,8 +609,8 @@ void test_diff_rename__working_directory_changes(void)
592609

593610
void test_diff_rename__patch(void)
594611
{
595-
const char *sha0 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
596-
const char *sha1 = "1c068dee5790ef1580cfc4cd670915b48d790084";
612+
const char *sha0 = COPY_RENAME_COMMIT;
613+
const char *sha1 = REWRITE_COPY_COMMIT;
597614
git_tree *old_tree, *new_tree;
598615
git_diff *diff;
599616
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
@@ -1425,9 +1442,9 @@ void test_diff_rename__can_delete_unmodified_deltas(void)
14251442

14261443
void test_diff_rename__matches_config_behavior(void)
14271444
{
1428-
const char *sha0 = "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2";
1429-
const char *sha1 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
1430-
const char *sha2 = "1c068dee5790ef1580cfc4cd670915b48d790084";
1445+
const char *sha0 = INITIAL_COMMIT;
1446+
const char *sha1 = COPY_RENAME_COMMIT;
1447+
const char *sha2 = REWRITE_COPY_COMMIT;
14311448

14321449
git_tree *tree0, *tree1, *tree2;
14331450
git_config *cfg;
@@ -1508,8 +1525,8 @@ void test_diff_rename__matches_config_behavior(void)
15081525

15091526
void test_diff_rename__can_override_thresholds_when_obeying_config(void)
15101527
{
1511-
const char *sha1 = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
1512-
const char *sha2 = "1c068dee5790ef1580cfc4cd670915b48d790084";
1528+
const char *sha1 = COPY_RENAME_COMMIT;
1529+
const char *sha2 = REWRITE_COPY_COMMIT;
15131530

15141531
git_tree *tree1, *tree2;
15151532
git_config *cfg;
@@ -1563,8 +1580,8 @@ void test_diff_rename__can_override_thresholds_when_obeying_config(void)
15631580

15641581
void test_diff_rename__by_config_doesnt_mess_with_whitespace_settings(void)
15651582
{
1566-
const char *sha1 = "1c068dee5790ef1580cfc4cd670915b48d790084";
1567-
const char *sha2 = "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13";
1583+
const char *sha1 = REWRITE_COPY_COMMIT;
1584+
const char *sha2 = RENAME_MODIFICATION_COMMIT;
15681585

15691586
git_tree *tree1, *tree2;
15701587
git_config *cfg;
@@ -1710,8 +1727,8 @@ void test_diff_rename__blank_files_not_renamed_when_not_ignoring_whitespace(void
17101727
*/
17111728
void test_diff_rename__identical(void)
17121729
{
1713-
const char *old_sha = "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2";
1714-
const char *new_sha = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
1730+
const char *old_sha = INITIAL_COMMIT;
1731+
const char *new_sha = COPY_RENAME_COMMIT;
17151732
git_tree *old_tree, *new_tree;
17161733
git_diff *diff;
17171734
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
@@ -1748,3 +1765,216 @@ void test_diff_rename__identical(void)
17481765
git_tree_free(new_tree);
17491766
}
17501767

1768+
void test_diff_rename__rewrite_and_delete(void)
1769+
{
1770+
const char *old_sha = RENAME_MODIFICATION_COMMIT;
1771+
const char *new_sha = REWRITE_DELETE_COMMIT;
1772+
git_tree *old_tree, *new_tree;
1773+
git_diff *diff;
1774+
git_diff_find_options find_opts = GIT_DIFF_FIND_OPTIONS_INIT;
1775+
git_buf diff_buf = GIT_BUF_INIT;
1776+
const char *expected =
1777+
"diff --git a/ikeepsix.txt b/ikeepsix.txt\n"
1778+
"deleted file mode 100644\n"
1779+
"index eaf4a3e..0000000\n"
1780+
"--- a/ikeepsix.txt\n"
1781+
"+++ /dev/null\n"
1782+
"@@ -1,27 +0,0 @@\n"
1783+
"-I Keep Six Honest Serving-Men\n"
1784+
"-=============================\n"
1785+
"-\n"
1786+
"-She sends'em abroad on her own affairs,\n"
1787+
"- From the second she opens her eyes—\n"
1788+
"-One million Hows, two million Wheres,\n"
1789+
"-And seven million Whys!\n"
1790+
"-\n"
1791+
"-I let them rest from nine till five,\n"
1792+
"- For I am busy then,\n"
1793+
"-As well as breakfast, lunch, and tea,\n"
1794+
"- For they are hungry men.\n"
1795+
"-But different folk have different views;\n"
1796+
"-I know a person small—\n"
1797+
"-She keeps ten million serving-men,\n"
1798+
"-Who get no rest at all!\n"
1799+
"-\n"
1800+
"- -- Rudyard Kipling\n"
1801+
"-\n"
1802+
"-I KEEP six honest serving-men\n"
1803+
"- (They taught me all I knew);\n"
1804+
"-Their names are What and Why and When\n"
1805+
"- And How and Where and Who.\n"
1806+
"-I send them over land and sea,\n"
1807+
"- I send them east and west;\n"
1808+
"-But after they have worked for me,\n"
1809+
"- I give them all a rest.\n"
1810+
"diff --git a/songof7cities.txt b/songof7cities.txt\n"
1811+
"index 4210ffd..95ceb12 100644\n"
1812+
"--- a/songof7cities.txt\n"
1813+
"+++ b/songof7cities.txt\n"
1814+
"@@ -1,45 +1,45 @@\n"
1815+
"-The Song of Seven Cities\n"
1816+
"+THE SONG OF SEVEN CITIES\n"
1817+
" ------------------------\n"
1818+
" \n"
1819+
"-I WAS Lord of Cities very sumptuously builded.\n"
1820+
"-Seven roaring Cities paid me tribute from afar.\n"
1821+
"-Ivory their outposts were--the guardrooms of them gilded,\n"
1822+
"-And garrisoned with Amazons invincible in war.\n"
1823+
"-\n"
1824+
"-All the world went softly when it walked before my Cities--\n"
1825+
"-Neither King nor Army vexed my peoples at their toil,\n"
1826+
"-Never horse nor chariot irked or overbore my Cities,\n"
1827+
"-Never Mob nor Ruler questioned whence they drew their spoil.\n"
1828+
"-\n"
1829+
"-Banded, mailed and arrogant from sunrise unto sunset;\n"
1830+
"-Singing while they sacked it, they possessed the land at large.\n"
1831+
"-Yet when men would rob them, they resisted, they made onset\n"
1832+
"-And pierced the smoke of battle with a thousand-sabred charge.\n"
1833+
"-\n"
1834+
"-So they warred and trafficked only yesterday, my Cities.\n"
1835+
"-To-day there is no mark or mound of where my Cities stood.\n"
1836+
"-For the River rose at midnight and it washed away my Cities.\n"
1837+
"-They are evened with Atlantis and the towns before the Flood.\n"
1838+
"-\n"
1839+
"-Rain on rain-gorged channels raised the water-levels round them,\n"
1840+
"-Freshet backed on freshet swelled and swept their world from sight,\n"
1841+
"-Till the emboldened floods linked arms and, flashing forward, drowned them--\n"
1842+
"-Drowned my Seven Cities and their peoples in one night!\n"
1843+
"-\n"
1844+
"-Low among the alders lie their derelict foundations,\n"
1845+
"-The beams wherein they trusted and the plinths whereon they built--\n"
1846+
"-My rulers and their treasure and their unborn populations,\n"
1847+
"-Dead, destroyed, aborted, and defiled with mud and silt!\n"
1848+
"-\n"
1849+
"-The Daughters of the Palace whom they cherished in my Cities,\n"
1850+
"-My silver-tongued Princesses, and the promise of their May--\n"
1851+
"-Their bridegrooms of the June-tide--all have perished in my Cities,\n"
1852+
"-With the harsh envenomed virgins that can neither love nor play.\n"
1853+
"-\n"
1854+
"-I was Lord of Cities--I will build anew my Cities,\n"
1855+
"-Seven, set on rocks, above the wrath of any flood.\n"
1856+
"-Nor will I rest from search till I have filled anew my Cities\n"
1857+
"-With peoples undefeated of the dark, enduring blood.\n"
1858+
"+I WAS LORD OF CITIES VERY SUMPTUOUSLY BUILDED.\n"
1859+
"+SEVEN ROARING CITIES PAID ME TRIBUTE FROM AFAR.\n"
1860+
"+IVORY THEIR OUTPOSTS WERE--THE GUARDROOMS OF THEM GILDED,\n"
1861+
"+AND GARRISONED WITH AMAZONS INVINCIBLE IN WAR.\n"
1862+
"+\n"
1863+
"+ALL THE WORLD WENT SOFTLY WHEN IT WALKED BEFORE MY CITIES--\n"
1864+
"+NEITHER KING NOR ARMY VEXED MY PEOPLES AT THEIR TOIL,\n"
1865+
"+NEVER HORSE NOR CHARIOT IRKED OR OVERBORE MY CITIES,\n"
1866+
"+NEVER MOB NOR RULER QUESTIONED WHENCE THEY DREW THEIR SPOIL.\n"
1867+
"+\n"
1868+
"+BANDED, MAILED AND ARROGANT FROM SUNRISE UNTO SUNSET;\n"
1869+
"+SINGING WHILE THEY SACKED IT, THEY POSSESSED THE LAND AT LARGE.\n"
1870+
"+YET WHEN MEN WOULD ROB THEM, THEY RESISTED, THEY MADE ONSET\n"
1871+
"+AND PIERCED THE SMOKE OF BATTLE WITH A THOUSAND-SABRED CHARGE.\n"
1872+
"+\n"
1873+
"+SO THEY WARRED AND TRAFFICKED ONLY YESTERDAY, MY CITIES.\n"
1874+
"+TO-DAY THERE IS NO MARK OR MOUND OF WHERE MY CITIES STOOD.\n"
1875+
"+FOR THE RIVER ROSE AT MIDNIGHT AND IT WASHED AWAY MY CITIES.\n"
1876+
"+THEY ARE EVENED WITH ATLANTIS AND THE TOWNS BEFORE THE FLOOD.\n"
1877+
"+\n"
1878+
"+RAIN ON RAIN-GORGED CHANNELS RAISED THE WATER-LEVELS ROUND THEM,\n"
1879+
"+FRESHET BACKED ON FRESHET SWELLED AND SWEPT THEIR WORLD FROM SIGHT,\n"
1880+
"+TILL THE EMBOLDENED FLOODS LINKED ARMS AND, FLASHING FORWARD, DROWNED THEM--\n"
1881+
"+DROWNED MY SEVEN CITIES AND THEIR PEOPLES IN ONE NIGHT!\n"
1882+
"+\n"
1883+
"+LOW AMONG THE ALDERS LIE THEIR DERELICT FOUNDATIONS,\n"
1884+
"+THE BEAMS WHEREIN THEY TRUSTED AND THE PLINTHS WHEREON THEY BUILT--\n"
1885+
"+MY RULERS AND THEIR TREASURE AND THEIR UNBORN POPULATIONS,\n"
1886+
"+DEAD, DESTROYED, ABORTED, AND DEFILED WITH MUD AND SILT!\n"
1887+
"+\n"
1888+
"+THE DAUGHTERS OF THE PALACE WHOM THEY CHERISHED IN MY CITIES,\n"
1889+
"+MY SILVER-TONGUED PRINCESSES, AND THE PROMISE OF THEIR MAY--\n"
1890+
"+THEIR BRIDEGROOMS OF THE JUNE-TIDE--ALL HAVE PERISHED IN MY CITIES,\n"
1891+
"+WITH THE HARSH ENVENOMED VIRGINS THAT CAN NEITHER LOVE NOR PLAY.\n"
1892+
"+\n"
1893+
"+I WAS LORD OF CITIES--I WILL BUILD ANEW MY CITIES,\n"
1894+
"+SEVEN, SET ON ROCKS, ABOVE THE WRATH OF ANY FLOOD.\n"
1895+
"+NOR WILL I REST FROM SEARCH TILL I HAVE FILLED ANEW MY CITIES\n"
1896+
"+WITH PEOPLES UNDEFEATED OF THE DARK, ENDURING BLOOD.\n"
1897+
" \n"
1898+
" To the sound of trumpets shall their seed restore my Cities\n"
1899+
" Wealthy and well-weaponed, that once more may I behold\n";
1900+
1901+
old_tree = resolve_commit_oid_to_tree(g_repo, old_sha);
1902+
new_tree = resolve_commit_oid_to_tree(g_repo, new_sha);
1903+
1904+
find_opts.flags = GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
1905+
1906+
cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, old_tree, new_tree, NULL));
1907+
cl_git_pass(git_diff_find_similar(diff, &find_opts));
1908+
1909+
cl_git_pass(git_diff_to_buf(&diff_buf, diff, GIT_DIFF_FORMAT_PATCH));
1910+
1911+
cl_assert_equal_s(expected, diff_buf.ptr);
1912+
1913+
git_buf_free(&diff_buf);
1914+
git_diff_free(diff);
1915+
git_tree_free(old_tree);
1916+
git_tree_free(new_tree);
1917+
}
1918+
1919+
void test_diff_rename__delete_and_rename(void)
1920+
{
1921+
const char *old_sha = RENAME_MODIFICATION_COMMIT;
1922+
const char *new_sha = DELETE_RENAME_COMMIT;
1923+
git_tree *old_tree, *new_tree;
1924+
git_diff *diff;
1925+
git_diff_find_options find_opts = GIT_DIFF_FIND_OPTIONS_INIT;
1926+
git_buf diff_buf = GIT_BUF_INIT;
1927+
const char *expected =
1928+
"diff --git a/sixserving.txt b/sixserving.txt\n"
1929+
"deleted file mode 100644\n"
1930+
"index f90d4fc..0000000\n"
1931+
"--- a/sixserving.txt\n"
1932+
"+++ /dev/null\n"
1933+
"@@ -1,25 +0,0 @@\n"
1934+
"-I KEEP six honest serving-men\n"
1935+
"- (They taught me all I knew);\n"
1936+
"-Their names are What and Why and When\n"
1937+
"- And How and Where and Who.\n"
1938+
"-I send them over land and sea,\n"
1939+
"- I send them east and west;\n"
1940+
"-But after they have worked for me,\n"
1941+
"- I give them all a rest.\n"
1942+
"-\n"
1943+
"-I let them rest from nine till five,\n"
1944+
"- For I am busy then,\n"
1945+
"-As well as breakfast, lunch, and tea,\n"
1946+
"- For they are hungry men.\n"
1947+
"-But different folk have different views;\n"
1948+
"-I know a person small—\n"
1949+
"-She keeps ten million serving-men,\n"
1950+
"-Who get no rest at all!\n"
1951+
"-\n"
1952+
"-She sends'em abroad on her own affairs,\n"
1953+
"- From the second she opens her eyes—\n"
1954+
"-One million Hows, two million Wheres,\n"
1955+
"-And seven million Whys!\n"
1956+
"-\n"
1957+
"- -- Rudyard Kipling\n"
1958+
"-\n"
1959+
"diff --git a/songof7cities.txt b/sixserving.txt\n"
1960+
"similarity index 100%\n"
1961+
"rename from songof7cities.txt\n"
1962+
"rename to sixserving.txt\n";
1963+
1964+
old_tree = resolve_commit_oid_to_tree(g_repo, old_sha);
1965+
new_tree = resolve_commit_oid_to_tree(g_repo, new_sha);
1966+
1967+
find_opts.flags = GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
1968+
1969+
cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, old_tree, new_tree, NULL));
1970+
cl_git_pass(git_diff_find_similar(diff, &find_opts));
1971+
1972+
cl_git_pass(git_diff_to_buf(&diff_buf, diff, GIT_DIFF_FORMAT_PATCH));
1973+
1974+
cl_assert_equal_s(expected, diff_buf.ptr);
1975+
1976+
git_buf_free(&diff_buf);
1977+
git_diff_free(diff);
1978+
git_tree_free(old_tree);
1979+
git_tree_free(new_tree);
1980+
}
Binary file not shown.

tests/resources/renames/.gitted/objects/84/d8efa38af7ace2b302de0adbda16b1f1cd2e1b

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
x��Qj�0�S��X+۲ �!4'Xi��H�eC�ߐt�g�r_�f��ZRT�%�*�!q.�&���4��0���.��O���f?� �)g,Z0�����>8y����$�[���ж�t5:�����l���'�<�B� W�������H6%��uJI�
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
be053a189b0bbde545e0a3f59ce00b46ad29ce0d
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
84d8efa38af7ace2b302de0adbda16b1f1cd2e1b

0 commit comments

Comments
 (0)