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 ;
@@ -1992,6 +2001,163 @@ static int write_commit_with_parents(struct repository *r,
1992
2001
return ret ;
1993
2002
}
1994
2003
2004
+ static int do_import_stash (struct repository * r , const char * rev )
2005
+ {
2006
+ struct object_id chain ;
2007
+ int res = 0 ;
2008
+ const char * buffer = NULL ;
2009
+ unsigned long bufsize ;
2010
+ struct commit * this = NULL ;
2011
+ struct commit_list * items = NULL , * cur ;
2012
+ char * msg = NULL ;
2013
+
2014
+ if (repo_get_oid (r , rev , & chain ))
2015
+ return error (_ ("not a valid revision: %s" ), rev );
2016
+
2017
+ this = lookup_commit_reference (r , & chain );
2018
+ if (!this )
2019
+ return error (_ ("not a commit: %s" ), rev );
2020
+
2021
+ /*
2022
+ * Walk the commit history, finding each stash entry, and load data into
2023
+ * the array.
2024
+ */
2025
+ for (;;) {
2026
+ const char * author , * committer ;
2027
+ size_t author_len , committer_len ;
2028
+ const char * p ;
2029
+ const char * expected = "git stash <git@stash> 1000684800 +0000" ;
2030
+ const char * prefix = "git stash: " ;
2031
+ struct commit * stash ;
2032
+ struct tree * tree = repo_get_commit_tree (r , this );
2033
+
2034
+ if (!tree ||
2035
+ !oideq (& tree -> object .oid , r -> hash_algo -> empty_tree ) ||
2036
+ (this -> parents &&
2037
+ (!this -> parents -> next || this -> parents -> next -> next ))) {
2038
+ res = error (_ ("%s is not a valid exported stash commit" ),
2039
+ oid_to_hex (& this -> object .oid ));
2040
+ goto out ;
2041
+ }
2042
+
2043
+ buffer = repo_get_commit_buffer (r , this , & bufsize );
2044
+
2045
+ if (!this -> parents ) {
2046
+ /*
2047
+ * We don't have any parents. Make sure this is our
2048
+ * root commit.
2049
+ */
2050
+ author = find_commit_header (buffer , "author" , & author_len );
2051
+ committer = find_commit_header (buffer , "committer" , & committer_len );
2052
+
2053
+ if (!author || !committer ) {
2054
+ error (_ ("cannot parse commit %s" ), oid_to_hex (& this -> object .oid ));
2055
+ goto out ;
2056
+ }
2057
+
2058
+ if (author_len != strlen (expected ) ||
2059
+ committer_len != strlen (expected ) ||
2060
+ memcmp (author , expected , author_len ) ||
2061
+ memcmp (committer , expected , committer_len )) {
2062
+ res = error (_ ("found root commit %s with invalid data" ), oid_to_hex (& this -> object .oid ));
2063
+ goto out ;
2064
+ }
2065
+ break ;
2066
+ }
2067
+
2068
+ p = strstr (buffer , "\n\n" );
2069
+ if (!p ) {
2070
+ res = error (_ ("cannot parse commit %s" ), oid_to_hex (& this -> object .oid ));
2071
+ goto out ;
2072
+ }
2073
+
2074
+ p += 2 ;
2075
+ if (((size_t )(bufsize - (p - buffer )) < strlen (prefix )) ||
2076
+ memcmp (prefix , p , strlen (prefix ))) {
2077
+ res = error (_ ("found stash commit %s without expected prefix" ), oid_to_hex (& this -> object .oid ));
2078
+ goto out ;
2079
+ }
2080
+
2081
+ stash = this -> parents -> next -> item ;
2082
+
2083
+ if (repo_parse_commit (r , this -> parents -> item ) ||
2084
+ repo_parse_commit (r , stash )) {
2085
+ res = error (_ ("cannot parse parents of commit: %s" ),
2086
+ oid_to_hex (& this -> object .oid ));
2087
+ goto out ;
2088
+ }
2089
+
2090
+ if (check_stash_topology (r , stash )) {
2091
+ res = error (_ ("%s does not look like a stash commit" ),
2092
+ oid_to_hex (& stash -> object .oid ));
2093
+ goto out ;
2094
+ }
2095
+
2096
+ repo_unuse_commit_buffer (r , this , buffer );
2097
+ buffer = NULL ;
2098
+ items = commit_list_insert (stash , & items );
2099
+ this = this -> parents -> item ;
2100
+ }
2101
+
2102
+ /*
2103
+ * Now, walk each entry, adding it to the stash as a normal stash
2104
+ * commit.
2105
+ */
2106
+ for (cur = items ; cur ; cur = cur -> next ) {
2107
+ const char * p ;
2108
+ struct object_id * oid ;
2109
+
2110
+ this = cur -> item ;
2111
+ oid = & this -> object .oid ;
2112
+ buffer = repo_get_commit_buffer (r , this , & bufsize );
2113
+ if (!buffer ) {
2114
+ res = error (_ ("cannot read commit buffer for %s" ), oid_to_hex (oid ));
2115
+ goto out ;
2116
+ }
2117
+
2118
+ p = strstr (buffer , "\n\n" );
2119
+ if (!p ) {
2120
+ res = error (_ ("cannot parse commit %s" ), oid_to_hex (oid ));
2121
+ goto out ;
2122
+ }
2123
+
2124
+ p += 2 ;
2125
+ msg = xmemdupz (p , bufsize - (p - buffer ));
2126
+ repo_unuse_commit_buffer (r , this , buffer );
2127
+ buffer = NULL ;
2128
+
2129
+ if (do_store_stash (oid , msg , 1 )) {
2130
+ res = error (_ ("cannot save the stash for %s" ), oid_to_hex (oid ));
2131
+ goto out ;
2132
+ }
2133
+ FREE_AND_NULL (msg );
2134
+ }
2135
+ out :
2136
+ if (this && buffer )
2137
+ repo_unuse_commit_buffer (r , this , buffer );
2138
+ free_commit_list (items );
2139
+ free (msg );
2140
+
2141
+ return res ;
2142
+ }
2143
+
2144
+ static int import_stash (int argc , const char * * argv , const char * prefix ,
2145
+ struct repository * repo )
2146
+ {
2147
+ struct option options [] = {
2148
+ OPT_END ()
2149
+ };
2150
+
2151
+ argc = parse_options (argc , argv , prefix , options ,
2152
+ git_stash_import_usage ,
2153
+ PARSE_OPT_KEEP_DASHDASH );
2154
+
2155
+ if (argc != 1 )
2156
+ usage_msg_opt ("a revision is required" , git_stash_import_usage , options );
2157
+
2158
+ return do_import_stash (repo , argv [0 ]);
2159
+ }
2160
+
1995
2161
struct stash_entry_data {
1996
2162
struct repository * r ;
1997
2163
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