@@ -325,35 +325,6 @@ static void add_diff_to_buf(struct diff_queue_struct *q,
325
325
}
326
326
}
327
327
328
- static int get_newly_staged (struct strbuf * out , struct object_id * c_tree )
329
- {
330
- struct child_process cp = CHILD_PROCESS_INIT ;
331
- const char * c_tree_hex = oid_to_hex (c_tree );
332
-
333
- /*
334
- * diff-index is very similar to diff-tree above, and should be
335
- * converted together with update_index.
336
- */
337
- cp .git_cmd = 1 ;
338
- strvec_pushl (& cp .args , "diff-index" , "--cached" , "--name-only" ,
339
- "--diff-filter=A" , NULL );
340
- strvec_push (& cp .args , c_tree_hex );
341
- return pipe_command (& cp , NULL , 0 , out , 0 , NULL , 0 );
342
- }
343
-
344
- static int update_index (struct strbuf * out )
345
- {
346
- struct child_process cp = CHILD_PROCESS_INIT ;
347
-
348
- /*
349
- * Update-index is very complicated and may need to have a public
350
- * function exposed in order to remove this forking.
351
- */
352
- cp .git_cmd = 1 ;
353
- strvec_pushl (& cp .args , "update-index" , "--add" , "--stdin" , NULL );
354
- return pipe_command (& cp , out -> buf , out -> len , NULL , 0 , NULL , 0 );
355
- }
356
-
357
328
static int restore_untracked (struct object_id * u_tree )
358
329
{
359
330
int res ;
@@ -385,6 +356,121 @@ static int restore_untracked(struct object_id *u_tree)
385
356
return res ;
386
357
}
387
358
359
+ static void unstage_changes_unless_new (struct object_id * orig_tree )
360
+ {
361
+ /*
362
+ * When we enter this function, there has been a clean merge of
363
+ * relevant trees, and the merge logic always stages whatever merges
364
+ * cleanly. We want to unstage those changes, unless it corresponds
365
+ * to a file that didn't exist as of orig_tree.
366
+ *
367
+ * However, if any SKIP_WORKTREE path is modified relative to
368
+ * orig_tree, then we want to clear the SKIP_WORKTREE bit and write
369
+ * it to the worktree before unstaging.
370
+ */
371
+
372
+ struct checkout state = CHECKOUT_INIT ;
373
+ struct diff_options diff_opts ;
374
+ struct lock_file lock = LOCK_INIT ;
375
+ int i ;
376
+
377
+ /* If any entries have skip_worktree set, we'll have to check 'em out */
378
+ state .force = 1 ;
379
+ state .quiet = 1 ;
380
+ state .refresh_cache = 1 ;
381
+ state .istate = & the_index ;
382
+
383
+ /*
384
+ * Step 1: get a difference between orig_tree (which corresponding
385
+ * to the index before a merge was run) and the current index
386
+ * (reflecting the changes brought in by the merge).
387
+ */
388
+ diff_setup (& diff_opts );
389
+ diff_opts .flags .recursive = 1 ;
390
+ diff_opts .detect_rename = 0 ;
391
+ diff_opts .output_format = DIFF_FORMAT_NO_OUTPUT ;
392
+ diff_setup_done (& diff_opts );
393
+
394
+ do_diff_cache (orig_tree , & diff_opts );
395
+ diffcore_std (& diff_opts );
396
+
397
+ /* Iterate over the paths that changed due to the merge... */
398
+ for (i = 0 ; i < diff_queued_diff .nr ; i ++ ) {
399
+ struct diff_filepair * p ;
400
+ struct cache_entry * ce ;
401
+ int pos ;
402
+
403
+ /* Look up the path's position in the current index. */
404
+ p = diff_queued_diff .queue [i ];
405
+ pos = index_name_pos (& the_index , p -> two -> path ,
406
+ strlen (p -> two -> path ));
407
+
408
+ /*
409
+ * Step 2: Place changes in the working tree
410
+ *
411
+ * Stash is about restoring changes *to the working tree*.
412
+ * So if the merge successfully got a new version of some
413
+ * path, but left it out of the working tree, then clear the
414
+ * SKIP_WORKTREE bit and write it to the working tree.
415
+ */
416
+ if (pos >= 0 && ce_skip_worktree (active_cache [pos ])) {
417
+ struct stat st ;
418
+
419
+ ce = active_cache [pos ];
420
+ if (!lstat (ce -> name , & st )) {
421
+ /* Conflicting path present; relocate it */
422
+ struct strbuf new_path = STRBUF_INIT ;
423
+ int fd ;
424
+
425
+ strbuf_addf (& new_path ,
426
+ "%s.stash.XXXXXX" , ce -> name );
427
+ fd = xmkstemp (new_path .buf );
428
+ close (fd );
429
+ printf (_ ("WARNING: Untracked file in way of "
430
+ "tracked file! Renaming\n "
431
+ " %s -> %s\n"
432
+ " to make room.\n" ),
433
+ ce -> name , new_path .buf );
434
+ if (rename (ce -> name , new_path .buf ))
435
+ die ("Failed to move %s to %s\n" ,
436
+ ce -> name , new_path .buf );
437
+ strbuf_release (& new_path );
438
+ }
439
+ checkout_entry (ce , & state , NULL , NULL );
440
+ ce -> ce_flags &= ~CE_SKIP_WORKTREE ;
441
+ }
442
+
443
+ /*
444
+ * Step 3: "unstage" changes, as long as they are still tracked
445
+ */
446
+ if (p -> one -> oid_valid ) {
447
+ /*
448
+ * Path existed in orig_tree; restore index entry
449
+ * from that tree in order to "unstage" the changes.
450
+ */
451
+ int option = ADD_CACHE_OK_TO_REPLACE ;
452
+ if (pos < 0 )
453
+ option = ADD_CACHE_OK_TO_ADD ;
454
+
455
+ ce = make_cache_entry (& the_index ,
456
+ p -> one -> mode ,
457
+ & p -> one -> oid ,
458
+ p -> one -> path ,
459
+ 0 , 0 );
460
+ add_index_entry (& the_index , ce , option );
461
+ }
462
+ }
463
+ diff_flush (& diff_opts );
464
+
465
+ /*
466
+ * Step 4: write the new index to disk
467
+ */
468
+ repo_hold_locked_index (the_repository , & lock , LOCK_DIE_ON_ERROR );
469
+ if (write_locked_index (& the_index , & lock ,
470
+ COMMIT_LOCK | SKIP_IF_UNCHANGED ))
471
+ die (_ ("Unable to write index." ));
472
+ }
473
+
388
474
static int do_apply_stash (const char * prefix , struct stash_info * info ,
389
475
int index , int quiet )
390
476
{
@@ -467,26 +553,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
467
553
if (reset_tree (& index_tree , 0 , 0 ))
468
554
return -1 ;
469
555
} else {
470
- struct strbuf out = STRBUF_INIT ;
471
-
472
- if (get_newly_staged (& out , & c_tree )) {
473
- strbuf_release (& out );
474
- return -1 ;
475
- }
476
-
477
- if (reset_tree (& c_tree , 0 , 1 )) {
478
- strbuf_release (& out );
479
- return -1 ;
480
- }
481
-
482
- ret = update_index (& out );
483
- strbuf_release (& out );
484
- if (ret )
485
- return -1 ;
486
-
487
- /* read back the result of update_index() back from the disk */
488
- discard_cache ();
489
- read_cache ();
556
+ unstage_changes_unless_new (& c_tree );
490
557
}
491
558
492
559
if (!quiet ) {
0 commit comments