]>
Commit | Line | Data |
---|---|---|
867a36f3 ET |
1 | /* |
2 | * Copyright (C) the libgit2 contributors. All rights reserved. | |
3 | * | |
4 | * This file is part of libgit2, distributed under the GNU GPL v2 with | |
5 | * a Linking Exception. For full terms see the included COPYING file. | |
6 | */ | |
7 | #ifndef INCLUDE_git_rebase_h__ | |
8 | #define INCLUDE_git_rebase_h__ | |
9 | ||
10 | #include "common.h" | |
11 | #include "types.h" | |
12 | #include "oid.h" | |
18b00406 | 13 | #include "annotated_commit.h" |
ac3d33df JK |
14 | #include "merge.h" |
15 | #include "checkout.h" | |
22a2d3d5 | 16 | #include "commit.h" |
867a36f3 ET |
17 | |
18 | /** | |
19 | * @file git2/rebase.h | |
20 | * @brief Git rebase routines | |
21 | * @defgroup git_rebase Git merge routines | |
22 | * @ingroup Git | |
23 | * @{ | |
24 | */ | |
25 | GIT_BEGIN_DECL | |
26 | ||
a295bd2d CMN |
27 | /** |
28 | * Rebase options | |
29 | * | |
30 | * Use to tell the rebase machinery how to operate. | |
31 | */ | |
867a36f3 ET |
32 | typedef struct { |
33 | unsigned int version; | |
34 | ||
35 | /** | |
f3a199dd ET |
36 | * Used by `git_rebase_init`, this will instruct other clients working |
37 | * on this rebase that you want a quiet rebase experience, which they | |
38 | * may choose to provide in an application-specific manner. This has no | |
aa9bb425 ET |
39 | * effect upon libgit2 directly, but is provided for interoperability |
40 | * between Git tools. | |
867a36f3 ET |
41 | */ |
42 | int quiet; | |
5ae9d296 | 43 | |
ee667307 ET |
44 | /** |
45 | * Used by `git_rebase_init`, this will begin an in-memory rebase, | |
46 | * which will allow callers to step through the rebase operations and | |
47 | * commit the rebased changes, but will not rewind HEAD or update the | |
48 | * repository to be in a rebasing state. This will not interfere with | |
49 | * the working directory (if there is one). | |
50 | */ | |
51 | int inmemory; | |
52 | ||
5ae9d296 | 53 | /** |
aa9bb425 ET |
54 | * Used by `git_rebase_finish`, this is the name of the notes reference |
55 | * used to rewrite notes for rebased commits when finishing the rebase; | |
1087e6be | 56 | * if NULL, the contents of the configuration option `notes.rewriteRef` |
aa9bb425 ET |
57 | * is examined, unless the configuration option `notes.rewrite.rebase` |
58 | * is set to false. If `notes.rewriteRef` is also NULL, notes will | |
59 | * not be rewritten. | |
5ae9d296 ET |
60 | */ |
61 | const char *rewrite_notes_ref; | |
f3a199dd | 62 | |
a202e0d4 ET |
63 | /** |
64 | * Options to control how trees are merged during `git_rebase_next`. | |
65 | */ | |
66 | git_merge_options merge_options; | |
67 | ||
f3a199dd ET |
68 | /** |
69 | * Options to control how files are written during `git_rebase_init`, | |
88ab3be6 | 70 | * `git_rebase_next` and `git_rebase_abort`. Note that a minimum |
f3a199dd ET |
71 | * strategy of `GIT_CHECKOUT_SAFE` is defaulted in `init` and `next`, |
72 | * and a minimum strategy of `GIT_CHECKOUT_FORCE` is defaulted in | |
73 | * `abort` to match git semantics. | |
74 | */ | |
94c988f6 | 75 | git_checkout_options checkout_options; |
22a2d3d5 | 76 | |
c25aa7cd PP |
77 | /** |
78 | * Optional callback that allows users to override commit | |
79 | * creation in `git_rebase_commit`. If specified, users can | |
80 | * create their own commit and provide the commit ID, which | |
81 | * may be useful for signing commits or otherwise customizing | |
82 | * the commit creation. | |
83 | * | |
84 | * If this callback returns `GIT_PASSTHROUGH`, then | |
85 | * `git_rebase_commit` will continue to create the commit. | |
86 | */ | |
87 | git_commit_create_cb commit_create_cb; | |
88 | ||
89 | #ifdef GIT_DEPRECATE_HARD | |
90 | void *reserved; | |
91 | #else | |
22a2d3d5 UG |
92 | /** |
93 | * If provided, this will be called with the commit content, allowing | |
94 | * a signature to be added to the rebase commit. Can be skipped with | |
95 | * GIT_PASSTHROUGH. If GIT_PASSTHROUGH is returned, a commit will be made | |
96 | * without a signature. | |
c25aa7cd | 97 | * |
22a2d3d5 | 98 | * This field is only used when performing git_rebase_commit. |
c25aa7cd PP |
99 | * |
100 | * This callback is not invoked if a `git_commit_create_cb` is | |
101 | * specified. | |
102 | * | |
103 | * This callback is deprecated; users should provide a | |
104 | * creation callback as `commit_create_cb` that produces a | |
105 | * commit buffer, signs it, and commits it. | |
22a2d3d5 | 106 | */ |
c25aa7cd PP |
107 | int (*signing_cb)(git_buf *, git_buf *, const char *, void *); |
108 | #endif | |
22a2d3d5 UG |
109 | |
110 | /** | |
111 | * This will be passed to each of the callbacks in this struct | |
112 | * as the last parameter. | |
113 | */ | |
114 | void *payload; | |
867a36f3 ET |
115 | } git_rebase_options; |
116 | ||
a295bd2d CMN |
117 | /** |
118 | * Type of rebase operation in-progress after calling `git_rebase_next`. | |
119 | */ | |
18b439b9 ET |
120 | typedef enum { |
121 | /** | |
122 | * The given commit is to be cherry-picked. The client should commit | |
123 | * the changes and continue if there are no conflicts. | |
124 | */ | |
125 | GIT_REBASE_OPERATION_PICK = 0, | |
126 | ||
127 | /** | |
128 | * The given commit is to be cherry-picked, but the client should prompt | |
129 | * the user to provide an updated commit message. | |
130 | */ | |
131 | GIT_REBASE_OPERATION_REWORD, | |
132 | ||
133 | /** | |
134 | * The given commit is to be cherry-picked, but the client should stop | |
135 | * to allow the user to edit the changes before committing them. | |
136 | */ | |
137 | GIT_REBASE_OPERATION_EDIT, | |
138 | ||
139 | /** | |
140 | * The given commit is to be squashed into the previous commit. The | |
141 | * commit message will be merged with the previous message. | |
142 | */ | |
143 | GIT_REBASE_OPERATION_SQUASH, | |
144 | ||
145 | /** | |
146 | * The given commit is to be squashed into the previous commit. The | |
147 | * commit message from this commit will be discarded. | |
148 | */ | |
149 | GIT_REBASE_OPERATION_FIXUP, | |
150 | ||
151 | /** | |
152 | * No commit will be cherry-picked. The client should run the given | |
153 | * command and (if successful) continue. | |
154 | */ | |
e579e0f7 | 155 | GIT_REBASE_OPERATION_EXEC |
18b439b9 ET |
156 | } git_rebase_operation_t; |
157 | ||
867a36f3 | 158 | #define GIT_REBASE_OPTIONS_VERSION 1 |
94c988f6 | 159 | #define GIT_REBASE_OPTIONS_INIT \ |
a202e0d4 | 160 | { GIT_REBASE_OPTIONS_VERSION, 0, 0, NULL, GIT_MERGE_OPTIONS_INIT, \ |
22a2d3d5 | 161 | GIT_CHECKOUT_OPTIONS_INIT, NULL, NULL } |
867a36f3 | 162 | |
30640aa9 ET |
163 | /** Indicates that a rebase operation is not (yet) in progress. */ |
164 | #define GIT_REBASE_NO_OPERATION SIZE_MAX | |
165 | ||
a295bd2d CMN |
166 | /** |
167 | * A rebase operation | |
168 | * | |
169 | * Describes a single instruction/operation to be performed during the | |
170 | * rebase. | |
171 | */ | |
18b439b9 ET |
172 | typedef struct { |
173 | /** The type of rebase operation. */ | |
979645a7 | 174 | git_rebase_operation_t type; |
18b439b9 | 175 | |
979645a7 ET |
176 | /** |
177 | * The commit ID being cherry-picked. This will be populated for | |
178 | * all operations except those of type `GIT_REBASE_OPERATION_EXEC`. | |
179 | */ | |
180 | const git_oid id; | |
18b439b9 | 181 | |
979645a7 ET |
182 | /** |
183 | * The executable the user has requested be run. This will only | |
184 | * be populated for operations of type `GIT_REBASE_OPERATION_EXEC`. | |
185 | */ | |
186 | const char *exec; | |
18b439b9 ET |
187 | } git_rebase_operation; |
188 | ||
867a36f3 | 189 | /** |
ac3d33df JK |
190 | * Initialize git_rebase_options structure |
191 | * | |
867a36f3 | 192 | * Initializes a `git_rebase_options` with default values. Equivalent to |
ac3d33df | 193 | * creating an instance with `GIT_REBASE_OPTIONS_INIT`. |
867a36f3 | 194 | * |
ac3d33df JK |
195 | * @param opts The `git_rebase_options` struct to initialize. |
196 | * @param version The struct version; pass `GIT_REBASE_OPTIONS_VERSION`. | |
867a36f3 ET |
197 | * @return Zero on success; -1 on failure. |
198 | */ | |
22a2d3d5 | 199 | GIT_EXTERN(int) git_rebase_options_init( |
867a36f3 ET |
200 | git_rebase_options *opts, |
201 | unsigned int version); | |
202 | ||
203 | /** | |
979645a7 | 204 | * Initializes a rebase operation to rebase the changes in `branch` |
b6b636a7 ET |
205 | * relative to `upstream` onto another branch. To begin the rebase |
206 | * process, call `git_rebase_next`. When you have finished with this | |
207 | * object, call `git_rebase_free`. | |
867a36f3 | 208 | * |
b6b636a7 | 209 | * @param out Pointer to store the rebase object |
867a36f3 | 210 | * @param repo The repository to perform the rebase |
49b8293c ET |
211 | * @param branch The terminal commit to rebase, or NULL to rebase the |
212 | * current branch | |
867a36f3 ET |
213 | * @param upstream The commit to begin rebasing from, or NULL to rebase all |
214 | * reachable commits | |
215 | * @param onto The branch to rebase onto, or NULL to rebase onto the given | |
216 | * upstream | |
f3a199dd | 217 | * @param opts Options to specify how rebase is performed, or NULL |
867a36f3 ET |
218 | * @return Zero on success; -1 on failure. |
219 | */ | |
b6b636a7 ET |
220 | GIT_EXTERN(int) git_rebase_init( |
221 | git_rebase **out, | |
867a36f3 | 222 | git_repository *repo, |
18b00406 ET |
223 | const git_annotated_commit *branch, |
224 | const git_annotated_commit *upstream, | |
225 | const git_annotated_commit *onto, | |
f3a199dd | 226 | const git_rebase_options *opts); |
867a36f3 | 227 | |
b6b636a7 ET |
228 | /** |
229 | * Opens an existing rebase that was previously started by either an | |
230 | * invocation of `git_rebase_init` or by another client. | |
231 | * | |
232 | * @param out Pointer to store the rebase object | |
ec7e1c93 | 233 | * @param repo The repository that has a rebase in-progress |
f3a199dd | 234 | * @param opts Options to specify how rebase is performed |
b6b636a7 ET |
235 | * @return Zero on success; -1 on failure. |
236 | */ | |
f3a199dd ET |
237 | GIT_EXTERN(int) git_rebase_open( |
238 | git_rebase **out, | |
239 | git_repository *repo, | |
240 | const git_rebase_options *opts); | |
b6b636a7 | 241 | |
22a2d3d5 UG |
242 | /** |
243 | * Gets the original `HEAD` ref name for merge rebases. | |
244 | * | |
e579e0f7 | 245 | * @param rebase The in-progress rebase. |
22a2d3d5 UG |
246 | * @return The original `HEAD` ref name |
247 | */ | |
248 | GIT_EXTERN(const char *) git_rebase_orig_head_name(git_rebase *rebase); | |
249 | ||
250 | /** | |
251 | * Gets the original `HEAD` id for merge rebases. | |
252 | * | |
e579e0f7 | 253 | * @param rebase The in-progress rebase. |
22a2d3d5 UG |
254 | * @return The original `HEAD` id |
255 | */ | |
256 | GIT_EXTERN(const git_oid *) git_rebase_orig_head_id(git_rebase *rebase); | |
257 | ||
258 | /** | |
259 | * Gets the `onto` ref name for merge rebases. | |
260 | * | |
e579e0f7 | 261 | * @param rebase The in-progress rebase. |
22a2d3d5 UG |
262 | * @return The `onto` ref name |
263 | */ | |
264 | GIT_EXTERN(const char *) git_rebase_onto_name(git_rebase *rebase); | |
265 | ||
266 | /** | |
267 | * Gets the `onto` id for merge rebases. | |
268 | * | |
e579e0f7 | 269 | * @param rebase The in-progress rebase. |
22a2d3d5 UG |
270 | * @return The `onto` id |
271 | */ | |
272 | GIT_EXTERN(const git_oid *) git_rebase_onto_id(git_rebase *rebase); | |
273 | ||
ed2c06a6 ET |
274 | /** |
275 | * Gets the count of rebase operations that are to be applied. | |
276 | * | |
277 | * @param rebase The in-progress rebase | |
278 | * @return The number of rebase operations in total | |
279 | */ | |
280 | GIT_EXTERN(size_t) git_rebase_operation_entrycount(git_rebase *rebase); | |
281 | ||
282 | /** | |
283 | * Gets the index of the rebase operation that is currently being applied. | |
30640aa9 ET |
284 | * If the first operation has not yet been applied (because you have |
285 | * called `init` but not yet `next`) then this returns | |
286 | * `GIT_REBASE_NO_OPERATION`. | |
ed2c06a6 ET |
287 | * |
288 | * @param rebase The in-progress rebase | |
289 | * @return The index of the rebase operation currently being applied. | |
290 | */ | |
291 | GIT_EXTERN(size_t) git_rebase_operation_current(git_rebase *rebase); | |
292 | ||
293 | /** | |
294 | * Gets the rebase operation specified by the given index. | |
295 | * | |
296 | * @param rebase The in-progress rebase | |
297 | * @param idx The index of the rebase operation to retrieve | |
298 | * @return The rebase operation or NULL if `idx` was out of bounds | |
299 | */ | |
300 | GIT_EXTERN(git_rebase_operation *) git_rebase_operation_byindex( | |
301 | git_rebase *rebase, | |
302 | size_t idx); | |
303 | ||
950a7091 | 304 | /** |
18b439b9 ET |
305 | * Performs the next rebase operation and returns the information about it. |
306 | * If the operation is one that applies a patch (which is any operation except | |
307 | * GIT_REBASE_OPERATION_EXEC) then the patch will be applied and the index and | |
308 | * working directory will be updated with the changes. If there are conflicts, | |
309 | * you will need to address those before committing the changes. | |
950a7091 | 310 | * |
ec7e1c93 BC |
311 | * @param operation Pointer to store the rebase operation that is to be performed next |
312 | * @param rebase The rebase in progress | |
950a7091 ET |
313 | * @return Zero on success; -1 on failure. |
314 | */ | |
315 | GIT_EXTERN(int) git_rebase_next( | |
f152f8ac | 316 | git_rebase_operation **operation, |
f3a199dd | 317 | git_rebase *rebase); |
950a7091 | 318 | |
f28bae0c ET |
319 | /** |
320 | * Gets the index produced by the last operation, which is the result | |
321 | * of `git_rebase_next` and which will be committed by the next | |
322 | * invocation of `git_rebase_commit`. This is useful for resolving | |
323 | * conflicts in an in-memory rebase before committing them. You must | |
324 | * call `git_index_free` when you are finished with this. | |
325 | * | |
326 | * This is only applicable for in-memory rebases; for rebases within | |
327 | * a working directory, the changes were applied to the repository's | |
328 | * index. | |
e579e0f7 MB |
329 | * |
330 | * @param index The result index of the last operation. | |
331 | * @param rebase The in-progress rebase. | |
332 | * @return 0 or an error code | |
f28bae0c ET |
333 | */ |
334 | GIT_EXTERN(int) git_rebase_inmemory_index( | |
335 | git_index **index, | |
336 | git_rebase *rebase); | |
337 | ||
a35a9890 ET |
338 | /** |
339 | * Commits the current patch. You must have resolved any conflicts that | |
340 | * were introduced during the patch application from the `git_rebase_next` | |
341 | * invocation. | |
18b439b9 | 342 | * |
a35a9890 | 343 | * @param id Pointer in which to store the OID of the newly created commit |
ec7e1c93 | 344 | * @param rebase The rebase that is in-progress |
a35a9890 ET |
345 | * @param author The author of the updated commit, or NULL to keep the |
346 | * author from the original commit | |
347 | * @param committer The committer of the rebase | |
348 | * @param message_encoding The encoding for the message in the commit, | |
349 | * represented with a standard encoding name. If message is NULL, | |
350 | * this should also be NULL, and the encoding from the original | |
351 | * commit will be maintained. If message is specified, this may be | |
352 | * NULL to indicate that "UTF-8" is to be used. | |
18b439b9 ET |
353 | * @param message The message for this commit, or NULL to use the message |
354 | * from the original commit. | |
a35a9890 | 355 | * @return Zero on success, GIT_EUNMERGED if there are unmerged changes in |
93a7004c ET |
356 | * the index, GIT_EAPPLIED if the current commit has already |
357 | * been applied to the upstream and there is nothing to commit, | |
358 | * -1 on failure. | |
a35a9890 ET |
359 | */ |
360 | GIT_EXTERN(int) git_rebase_commit( | |
361 | git_oid *id, | |
b6b636a7 | 362 | git_rebase *rebase, |
a35a9890 ET |
363 | const git_signature *author, |
364 | const git_signature *committer, | |
365 | const char *message_encoding, | |
366 | const char *message); | |
367 | ||
4fe84d62 ET |
368 | /** |
369 | * Aborts a rebase that is currently in progress, resetting the repository | |
370 | * and working directory to their state before rebase began. | |
371 | * | |
b6b636a7 | 372 | * @param rebase The rebase that is in-progress |
4fe84d62 ET |
373 | * @return Zero on success; GIT_ENOTFOUND if a rebase is not in progress, |
374 | * -1 on other errors. | |
375 | */ | |
f3a199dd | 376 | GIT_EXTERN(int) git_rebase_abort(git_rebase *rebase); |
4fe84d62 | 377 | |
517644cc ET |
378 | /** |
379 | * Finishes a rebase that is currently in progress once all patches have | |
380 | * been applied. | |
381 | * | |
b6b636a7 | 382 | * @param rebase The rebase that is in-progress |
979645a7 | 383 | * @param signature The identity that is finishing the rebase (optional) |
ec7e1c93 | 384 | * @return Zero on success; -1 on error |
517644cc ET |
385 | */ |
386 | GIT_EXTERN(int) git_rebase_finish( | |
b6b636a7 | 387 | git_rebase *rebase, |
f3a199dd | 388 | const git_signature *signature); |
517644cc | 389 | |
b6b636a7 ET |
390 | /** |
391 | * Frees the `git_rebase` object. | |
392 | * | |
979645a7 | 393 | * @param rebase The rebase object |
b6b636a7 ET |
394 | */ |
395 | GIT_EXTERN(void) git_rebase_free(git_rebase *rebase); | |
396 | ||
867a36f3 ET |
397 | /** @} */ |
398 | GIT_END_DECL | |
399 | #endif |