4
4
#include "git-compat-util.h"
5
5
#include "add-patch.h"
6
6
#include "advice.h"
7
+ #include "commit.h"
7
8
#include "config.h"
8
9
#include "diff.h"
9
10
#include "editor.h"
10
11
#include "environment.h"
11
12
#include "gettext.h"
13
+ #include "hex.h"
12
14
#include "object-name.h"
13
15
#include "pager.h"
14
16
#include "read-cache-ll.h"
@@ -263,6 +265,8 @@ struct hunk {
263
265
264
266
struct add_p_state {
265
267
struct repository * r ;
268
+ struct index_state * index ;
269
+ const char * index_file ;
266
270
struct interactive_config cfg ;
267
271
struct strbuf answer , buf ;
268
272
@@ -437,7 +441,7 @@ static void setup_child_process(struct add_p_state *s,
437
441
438
442
cp -> git_cmd = 1 ;
439
443
strvec_pushf (& cp -> env ,
440
- INDEX_ENVIRONMENT "=%s" , s -> r -> index_file );
444
+ INDEX_ENVIRONMENT "=%s" , s -> index_file );
441
445
}
442
446
443
447
static int parse_range (const char * * p ,
@@ -1861,7 +1865,7 @@ static int patch_update_file(struct add_p_state *s,
1861
1865
strbuf_reset (& s -> buf );
1862
1866
reassemble_patch (s , file_diff , 0 , & s -> buf );
1863
1867
1864
- discard_index (s -> r -> index );
1868
+ discard_index (s -> index );
1865
1869
if (s -> mode -> apply_for_checkout )
1866
1870
apply_for_checkout (s , & s -> buf ,
1867
1871
s -> mode -> is_reverse );
@@ -1872,9 +1876,11 @@ static int patch_update_file(struct add_p_state *s,
1872
1876
NULL , 0 , NULL , 0 ))
1873
1877
error (_ ("'git apply' failed" ));
1874
1878
}
1875
- if (repo_read_index (s -> r ) >= 0 )
1879
+ if (read_index_from (s -> index , s -> index_file , s -> r -> gitdir ) >= 0 &&
1880
+ s -> index == s -> r -> index ) {
1876
1881
repo_refresh_and_write_index (s -> r , REFRESH_QUIET , 0 ,
1877
1882
1 , NULL , NULL , NULL );
1883
+ }
1878
1884
}
1879
1885
1880
1886
putchar ('\n' );
@@ -1887,6 +1893,8 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
1887
1893
{
1888
1894
struct add_p_state s = {
1889
1895
.r = r ,
1896
+ .index = r -> index ,
1897
+ .index_file = r -> index_file ,
1890
1898
.answer = STRBUF_INIT ,
1891
1899
.buf = STRBUF_INIT ,
1892
1900
.plain = STRBUF_INIT ,
@@ -1945,3 +1953,99 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
1945
1953
add_p_state_clear (& s );
1946
1954
return 0 ;
1947
1955
}
1956
+
1957
+ int run_add_p_index (struct repository * r ,
1958
+ struct index_state * index ,
1959
+ const char * index_file ,
1960
+ struct interactive_options * opts ,
1961
+ const char * revision ,
1962
+ const struct pathspec * ps )
1963
+ {
1964
+ struct patch_mode mode = {
1965
+ .apply_args = { "--cached" , NULL },
1966
+ .apply_check_args = { "--cached" , NULL },
1967
+ .prompt_mode = {
1968
+ N_ ("Stage mode change [y,n,q,a,d%s,?]? " ),
1969
+ N_ ("Stage deletion [y,n,q,a,d%s,?]? " ),
1970
+ N_ ("Stage addition [y,n,q,a,d%s,?]? " ),
1971
+ N_ ("Stage this hunk [y,n,q,a,d%s,?]? " )
1972
+ },
1973
+ .edit_hunk_hint = N_ ("If the patch applies cleanly, the edited hunk "
1974
+ "will immediately be marked for staging." ),
1975
+ .help_patch_text =
1976
+ N_ ("y - stage this hunk\n"
1977
+ "n - do not stage this hunk\n"
1978
+ "q - quit; do not stage this hunk or any of the remaining "
1979
+ "ones\n"
1980
+ "a - stage this hunk and all later hunks in the file\n"
1981
+ "d - do not stage this hunk or any of the later hunks in "
1982
+ "the file\n" ),
1983
+ .index_only = 1 ,
1984
+ };
1985
+ struct add_p_state s = {
1986
+ .r = r ,
1987
+ .index = index ,
1988
+ .index_file = index_file ,
1989
+ .answer = STRBUF_INIT ,
1990
+ .buf = STRBUF_INIT ,
1991
+ .plain = STRBUF_INIT ,
1992
+ .colored = STRBUF_INIT ,
1993
+ .mode = & mode ,
1994
+ .revision = revision ,
1995
+ };
1996
+ struct strbuf parent_revision = STRBUF_INIT ;
1997
+ char parent_tree_oid [GIT_MAX_HEXSZ + 1 ];
1998
+ size_t binary_count = 0 ;
1999
+ struct commit * commit ;
2000
+ int ret ;
2001
+
2002
+ commit = lookup_commit_reference_by_name (revision );
2003
+ if (!commit ) {
2004
+ err (& s , _ ("Revision does not refer to a commit" ));
2005
+ ret = -1 ;
2006
+ goto out ;
2007
+ }
2008
+
2009
+ if (commit -> parents )
2010
+ oid_to_hex_r (parent_tree_oid , get_commit_tree_oid (commit -> parents -> item ));
2011
+ else
2012
+ oid_to_hex_r (parent_tree_oid , r -> hash_algo -> empty_tree );
2013
+
2014
+ strbuf_addf (& parent_revision , "%s~" , revision );
2015
+ mode .diff_cmd [0 ] = "diff-tree" ;
2016
+ mode .diff_cmd [1 ] = "-r" ;
2017
+ mode .diff_cmd [2 ] = parent_tree_oid ;
2018
+
2019
+ interactive_config_init (& s .cfg , r , opts );
2020
+
2021
+ if (parse_diff (& s , ps ) < 0 ) {
2022
+ ret = -1 ;
2023
+ goto out ;
2024
+ }
2025
+
2026
+ for (size_t i = 0 ; i < s .file_diff_nr ; i ++ ) {
2027
+ if (s .file_diff [i ].binary && !s .file_diff [i ].hunk_nr )
2028
+ binary_count ++ ;
2029
+ else if (patch_update_file (& s , s .file_diff + i ))
2030
+ break ;
2031
+ }
2032
+
2033
+ if (s .file_diff_nr == 0 ) {
2034
+ err (& s , _ ("No changes." ));
2035
+ ret = -1 ;
2036
+ goto out ;
2037
+ }
2038
+
2039
+ if (binary_count == s .file_diff_nr ) {
2040
+ err (& s , _ ("Only binary files changed." ));
2041
+ ret = -1 ;
2042
+ goto out ;
2043
+ }
2044
+
2045
+ ret = 0 ;
2046
+
2047
+ out :
2048
+ strbuf_release (& parent_revision );
2049
+ add_p_state_clear (& s );
2050
+ return ret ;
2051
+ }
0 commit comments