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  * @param opts The `git_rebase_options` struct to initialize.
196  * @param version The struct version; pass `GIT_REBASE_OPTIONS_VERSION`.
197  * @return Zero on success; -1 on failure.
198  */
199 //GIT_EXTERN
200 int git_rebase_options_init(.git_rebase_options* opts, uint version_);
201 
202 /**
203  * Initializes a rebase operation to rebase the changes in `branch`
204  * relative to `upstream` onto another branch.  To begin the rebase
205  * process, call `git_rebase_next`.  When you have finished with this
206  * object, call `git_rebase_free`.
207  *
208  * @param out_ Pointer to store the rebase object
209  * @param repo The repository to perform the rebase
210  * @param branch The terminal commit to rebase, or null to rebase the
211  *               current branch
212  * @param upstream The commit to begin rebasing from, or null to rebase all
213  *                 reachable commits
214  * @param onto The branch to rebase onto, or null to rebase onto the given
215  *             upstream
216  * @param opts Options to specify how rebase is performed, or null
217  * @return Zero on success; -1 on failure.
218  */
219 //GIT_EXTERN
220 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);
221 
222 /**
223  * Opens an existing rebase that was previously started by either an
224  * invocation of `git_rebase_init` or by another client.
225  *
226  * @param out_ Pointer to store the rebase object
227  * @param repo The repository that has a rebase in-progress
228  * @param opts Options to specify how rebase is performed
229  * @return Zero on success; -1 on failure.
230  */
231 //GIT_EXTERN
232 int git_rebase_open(libgit2_d.types.git_rebase** out_, libgit2_d.types.git_repository* repo, const (git_rebase_options)* opts);
233 
234 /**
235  * Gets the original `HEAD` ref name for merge rebases.
236  *
237  * @return The original `HEAD` ref name
238  */
239 //GIT_EXTERN
240 const (char)* git_rebase_orig_head_name(libgit2_d.types.git_rebase* rebase);
241 
242 /**
243  * Gets the original `HEAD` id for merge rebases.
244  *
245  * @return The original `HEAD` id
246  */
247 //GIT_EXTERN
248 const (libgit2_d.oid.git_oid)* git_rebase_orig_head_id(libgit2_d.types.git_rebase* rebase);
249 
250 /**
251  * Gets the `onto` ref name for merge rebases.
252  *
253  * @return The `onto` ref name
254  */
255 //GIT_EXTERN
256 const (char)* git_rebase_onto_name(libgit2_d.types.git_rebase* rebase);
257 
258 /**
259  * Gets the `onto` id for merge rebases.
260  *
261  * @return The `onto` id
262  */
263 //GIT_EXTERN
264 const (libgit2_d.oid.git_oid)* git_rebase_onto_id(libgit2_d.types.git_rebase* rebase);
265 
266 /**
267  * Gets the count of rebase operations that are to be applied.
268  *
269  * @param rebase The in-progress rebase
270  * @return The number of rebase operations in total
271  */
272 //GIT_EXTERN
273 size_t git_rebase_operation_entrycount(libgit2_d.types.git_rebase* rebase);
274 
275 /**
276  * Gets the index of the rebase operation that is currently being applied.
277  * If the first operation has not yet been applied (because you have
278  * called `init` but not yet `next`) then this returns
279  * `GIT_REBASE_NO_OPERATION`.
280  *
281  * @param rebase The in-progress rebase
282  * @return The index of the rebase operation currently being applied.
283  */
284 //GIT_EXTERN
285 size_t git_rebase_operation_current(libgit2_d.types.git_rebase* rebase);
286 
287 /**
288  * Gets the rebase operation specified by the given index.
289  *
290  * @param rebase The in-progress rebase
291  * @param idx The index of the rebase operation to retrieve
292  * @return The rebase operation or null if `idx` was out of bounds
293  */
294 //GIT_EXTERN
295 .git_rebase_operation* git_rebase_operation_byindex(libgit2_d.types.git_rebase* rebase, size_t idx);
296 
297 /**
298  * Performs the next rebase operation and returns the information about it.
299  * If the operation is one that applies a patch (which is any operation except
300  * git_rebase_operation_t.GIT_REBASE_OPERATION_EXEC) then the patch will be applied and the index and
301  * working directory will be updated with the changes.  If there are conflicts,
302  * you will need to address those before committing the changes.
303  *
304  * @param operation Pointer to store the rebase operation that is to be
305  * performed next
306  * @param rebase The rebase in progress
307  * @return Zero on success; -1 on failure.
308  */
309 //GIT_EXTERN
310 int git_rebase_next(.git_rebase_operation** operation, libgit2_d.types.git_rebase* rebase);
311 
312 /**
313  * Gets the index produced by the last operation, which is the result
314  * of `git_rebase_next` and which will be committed by the next
315  * invocation of `git_rebase_commit`.  This is useful for resolving
316  * conflicts in an in-memory rebase before committing them.  You must
317  * call `git_index_free` when you are finished with this.
318  *
319  * This is only applicable for in-memory rebases; for rebases within
320  * a working directory, the changes were applied to the repository's
321  * index.
322  */
323 //GIT_EXTERN
324 int git_rebase_inmemory_index(libgit2_d.types.git_index** index, libgit2_d.types.git_rebase* rebase);
325 
326 /**
327  * Commits the current patch.  You must have resolved any conflicts that
328  * were introduced during the patch application from the `git_rebase_next`
329  * invocation.
330  *
331  * @param id Pointer in which to store the OID of the newly created commit
332  * @param rebase The rebase that is in-progress
333  * @param author The author of the updated commit, or null to keep the
334  *        author from the original commit
335  * @param committer The committer of the rebase
336  * @param message_encoding The encoding for the message in the commit,
337  *        represented with a standard encoding name.  If message is null,
338  *        this should also be null, and the encoding from the original
339  *        commit will be maintained.  If message is specified, this may be
340  *        null to indicate that "UTF-8" is to be used.
341  * @param message The message for this commit, or null to use the message
342  *        from the original commit.
343  * @return Zero on success, git_error_code.GIT_EUNMERGED if there are unmerged changes in
344  *        the index, git_error_code.GIT_EAPPLIED if the current commit has already
345  *        been applied to the upstream and there is nothing to commit,
346  *        -1 on failure.
347  */
348 //GIT_EXTERN
349 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);
350 
351 /**
352  * Aborts a rebase that is currently in progress, resetting the repository
353  * and working directory to their state before rebase began.
354  *
355  * @param rebase The rebase that is in-progress
356  * @return Zero on success; git_error_code.GIT_ENOTFOUND if a rebase is not in progress,
357  *         -1 on other errors.
358  */
359 //GIT_EXTERN
360 int git_rebase_abort(libgit2_d.types.git_rebase* rebase);
361 
362 /**
363  * Finishes a rebase that is currently in progress once all patches have
364  * been applied.
365  *
366  * @param rebase The rebase that is in-progress
367  * @param signature The identity that is finishing the rebase (optional)
368  * @return Zero on success; -1 on error
369  */
370 //GIT_EXTERN
371 int git_rebase_finish(libgit2_d.types.git_rebase* rebase, const (libgit2_d.types.git_signature)* signature);
372 
373 /**
374  * Frees the `git_rebase` object.
375  *
376  * @param rebase The rebase object
377  */
378 //GIT_EXTERN
379 void git_rebase_free(libgit2_d.types.git_rebase* rebase);
380 
381 /** @} */