61
N_("git stash create [<message>]")
62
#define BUILTIN_STASH_EXPORT_USAGE \
63
N_("git stash export (--print | --to-ref <ref>) [<stash>...]")
64
+#define BUILTIN_STASH_IMPORT_USAGE \
65
+ N_("git stash import <commit>")
66
#define BUILTIN_STASH_CLEAR_USAGE \
67
"git stash clear"
68
79
BUILTIN_STASH_CREATE_USAGE,
80
BUILTIN_STASH_STORE_USAGE,
81
BUILTIN_STASH_EXPORT_USAGE,
82
+ BUILTIN_STASH_IMPORT_USAGE,
83
NULL
84
};
85
138
NULL
139
};
140
141
+static const char * const git_stash_import_usage[] = {
142
+ BUILTIN_STASH_IMPORT_USAGE,
143
+ NULL
144
+};
145
146
static const char ref_stash[] = "refs/stash";
147
static struct strbuf stash_index_path = STRBUF_INIT;
151
* b_commit is set to the base commit
152
* i_commit is set to the commit containing the index tree
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
155
* w_tree is set to the working tree
156
* b_tree is set to the base tree
157
* i_tree is set to the index tree
162
struct object_id b_commit;
163
struct object_id i_commit;
164
struct object_id u_commit;
165
+ struct object_id c_commit;
166
struct object_id w_tree;
167
struct object_id b_tree;
168
struct object_id i_tree;
2000
return ret;
2001
}
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
+
2160
struct stash_entry_data {
2161
struct repository *r;
2162
struct commit_list **items;
2341
OPT_SUBCOMMAND("create", &fn, create_stash),
2342
OPT_SUBCOMMAND("push", &fn, push_stash_unassumed),
2343
OPT_SUBCOMMAND("export", &fn, export_stash),
2344
+ OPT_SUBCOMMAND("import", &fn, import_stash),
2345
OPT_SUBCOMMAND_F("save", &fn, save_stash, PARSE_OPT_NOCOMPLETE),
2346
OPT_END()
2347
};