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