61
61
N_("git stash create [<message>]")
62
62
#define BUILTIN_STASH_EXPORT_USAGE \
63
63
N_("git stash export (--print | --to-ref <ref>) [<stash>...]")
64
+ #define BUILTIN_STASH_IMPORT_USAGE \
65
+ N_("git stash import <commit>")
64
66
#define BUILTIN_STASH_CLEAR_USAGE \
65
67
"git stash clear"
66
68
@@ -77,6 +79,7 @@ static const char * const git_stash_usage[] = {
77
79
BUILTIN_STASH_CREATE_USAGE ,
78
80
BUILTIN_STASH_STORE_USAGE ,
79
81
BUILTIN_STASH_EXPORT_USAGE ,
82
+ BUILTIN_STASH_IMPORT_USAGE ,
80
83
NULL
81
84
};
82
85
@@ -135,6 +138,10 @@ static const char * const git_stash_export_usage[] = {
135
138
NULL
136
139
};
137
140
141
+ static const char * const git_stash_import_usage [] = {
142
+ BUILTIN_STASH_IMPORT_USAGE ,
143
+ NULL
144
+ };
138
145
139
146
static const char ref_stash [] = "refs/stash" ;
140
147
static struct strbuf stash_index_path = STRBUF_INIT ;
@@ -144,6 +151,7 @@ static struct strbuf stash_index_path = STRBUF_INIT;
144
151
* b_commit is set to the base commit
145
152
* i_commit is set to the commit containing the index tree
146
153
* u_commit is set to the commit containing the untracked files tree
154
+ * c_commit is set to the first parent (chain commit) when importing and is otherwise unset
147
155
* w_tree is set to the working tree
148
156
* b_tree is set to the base tree
149
157
* i_tree is set to the index tree
@@ -154,6 +162,7 @@ struct stash_info {
154
162
struct object_id b_commit ;
155
163
struct object_id i_commit ;
156
164
struct object_id u_commit ;
165
+ struct object_id c_commit ;
157
166
struct object_id w_tree ;
158
167
struct object_id b_tree ;
159
168
struct object_id i_tree ;
@@ -1991,6 +2000,163 @@ static int write_commit_with_parents(struct repository *r,
1991
2000
return ret ;
1992
2001
}
1993
2002
2003
+ static int do_import_stash (struct repository * r , const char * rev )
2004
+ {
2005
+ struct object_id chain ;
2006
+ int res = 0 ;
2007
+ const char * buffer = NULL ;
2008
+ unsigned long bufsize ;
2009
+ struct commit * this = NULL ;
2010
+ struct commit_list * items = NULL , * cur ;
2011
+ char * msg = NULL ;
2012
+
2013
+ if (repo_get_oid (r , rev , & chain ))
2014
+ return error (_ ("not a valid revision: %s" ), rev );
2015
+
2016
+ this = lookup_commit_reference (r , & chain );
2017
+ if (!this )
2018
+ return error (_ ("not a commit: %s" ), rev );
2019
+
2020
+ /*
2021
+ * Walk the commit history, finding each stash entry, and load data into
2022
+ * the array.
2023
+ */
2024
+ for (;;) {
2025
+ const char * author , * committer ;
2026
+ size_t author_len , committer_len ;
2027
+ const char * p ;
2028
+ const char * expected = "git stash <git@stash> 1000684800 +0000" ;
2029
+ const char * prefix = "git stash: " ;
2030
+ struct commit * stash ;
2031
+ struct tree * tree = repo_get_commit_tree (r , this );
2032
+
2033
+ if (!tree ||
2034
+ !oideq (& tree -> object .oid , r -> hash_algo -> empty_tree ) ||
2035
+ (this -> parents &&
2036
+ (!this -> parents -> next || this -> parents -> next -> next ))) {
2037
+ res = error (_ ("%s is not a valid exported stash commit" ),
2038
+ oid_to_hex (& this -> object .oid ));
2039
+ goto out ;
2040
+ }
2041
+
2042
+ buffer = repo_get_commit_buffer (r , this , & bufsize );
2043
+
2044
+ if (!this -> parents ) {
2045
+ /*
2046
+ * We don't have any parents. Make sure this is our
2047
+ * root commit.
2048
+ */
2049
+ author = find_commit_header (buffer , "author" , & author_len );
2050
+ committer = find_commit_header (buffer , "committer" , & committer_len );
2051
+
2052
+ if (!author || !committer ) {
2053
+ error (_ ("cannot parse commit %s" ), oid_to_hex (& this -> object .oid ));
2054
+ goto out ;
2055
+ }
2056
+
2057
+ if (author_len != strlen (expected ) ||
2058
+ committer_len != strlen (expected ) ||
2059
+ memcmp (author , expected , author_len ) ||
2060
+ memcmp (committer , expected , committer_len )) {
2061
+ res = error (_ ("found root commit %s with invalid data" ), oid_to_hex (& this -> object .oid ));
2062
+ goto out ;
2063
+ }
2064
+ break ;
2065
+ }
2066
+
2067
+ p = strstr (buffer , "\n\n" );
2068
+ if (!p ) {
2069
+ res = error (_ ("cannot parse commit %s" ), oid_to_hex (& this -> object .oid ));
2070
+ goto out ;
2071
+ }
2072
+
2073
+ p += 2 ;
2074
+ if (((size_t )(bufsize - (p - buffer )) < strlen (prefix )) ||
2075
+ memcmp (prefix , p , strlen (prefix ))) {
2076
+ res = error (_ ("found stash commit %s without expected prefix" ), oid_to_hex (& this -> object .oid ));
2077
+ goto out ;
2078
+ }
2079
+
2080
+ stash = this -> parents -> next -> item ;
2081
+
2082
+ if (repo_parse_commit (r , this -> parents -> item ) ||
2083
+ repo_parse_commit (r , stash )) {
2084
+ res = error (_ ("cannot parse parents of commit: %s" ),
2085
+ oid_to_hex (& this -> object .oid ));
2086
+ goto out ;
2087
+ }
2088
+
2089
+ if (check_stash_topology (r , stash )) {
2090
+ res = error (_ ("%s does not look like a stash commit" ),
2091
+ oid_to_hex (& stash -> object .oid ));
2092
+ goto out ;
2093
+ }
2094
+
2095
+ repo_unuse_commit_buffer (r , this , buffer );
2096
+ buffer = NULL ;
2097
+ items = commit_list_insert (stash , & items );
2098
+ this = this -> parents -> item ;
2099
+ }
2100
+
2101
+ /*
2102
+ * Now, walk each entry, adding it to the stash as a normal stash
2103
+ * commit.
2104
+ */
2105
+ for (cur = items ; cur ; cur = cur -> next ) {
2106
+ const char * p ;
2107
+ struct object_id * oid ;
2108
+
2109
+ this = cur -> item ;
2110
+ oid = & this -> object .oid ;
2111
+ buffer = repo_get_commit_buffer (r , this , & bufsize );
2112
+ if (!buffer ) {
2113
+ res = error (_ ("cannot read commit buffer for %s" ), oid_to_hex (oid ));
2114
+ goto out ;
2115
+ }
2116
+
2117
+ p = strstr (buffer , "\n\n" );
2118
+ if (!p ) {
2119
+ res = error (_ ("cannot parse commit %s" ), oid_to_hex (oid ));
2120
+ goto out ;
2121
+ }
2122
+
2123
+ p += 2 ;
2124
+ msg = xmemdupz (p , bufsize - (p - buffer ));
2125
+ repo_unuse_commit_buffer (r , this , buffer );
2126
+ buffer = NULL ;
2127
+
2128
+ if (do_store_stash (oid , msg , 1 )) {
2129
+ res = error (_ ("cannot save the stash for %s" ), oid_to_hex (oid ));
2130
+ goto out ;
2131
+ }
2132
+ FREE_AND_NULL (msg );
2133
+ }
2134
+ out :
2135
+ if (this && buffer )
2136
+ repo_unuse_commit_buffer (r , this , buffer );
2137
+ free_commit_list (items );
2138
+ free (msg );
2139
+
2140
+ return res ;
2141
+ }
2142
+
2143
+ static int import_stash (int argc , const char * * argv , const char * prefix ,
2144
+ struct repository * repo )
2145
+ {
2146
+ struct option options [] = {
2147
+ OPT_END ()
2148
+ };
2149
+
2150
+ argc = parse_options (argc , argv , prefix , options ,
2151
+ git_stash_import_usage ,
2152
+ PARSE_OPT_KEEP_DASHDASH );
2153
+
2154
+ if (argc != 1 )
2155
+ usage_msg_opt ("a revision is required" , git_stash_import_usage , options );
2156
+
2157
+ return do_import_stash (repo , argv [0 ]);
2158
+ }
2159
+
1994
2160
struct stash_entry_data {
1995
2161
struct repository * r ;
1996
2162
struct commit_list * * items ;
@@ -2175,6 +2341,7 @@ int cmd_stash(int argc,
2175
2341
OPT_SUBCOMMAND ("create" , & fn , create_stash ),
2176
2342
OPT_SUBCOMMAND ("push" , & fn , push_stash_unassumed ),
2177
2343
OPT_SUBCOMMAND ("export" , & fn , export_stash ),
2344
+ OPT_SUBCOMMAND ("import" , & fn , import_stash ),
2178
2345
OPT_SUBCOMMAND_F ("save" , & fn , save_stash , PARSE_OPT_NOCOMPLETE ),
2179
2346
OPT_END ()
2180
2347
};
0 commit comments