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