Skip to content

Commit e61304f

Browse files
committed
Merge branch 'en/stash-df-fix' into maint
"git stash", where the tentative change involves changing a directory to a file (or vice versa), was confused, which has been corrected. * en/stash-df-fix: stash: restore untracked files AFTER restoring tracked files stash: avoid feeding directories to update-index t3903: document a pair of directory/file bugs
2 parents 9cfc01e + bee8691 commit e61304f

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

builtin/stash.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,27 @@ static int reset_head(void)
313313
return run_command(&cp);
314314
}
315315

316+
static int is_path_a_directory(const char *path)
317+
{
318+
/*
319+
* This function differs from abspath.c:is_directory() in that
320+
* here we use lstat() instead of stat(); we do not want to
321+
* follow symbolic links here.
322+
*/
323+
struct stat st;
324+
return (!lstat(path, &st) && S_ISDIR(st.st_mode));
325+
}
326+
316327
static void add_diff_to_buf(struct diff_queue_struct *q,
317328
struct diff_options *options,
318329
void *data)
319330
{
320331
int i;
321332

322333
for (i = 0; i < q->nr; i++) {
334+
if (is_path_a_directory(q->queue[i]->one->path))
335+
continue;
336+
323337
strbuf_addstr(data, q->queue[i]->one->path);
324338

325339
/* NUL-terminate: will be fed to update-index -z */
@@ -521,9 +535,6 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
521535
}
522536
}
523537

524-
if (info->has_u && restore_untracked(&info->u_tree))
525-
return error(_("could not restore untracked files from stash"));
526-
527538
init_merge_options(&o, the_repository);
528539

529540
o.branch1 = "Updated upstream";
@@ -558,6 +569,9 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
558569
unstage_changes_unless_new(&c_tree);
559570
}
560571

572+
if (info->has_u && restore_untracked(&info->u_tree))
573+
return error(_("could not restore untracked files from stash"));
574+
561575
if (!quiet) {
562576
struct child_process cp = CHILD_PROCESS_INIT;
563577

t/t3903-stash.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,4 +1307,62 @@ test_expect_success 'stash -c stash.useBuiltin=false warning ' '
13071307
test_must_be_empty err
13081308
'
13091309

1310+
test_expect_success 'git stash succeeds despite directory/file change' '
1311+
test_create_repo directory_file_switch_v1 &&
1312+
(
1313+
cd directory_file_switch_v1 &&
1314+
test_commit init &&
1315+
1316+
test_write_lines this file has some words >filler &&
1317+
git add filler &&
1318+
git commit -m filler &&
1319+
1320+
git rm filler &&
1321+
mkdir filler &&
1322+
echo contents >filler/file &&
1323+
git stash push
1324+
)
1325+
'
1326+
1327+
test_expect_success 'git stash can pop file -> directory saved changes' '
1328+
test_create_repo directory_file_switch_v2 &&
1329+
(
1330+
cd directory_file_switch_v2 &&
1331+
test_commit init &&
1332+
1333+
test_write_lines this file has some words >filler &&
1334+
git add filler &&
1335+
git commit -m filler &&
1336+
1337+
git rm filler &&
1338+
mkdir filler &&
1339+
echo contents >filler/file &&
1340+
cp filler/file expect &&
1341+
git stash push --include-untracked &&
1342+
git stash apply --index &&
1343+
test_cmp expect filler/file
1344+
)
1345+
'
1346+
1347+
test_expect_success 'git stash can pop directory -> file saved changes' '
1348+
test_create_repo directory_file_switch_v3 &&
1349+
(
1350+
cd directory_file_switch_v3 &&
1351+
test_commit init &&
1352+
1353+
mkdir filler &&
1354+
test_write_lines some words >filler/file1 &&
1355+
test_write_lines and stuff >filler/file2 &&
1356+
git add filler &&
1357+
git commit -m filler &&
1358+
1359+
git rm -rf filler &&
1360+
echo contents >filler &&
1361+
cp filler expect &&
1362+
git stash push --include-untracked &&
1363+
git stash apply --index &&
1364+
test_cmp expect filler
1365+
)
1366+
'
1367+
13101368
test_done

0 commit comments

Comments
 (0)