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 /* @} */