summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--include/git2.h1
-rw-r--r--include/git2/branch.h2
-rw-r--r--include/git2/cherrypick.h88
-rw-r--r--include/git2/errors.h1
-rw-r--r--include/git2/types.h1
-rw-r--r--src/attr_file.c18
-rw-r--r--src/cherrypick.c230
-rw-r--r--src/global.c3
-rw-r--r--src/ignore.c23
-rw-r--r--src/ignore.h1
-rw-r--r--src/merge.c42
-rw-r--r--src/merge.h2
-rw-r--r--src/revert.c1
-rw-r--r--tests/attr/ignore.c21
-rw-r--r--tests/cherrypick/bare.c106
-rw-r--r--tests/cherrypick/workdir.c429
-rw-r--r--tests/clar_libgit2.c21
-rw-r--r--tests/clar_libgit2.h3
-rw-r--r--tests/merge/workdir/simple.c10
-rw-r--r--tests/refs/branches/iterator.c4
-rw-r--r--tests/repo/open.c5
-rw-r--r--tests/resources/cherrypick/.gitted/HEAD1
-rw-r--r--tests/resources/cherrypick/.gitted/config7
-rw-r--r--tests/resources/cherrypick/.gitted/indexbin0 -> 248 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/info/exclude6
-rw-r--r--tests/resources/cherrypick/.gitted/objects/01/a2b453c2647c71ccfefc285f2266d1f00b8253bin0 -> 30 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/02/67838e09bbc5969bba035be2d27c8a6de694d8bin0 -> 38 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/06/3fc9f01e6e9ec2a8d8f749885e931875e50d37bin0 -> 141 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/08/9ac03f76058b5ba0b44bb268f317f9242481e93
-rw-r--r--tests/resources/cherrypick/.gitted/objects/0d/447a6c2528b06616cde3b209a4b4ea3dcb8d65bin0 -> 107 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/11/24c2c1ae07b26fded662d6c3f3631d9dc16f88bin0 -> 31 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/12/905f4ea5b76f9d3fdcfe73e462201c06ae632abin0 -> 108 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/19/c5c7207054604b69c84d08a7571ef9672bb5c2bin0 -> 28 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/1c/2116845780455ecf916538c1cc27c4222452afbin0 -> 116 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/1c/c85eb4ff0a8438fde1b14274c6f87f891b36a0bin0 -> 117 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/1e/1cb7391d25dcd8daba88f1f627f3045982286cbin0 -> 32 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/20/fc1a4c9d994021f43d33ab75e4252e27ca661dbin0 -> 126 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/28/d9eb4208074ad1cc84e71ccc908b34573f05d2bin0 -> 28 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/2a/26c7e88b285613b302ba76712bc998863f3cbc1
-rw-r--r--tests/resources/cherrypick/.gitted/objects/2a/c3b376093de405b0a951bff578655b1c2b7fa11
-rw-r--r--tests/resources/cherrypick/.gitted/objects/2c/acbcaabf785f1ac231e8519849d4ad38692f2cbin0 -> 26 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/35/cb210149022c7379b0a67b0dec13cc628ff87dbin0 -> 137 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/38/c05a857e831a7e759d83778bfc85d003e21c45bin0 -> 27 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/3f/9eed8946df9e2c737d3b8dc0b8e78959aacd925
-rw-r--r--tests/resources/cherrypick/.gitted/objects/40/9a1bec58bf35348e8b62b72bb9c1f45cf5a587bin0 -> 33 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/44/cd2ed2052c9c68f9a439d208e9614dc2a55c701
-rw-r--r--tests/resources/cherrypick/.gitted/objects/48/7434cace79238a7091e2220611d4f20a765690bin0 -> 33 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/49/20ad2f17162dcc8823ad491444dcb87f5899c9bin0 -> 36 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904bin0 -> 15 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/4c/532774cc1fea37f6efc2256763a64d38c8cddebin0 -> 26 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/51/145af30d411a50195b66517d825e69bf57ed22bin0 -> 107 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/54/61de53ffadbf15be4dd6345997c156895732094
-rw-r--r--tests/resources/cherrypick/.gitted/objects/54/784f10955e92ab27e4fa832e40cb2baf1edbdcbin0 -> 74 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/56/3f6473a3858f99b80e5f93c660512ed38e1e6fbin0 -> 31 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/58/a957ef0061c1a8ef995c855dfab4f5da8d6617bin0 -> 32 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/5d/c7e1f440ce74d5503a0dfbc6c30e091475f774bin0 -> 31 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/5e/2206cda1c56430ad107a6866a829c159e0b9ea1
-rw-r--r--tests/resources/cherrypick/.gitted/objects/5f/77a2a13935ac62a629553f8944ad57b1ed8b4abin0 -> 106 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/63/c0d92b95253c4a40d3883f423a54be47d2c4c8bin0 -> 30 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/6c/e83eb5f0fd34a10c3d25c6b36d2ed7ec0d6ce7bin0 -> 108 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/6d/1c2afe5eeb9e497528e2780ac468a5465cbc961
-rw-r--r--tests/resources/cherrypick/.gitted/objects/74/f06b5bfec6d33d7264f73606b57a7c0b963819bin0 -> 141 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/82/8b08c52d2cba30952e0e008f60b25b5ba0d41abin0 -> 107 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/85/36dd6f0ec3ddecb9f9b6c8c64c6d322cd01211bin0 -> 36 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/85/a4a1d791973644f24c72f5e89420d3064cc452bin0 -> 27 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/8b/5c30499a71001189b647f4d5b57fa8f04897cebin0 -> 107 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/96/4ea3da044d9083181a88ba6701de9e35778bf4bin0 -> 181 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/9c/c39fca3765a2facbe31157f7d60c2602193f36bin0 -> 107 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/9c/cb9bf50c011fd58dcbaa65df917bf79539717fbin0 -> 30 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/a1/0b59f4280491afe6e430c30654a7acc67d4a33bin0 -> 30 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/a2/1b4bfe7a04ab18024fb57f4ae9a52a1acef394bin0 -> 173 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/a4/3a050c588d4e92f11a6b139680923e9728477d1
-rw-r--r--tests/resources/cherrypick/.gitted/objects/a5/8ca3fee5eb68b11adc2703e5843f968c9dad1ebin0 -> 28 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/a6/61b5dec1004e2c62654ded3762370c27cf266bbin0 -> 27 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/a6/9ef8fcbb9a2c509a7dbf4f23d257eb551d56101
-rw-r--r--tests/resources/cherrypick/.gitted/objects/a8/3c6f70297b805dedc549e6583582966f6ebcabbin0 -> 138 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/a9/020cd240774e4d672732bcb82d516d9685da76bin0 -> 26 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/ab/4115f808bc585b60f822da7020af86d20f62c8bin0 -> 213 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/ab/e4603bc7cd5b8167a267e0e2418fd2348f8cff4
-rw-r--r--tests/resources/cherrypick/.gitted/objects/b8/26e9b36e22e949ec885e7a1f3db496bbab6cd0bin0 -> 108 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/ba/fbf6912c09505ac60575cd43d3f2aba3bd84d8bin0 -> 175 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/bb/14296ffa9dfbf935ec9ce2f9ed7808d952226bbin0 -> 38 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/bc/4dd0744364d1db380a9811bd264c101065231ebin0 -> 55 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/bd/65d4083845ed5ed4e1fe5feb85ac395d0760c82
-rw-r--r--tests/resources/cherrypick/.gitted/objects/bd/6ffc8c6c41f0f85ff9e3d61c9479516bac0024bin0 -> 31 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/bd/a51965cb36c0c5731c8cb50b80a36cac81018ebin0 -> 107 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/ce/d8fb81b6ec534d5deaf2a48b4b96c7997125071
-rw-r--r--tests/resources/cherrypick/.gitted/objects/cf/c4f0999a8367568e049af4f72e452d40828a15bin0 -> 180 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/d0/f21e17beb5b9d953b1d8349049818a4f2edd1e1
-rw-r--r--tests/resources/cherrypick/.gitted/objects/d3/d77487660ee3c0194ee01dc5eaf478782b1c7e1
-rw-r--r--tests/resources/cherrypick/.gitted/objects/e2/33b9ed408a95e9d4b65fec7fc34943a556deb2bin0 -> 31 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/e5/183bfd18e3a0a691fadde2f0d5610b73282d31bin0 -> 33 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/e6/ae8889c40c77d7be02758235b5b3f7a4f2a129bin0 -> 107 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/e7/811a2bc55635f182750f0420da5ad232c1af91bin0 -> 107 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/e9/b63f3655b2ad80c0ff587389b5a9589a3a71102
-rw-r--r--tests/resources/cherrypick/.gitted/objects/eb/da71fe44dcb60c53b8fbd53208a1204d32e959bin0 -> 36 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/f0/5ed049854c1596a7cc0e957fab34961077f3aebin0 -> 36 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/f0/a4e1c66bb548cd2b22eebefda703872e969775bin0 -> 191 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/f2/ec8c8cf1a9fb7aa047a25a4308bfe860237ad4bin0 -> 32 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/f5/684c96bf40c709877b56404cd8a5dd2d2a7978bin0 -> 106 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/objects/f9/0f9dcbdac2cce5cc166346160e19cb693ef4e8bin0 -> 31 bytes
-rw-r--r--tests/resources/cherrypick/.gitted/refs/heads/automerge-branch1
-rw-r--r--tests/resources/cherrypick/.gitted/refs/heads/master1
-rw-r--r--tests/resources/cherrypick/.gitted/refs/heads/merge-branch1
-rw-r--r--tests/resources/cherrypick/.gitted/refs/heads/merge-conflicts1
-rw-r--r--tests/resources/cherrypick/.gitted/refs/heads/merge-mainline1
-rw-r--r--tests/resources/cherrypick/.gitted/refs/heads/orphan1
-rw-r--r--tests/resources/cherrypick/.gitted/refs/heads/renames1
-rw-r--r--tests/resources/cherrypick/file1.txt15
-rw-r--r--tests/resources/cherrypick/file2.txt15
-rw-r--r--tests/resources/cherrypick/file3.txt15
-rw-r--r--tests/revert/workdir.c14
-rw-r--r--tests/status/ignore.c167
114 files changed, 1221 insertions, 69 deletions
diff --git a/AUTHORS b/AUTHORS
index f3a03ee74..6854ed016 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -25,6 +25,7 @@ Florian Forster
Holger Weiss
Ingmar Vanhassel
J. David Ibáñez
+Jacques Germishuys
Jakob Pfender
Jason Penny
Jason R. McNeil
diff --git a/include/git2.h b/include/git2.h
index 704fb585a..f74976061 100644
--- a/include/git2.h
+++ b/include/git2.h
@@ -14,6 +14,7 @@
#include "git2/branch.h"
#include "git2/buffer.h"
#include "git2/checkout.h"
+#include "git2/cherrypick.h"
#include "git2/clone.h"
#include "git2/commit.h"
#include "git2/common.h"
diff --git a/include/git2/branch.h b/include/git2/branch.h
index ad2a70b1f..f28410000 100644
--- a/include/git2/branch.h
+++ b/include/git2/branch.h
@@ -84,7 +84,7 @@ typedef struct git_branch_iterator git_branch_iterator;
* @param repo Repository where to find the branches.
* @param list_flags Filtering flags for the branch
* listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
- * or a combination of the two.
+ * or GIT_BRANCH_ALL.
*
* @return 0 on success or an error code
*/
diff --git a/include/git2/cherrypick.h b/include/git2/cherrypick.h
new file mode 100644
index 000000000..7c48e6659
--- /dev/null
+++ b/include/git2/cherrypick.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) the libgit2 contributors. All rights reserved.
+ *
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
+ * a Linking Exception. For full terms see the included COPYING file.
+ */
+#ifndef INCLUDE_git_cherrypick_h__
+#define INCLUDE_git_cherrypick_h__
+
+#include "common.h"
+#include "types.h"
+#include "merge.h"
+
+/**
+ * @file git2/cherrypick.h
+ * @brief Git cherry-pick routines
+ * @defgroup git_cherrypick Git cherry-pick routines
+ * @ingroup Git
+ * @{
+ */
+GIT_BEGIN_DECL
+
+typedef struct {
+ unsigned int version;
+
+ /** For merge commits, the "mainline" is treated as the parent. */
+ unsigned int mainline;
+
+ git_merge_options merge_opts;
+ git_checkout_options checkout_opts;
+} git_cherry_pick_options;
+
+#define GIT_CHERRY_PICK_OPTIONS_VERSION 1
+#define GIT_CHERRY_PICK_OPTIONS_INIT {GIT_CHERRY_PICK_OPTIONS_VERSION, 0, GIT_MERGE_OPTIONS_INIT, GIT_CHECKOUT_OPTIONS_INIT}
+
+/**
+ * Initializes a `git_cherry_pick_options` with default values. Equivalent to
+ * creating an instance with GIT_CHERRY_PICK_OPTIONS_INIT.
+ *
+ * @param opts the `git_cherry_pick_options` instance to initialize.
+ * @param version the version of the struct; you should pass
+ * `GIT_CHERRY_PICK_OPTIONS_VERSION` here.
+ * @return Zero on success; -1 on failure.
+ */
+GIT_EXTERN(int) git_cherry_pick_init_opts(
+ git_cherry_pick_options* opts,
+ int version);
+
+/**
+ * Cherry-picks the given commit against the given "our" commit, producing an
+ * index that reflects the result of the cherry-pick.
+ *
+ * The returned index must be freed explicitly with `git_index_free`.
+ *
+ * @param out pointer to store the index result in
+ * @param repo the repository that contains the given commits
+ * @param cherry_pick_commit the commit to cherry-pick
+ * @param our_commit the commit to revert against (eg, HEAD)
+ * @param mainline the parent of the revert commit, if it is a merge
+ * @param merge_tree_opts the merge tree options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_cherry_pick_commit(
+ git_index **out,
+ git_repository *repo,
+ git_commit *cherry_pick_commit,
+ git_commit *our_commit,
+ unsigned int mainline,
+ const git_merge_options *merge_options);
+
+/**
+ * Cherry-pick the given commit, producing changes in the index and working directory.
+ *
+ * @param repo the repository to cherry-pick
+ * @param commit the commit to cherry-pick
+ * @param cherry_pick_options the cherry-pick options (or null for defaults)
+ * @return zero on success, -1 on failure.
+ */
+GIT_EXTERN(int) git_cherry_pick(
+ git_repository *repo,
+ git_commit *commit,
+ const git_cherry_pick_options *cherry_pick_options);
+
+/** @} */
+GIT_END_DECL
+
+#endif
+
diff --git a/include/git2/errors.h b/include/git2/errors.h
index bcf2f80ab..e22f0d86d 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -86,6 +86,7 @@ typedef enum {
GITERR_FILTER,
GITERR_REVERT,
GITERR_CALLBACK,
+ GITERR_CHERRYPICK,
} git_error_t;
/**
diff --git a/include/git2/types.h b/include/git2/types.h
index 2229f6bf4..9db59b16b 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -193,6 +193,7 @@ typedef enum {
typedef enum {
GIT_BRANCH_LOCAL = 1,
GIT_BRANCH_REMOTE = 2,
+ GIT_BRANCH_ALL = GIT_BRANCH_LOCAL|GIT_BRANCH_REMOTE,
} git_branch_t;
/** Valid modes for index and tree entries. */
diff --git a/src/attr_file.c b/src/attr_file.c
index 4eb732436..ea92336f7 100644
--- a/src/attr_file.c
+++ b/src/attr_file.c
@@ -61,8 +61,7 @@ int git_attr_file__parse_buffer(
git_repository *repo, void *parsedata, const char *buffer, git_attr_file *attrs)
{
int error = 0;
- const char *scan = NULL;
- char *context = NULL;
+ const char *scan = NULL, *context = NULL;
git_attr_rule *rule = NULL;
GIT_UNUSED(parsedata);
@@ -72,10 +71,10 @@ int git_attr_file__parse_buffer(
scan = buffer;
/* if subdir file path, convert context for file paths */
- if (attrs->key && git__suffixcmp(attrs->key, "/" GIT_ATTR_FILE) == 0) {
+ if (attrs->key &&
+ git_path_root(attrs->key + 2) < 0 &&
+ git__suffixcmp(attrs->key, "/" GIT_ATTR_FILE) == 0)
context = attrs->key + 2;
- context[strlen(context) - strlen(GIT_ATTR_FILE)] = '\0';
- }
while (!error && *scan) {
/* allocate rule if needed */
@@ -115,10 +114,6 @@ int git_attr_file__parse_buffer(
git_attr_rule__free(rule);
- /* restore file path used for context */
- if (context)
- context[strlen(context)] = '.'; /* first char of GIT_ATTR_FILE */
-
return error;
}
@@ -414,7 +409,10 @@ int git_attr_fnmatch__parse(
if ((spec->flags & GIT_ATTR_FNMATCH_FULLPATH) != 0 &&
source != NULL && git_path_root(pattern) < 0)
{
- size_t sourcelen = strlen(source);
+ /* use context path minus the trailing filename */
+ char *slash = strrchr(source, '/');
+ size_t sourcelen = slash ? slash - source + 1 : 0;
+
/* given an unrooted fullpath match from a file inside a repo,
* prefix the pattern with the relative directory of the source file
*/
diff --git a/src/cherrypick.c b/src/cherrypick.c
new file mode 100644
index 000000000..67a2c6af3
--- /dev/null
+++ b/src/cherrypick.c
@@ -0,0 +1,230 @@
+/*
+* Copyright (C) the libgit2 contributors. All rights reserved.
+*
+* This file is part of libgit2, distributed under the GNU GPL v2 with
+* a Linking Exception. For full terms see the included COPYING file.
+*/
+
+#include "common.h"
+#include "repository.h"
+#include "filebuf.h"
+#include "merge.h"
+#include "vector.h"
+
+#include "git2/types.h"
+#include "git2/merge.h"
+#include "git2/cherrypick.h"
+#include "git2/commit.h"
+#include "git2/sys/commit.h"
+
+#define GIT_CHERRY_PICK_FILE_MODE 0666
+
+static int write_cherry_pick_head(
+ git_repository *repo,
+ const char *commit_oidstr)
+{
+ git_filebuf file = GIT_FILEBUF_INIT;
+ git_buf file_path = GIT_BUF_INIT;
+ int error = 0;
+
+ if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_CHERRY_PICK_HEAD_FILE)) >= 0 &&
+ (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRY_PICK_FILE_MODE)) >= 0 &&
+ (error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0)
+ error = git_filebuf_commit(&file);
+
+ if (error < 0)
+ git_filebuf_cleanup(&file);
+
+ git_buf_free(&file_path);
+
+ return error;
+}
+
+static int write_merge_msg(
+ git_repository *repo,
+ const char *commit_msg)
+{
+ git_filebuf file = GIT_FILEBUF_INIT;
+ git_buf file_path = GIT_BUF_INIT;
+ int error = 0;
+
+ if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
+ (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRY_PICK_FILE_MODE)) < 0 ||
+ (error = git_filebuf_printf(&file, "%s", commit_msg)) < 0)
+ goto cleanup;
+
+ error = git_filebuf_commit(&file);
+
+cleanup:
+ if (error < 0)
+ git_filebuf_cleanup(&file);
+
+ git_buf_free(&file_path);
+
+ return error;
+}
+
+static int cherry_pick_normalize_opts(
+ git_repository *repo,
+ git_cherry_pick_options *opts,
+ const git_cherry_pick_options *given,
+ const char *their_label)
+{
+ int error = 0;
+ unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE_CREATE |
+ GIT_CHECKOUT_ALLOW_CONFLICTS;
+
+ GIT_UNUSED(repo);
+
+ if (given != NULL)
+ memcpy(opts, given, sizeof(git_cherry_pick_options));
+ else {
+ git_cherry_pick_options default_opts = GIT_CHERRY_PICK_OPTIONS_INIT;
+ memcpy(opts, &default_opts, sizeof(git_cherry_pick_options));
+ }
+
+ if (!opts->checkout_opts.checkout_strategy)
+ opts->checkout_opts.checkout_strategy = default_checkout_strategy;
+
+ if (!opts->checkout_opts.our_label)
+ opts->checkout_opts.our_label = "HEAD";
+
+ if (!opts->checkout_opts.their_label)
+ opts->checkout_opts.their_label = their_label;
+
+ return error;
+}
+
+static int cherry_pick_state_cleanup(git_repository *repo)
+{
+ const char *state_files[] = { GIT_CHERRY_PICK_HEAD_FILE, GIT_MERGE_MSG_FILE };
+
+ return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
+}
+
+static int cherry_pick_seterr(git_commit *commit, const char *fmt)
+{
+ char commit_oidstr[GIT_OID_HEXSZ + 1];
+
+ giterr_set(GITERR_CHERRYPICK, fmt,
+ git_oid_tostr(commit_oidstr, GIT_OID_HEXSZ + 1, git_commit_id(commit)));
+
+ return -1;
+}
+
+int git_cherry_pick_commit(
+ git_index **out,
+ git_repository *repo,
+ git_commit *cherry_pick_commit,
+ git_commit *our_commit,
+ unsigned int mainline,
+ const git_merge_options *merge_opts)
+{
+ git_commit *parent_commit = NULL;
+ git_tree *parent_tree = NULL, *our_tree = NULL, *cherry_pick_tree = NULL;
+ int parent = 0, error = 0;
+
+ assert(out && repo && cherry_pick_commit && our_commit);
+
+ if (git_commit_parentcount(cherry_pick_commit) > 1) {
+ if (!mainline)
+ return cherry_pick_seterr(cherry_pick_commit,
+ "Mainline branch is not specified but %s is a merge commit");
+
+ parent = mainline;
+ } else {
+ if (mainline)
+ return cherry_pick_seterr(cherry_pick_commit,
+ "Mainline branch specified but %s is not a merge commit");
+
+ parent = git_commit_parentcount(cherry_pick_commit);
+ }
+
+ if (parent &&
+ ((error = git_commit_parent(&parent_commit, cherry_pick_commit, (parent - 1))) < 0 ||
+ (error = git_commit_tree(&parent_tree, parent_commit)) < 0))
+ goto done;
+
+ if ((error = git_commit_tree(&cherry_pick_tree, cherry_pick_commit)) < 0 ||
+ (error = git_commit_tree(&our_tree, our_commit)) < 0)
+ goto done;
+
+ error = git_merge_trees(out, repo, parent_tree, our_tree, cherry_pick_tree, merge_opts);
+
+done:
+ git_tree_free(parent_tree);
+ git_tree_free(our_tree);
+ git_tree_free(cherry_pick_tree);
+ git_commit_free(parent_commit);
+
+ return error;
+}
+
+int git_cherry_pick(
+ git_repository *repo,
+ git_commit *commit,
+ const git_cherry_pick_options *given_opts)
+{
+ git_cherry_pick_options opts;
+ git_reference *our_ref = NULL;
+ git_commit *our_commit = NULL;
+ char commit_oidstr[GIT_OID_HEXSZ + 1];
+ const char *commit_msg, *commit_summary;
+ git_buf their_label = GIT_BUF_INIT;
+ git_index *index_new = NULL, *index_repo = NULL;
+ int error = 0;
+
+ assert(repo && commit);
+
+ GITERR_CHECK_VERSION(given_opts, GIT_CHERRY_PICK_OPTIONS_VERSION, "git_cherry_pick_options");
+
+ if ((error = git_repository__ensure_not_bare(repo, "cherry-pick")) < 0)
+ return error;
+
+ if ((commit_msg = git_commit_message(commit)) == NULL ||
+ (commit_summary = git_commit_summary(commit)) == NULL) {
+ error = -1;
+ goto on_error;
+ }
+
+ git_oid_fmt(commit_oidstr, git_commit_id(commit));
+
+ if ((error = write_merge_msg(repo, commit_msg)) < 0 ||
+ (error = git_buf_printf(&their_label, "%.7s... %s", commit_oidstr, commit_summary)) < 0 ||
+ (error = cherry_pick_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 ||
+ (error = write_cherry_pick_head(repo, commit_oidstr)) < 0 ||
+ (error = git_repository_head(&our_ref, repo)) < 0 ||
+ (error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
+ (error = git_cherry_pick_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
+ (error = git_merge__indexes(repo, index_new)) < 0 ||
+ (error = git_repository_index(&index_repo, repo)) < 0 ||
+ (error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 ||
+ (error = git_checkout_index(repo, index_repo, &opts.checkout_opts)) < 0)
+ goto on_error;
+
+ goto done;
+
+on_error:
+ cherry_pick_state_cleanup(repo);
+
+done:
+ git_index_free(index_new);
+ git_index_free(index_repo);
+ git_commit_free(our_commit);
+ git_reference_free(our_ref);
+ git_buf_free(&their_label);
+
+ return error;
+}
+
+int git_cherry_pick_init_opts(git_cherry_pick_options* opts, int version)
+{
+ if (version != GIT_CHERRY_PICK_OPTIONS_VERSION) {
+ giterr_set(GITERR_INVALID, "Invalid version %d for git_cherry_pick_options", version);
+ return -1;
+ } else {
+ git_cherry_pick_options o = GIT_CHERRY_PICK_OPTIONS_INIT;
+ memcpy(opts, &o, sizeof(o));
+ return 0;
+ }
+}
diff --git a/src/global.c b/src/global.c
index 8c8f55a90..c26b4b311 100644
--- a/src/global.c
+++ b/src/global.c
@@ -183,6 +183,7 @@ int git_threads_init(void)
void git_threads_shutdown(void)
{
+ void *ptr = NULL;
pthread_once_t new_once = PTHREAD_ONCE_INIT;
if (git_atomic_dec(&git__n_inits) > 0) return;
@@ -190,7 +191,7 @@ void git_threads_shutdown(void)
/* Shut down any subsystems that have global state */
git__shutdown();
- void *ptr = pthread_getspecific(_tls_key);
+ ptr = pthread_getspecific(_tls_key);
pthread_setspecific(_tls_key, NULL);
git__free(ptr);
diff --git a/src/ignore.c b/src/ignore.c
index c79fe4871..5cf4fca5c 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -14,8 +14,7 @@ static int parse_ignore_file(
{
int error = 0;
git_attr_fnmatch *match = NULL;
- const char *scan = NULL;
- char *context = NULL;
+ const char *scan = NULL, *context = NULL;
int ignore_case = false;
/* Prefer to have the caller pass in a git_ignores as the parsedata
@@ -25,10 +24,10 @@ static int parse_ignore_file(
else if (git_repository__cvar(&ignore_case, repo, GIT_CVAR_IGNORECASE) < 0)
return error;
- if (ignores->key && git__suffixcmp(ignores->key, "/" GIT_IGNORE_FILE) == 0) {
+ if (ignores->key &&
+ git_path_root(ignores->key + 2) < 0 &&
+ git__suffixcmp(ignores->key, "/" GIT_IGNORE_FILE) == 0)
context = ignores->key + 2;
- context[strlen(context) - strlen(GIT_IGNORE_FILE)] = '\0';
- }
scan = buffer;
@@ -64,9 +63,6 @@ static int parse_ignore_file(
}
git__free(match);
- /* restore file path used for context */
- if (context)
- context[strlen(context)] = '.'; /* first char of GIT_IGNORE_FILE */
return error;
}
@@ -78,6 +74,8 @@ static int push_one_ignore(void *payload, git_buf *path)
{
git_ignores *ign = payload;
+ ign->depth++;
+
return push_ignore_file(
ign->repo, ign, &ign->ign_path, path->ptr, GIT_IGNORE_FILE);
}
@@ -108,6 +106,7 @@ int git_ignore__for_path(
ignores->repo = repo;
git_buf_init(&ignores->dir, 0);
ignores->ign_internal = NULL;
+ ignores->depth = 0;
/* Read the ignore_case flag */
if ((error = git_repository__cvar(
@@ -163,6 +162,8 @@ int git_ignore__push_dir(git_ignores *ign, const char *dir)
if (git_buf_joinpath(&ign->dir, ign->dir.ptr, dir) < 0)
return -1;
+ ign->depth++;
+
return push_ignore_file(
ign->repo, ign, &ign->ign_path, ign->dir.ptr, GIT_IGNORE_FILE);
}
@@ -174,7 +175,7 @@ int git_ignore__pop_dir(git_ignores *ign)
const char *start, *end, *scan;
size_t keylen;
- /* - ign->dir looks something like "a/b" (or "a/b/c/d")
+ /* - ign->dir looks something like "a/b/" (or "a/b/c/d/")
* - file->key looks something like "0#a/b/.gitignore
*
* We are popping the last directory off ign->dir. We also want to
@@ -191,9 +192,13 @@ int git_ignore__pop_dir(git_ignores *ign)
if (ign->dir.size >= keylen &&
!memcmp(ign->dir.ptr + ign->dir.size - keylen, start, keylen))
git_vector_pop(&ign->ign_path);
+ }
+ if (--ign->depth > 0) {
git_buf_rtruncate_at_char(&ign->dir, '/');
+ git_path_to_dir(&ign->dir);
}
+
return 0;
}
diff --git a/src/ignore.h b/src/ignore.h
index 851c824bf..46172c72f 100644
--- a/src/ignore.h
+++ b/src/ignore.h
@@ -29,6 +29,7 @@ typedef struct {
git_vector ign_path;
git_vector ign_global;
int ignore_case;
+ int depth;
} git_ignores;
extern int git_ignore__for_path(
diff --git a/src/merge.c b/src/merge.c
index dd6a39f37..10c19b5c5 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -2469,6 +2469,47 @@ done:
return error;
}
+int git_merge__append_conflicts_to_merge_msg(
+ git_repository *repo,
+ git_index *index)
+{
+ git_filebuf file = GIT_FILEBUF_INIT;
+ git_buf file_path = GIT_BUF_INIT;
+ const char *last = NULL;
+ size_t i;
+ int error;
+
+ if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
+ (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_APPEND, GIT_MERGE_FILE_MODE)) < 0)
+ goto cleanup;
+
+ if (git_index_has_conflicts(index))
+ git_filebuf_printf(&file, "\nConflicts:\n");
+
+ for (i = 0; i < git_index_entrycount(index); i++) {
+ const git_index_entry *e = git_index_get_byindex(index, i);
+
+ if (git_index_entry_stage(e) == 0)
+ continue;
+
+ if (last == NULL || strcmp(e->path, last) != 0)
+ git_filebuf_printf(&file, "\t%s\n", e->path);
+
+ last = e->path;
+ }
+
+ error = git_filebuf_commit(&file);
+
+cleanup:
+ if (error < 0)
+ git_filebuf_cleanup(&file);
+
+ git_buf_free(&file_path);
+
+ return error;
+}
+
+
static int merge_state_cleanup(git_repository *repo)
{
const char *state_files[] = {
@@ -2621,6 +2662,7 @@ int git_merge(
if ((error = git_merge_trees(&index_new, repo, ancestor_tree, our_tree, their_trees[0], merge_opts)) < 0 ||
(error = git_merge__indexes(repo, index_new)) < 0 ||
(error = git_repository_index(&index_repo, repo)) < 0 ||
+ (error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 ||
(error = git_checkout_index(repo, index_repo, &checkout_opts)) < 0)
goto on_error;
diff --git a/src/merge.h b/src/merge.h
index 2362da04d..00f6197bf 100644
--- a/src/merge.h
+++ b/src/merge.h
@@ -151,4 +151,6 @@ int git_merge__setup(
int git_merge__indexes(git_repository *repo, git_index *index_new);
+int git_merge__append_conflicts_to_merge_msg(git_repository *repo, git_index *index);
+
#endif
diff --git a/src/revert.c b/src/revert.c
index 4039ec34c..29e124f6c 100644
--- a/src/revert.c
+++ b/src/revert.c
@@ -201,6 +201,7 @@ int git_revert(
(error = git_revert_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
(error = git_merge__indexes(repo, index_new)) < 0 ||
(error = git_repository_index(&index_repo, repo)) < 0 ||
+ (error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 ||
(error = git_checkout_index(repo, index_repo, &opts.checkout_opts)) < 0)
goto on_error;
diff --git a/tests/attr/ignore.c b/tests/attr/ignore.c
index 4ed92387c..a83c5bd74 100644
--- a/tests/attr/ignore.c
+++ b/tests/attr/ignore.c
@@ -130,22 +130,18 @@ void test_attr_ignore__skip_gitignore_directory(void)
void test_attr_ignore__expand_tilde_to_homedir(void)
{
- git_buf path = GIT_BUF_INIT;
+ git_buf cleanup = GIT_BUF_INIT;
git_config *cfg;
assert_is_ignored(false, "example.global_with_tilde");
- /* construct fake home with fake global excludes */
-
- cl_must_pass(p_mkdir("home", 0777));
- cl_git_pass(git_path_prettify(&path, "home", NULL));
- cl_git_pass(git_libgit2_opts(
- GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+ cl_fake_home(&cleanup);
- cl_git_mkfile("home/globalexcludes", "# found me\n*.global_with_tilde\n");
+ /* construct fake home with fake global excludes */
+ cl_git_mkfile("home/globalexclude", "# found me\n*.global_with_tilde\n");
cl_git_pass(git_repository_config(&cfg, g_repo));
- cl_git_pass(git_config_set_string(cfg, "core.excludesfile", "~/globalexcludes"));
+ cl_git_pass(git_config_set_string(cfg, "core.excludesfile", "~/globalexclude"));
git_config_free(cfg);
git_attr_cache_flush(g_repo); /* must reset to pick up change */
@@ -154,8 +150,9 @@ void test_attr_ignore__expand_tilde_to_homedir(void)
cl_git_pass(git_futils_rmdir_r("home", NULL, GIT_RMDIR_REMOVE_FILES));
- cl_git_pass(git_libgit2_opts(
- GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
+ cl_fake_home_cleanup(&cleanup);
- git_buf_free(&path);
+ git_attr_cache_flush(g_repo); /* must reset to pick up change */
+
+ assert_is_ignored(false, "example.global_with_tilde");
}
diff --git a/tests/cherrypick/bare.c b/tests/cherrypick/bare.c
new file mode 100644
index 000000000..7ac1054a1
--- /dev/null
+++ b/tests/cherrypick/bare.c
@@ -0,0 +1,106 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "fileops.h"
+#include "git2/cherrypick.h"
+
+#include "../merge/merge_helpers.h"
+
+#define TEST_REPO_PATH "cherrypick"
+
+static git_repository *repo;
+
+void test_cherrypick_bare__initialize(void)
+{
+ repo = cl_git_sandbox_init(TEST_REPO_PATH);
+}
+
+void test_cherrypick_bare__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+void test_cherrypick_bare__automerge(void)
+{
+ git_commit *head = NULL, *commit = NULL;
+ git_index *index = NULL;
+ git_oid head_oid, cherry_oid;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" },
+ { 0100644, "a661b5dec1004e2c62654ded3762370c27cf266b", 0, "file2.txt" },
+ { 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
+ };
+
+ git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+
+ git_oid_fromstr(&cherry_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+ cl_git_pass(git_cherry_pick_commit(&index, repo, commit, head, 0, NULL));
+ cl_assert(merge_test_index(index, merge_index_entries, 3));
+
+ git_index_free(index);
+ git_commit_free(head);
+ git_commit_free(commit);
+}
+
+void test_cherrypick_bare__conflicts(void)
+{
+ git_commit *head = NULL, *commit = NULL;
+ git_index *index = NULL;
+ git_oid head_oid, cherry_oid;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
+ { 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 1, "file2.txt" },
+ { 0100644, "bd6ffc8c6c41f0f85ff9e3d61c9479516bac0024", 2, "file2.txt" },
+ { 0100644, "563f6473a3858f99b80e5f93c660512ed38e1e6f", 3, "file2.txt" },
+ { 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 1, "file3.txt" },
+ { 0100644, "1124c2c1ae07b26fded662d6c3f3631d9dc16f88", 2, "file3.txt" },
+ { 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" },
+ };
+
+ git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+
+ git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+ cl_git_pass(git_cherry_pick_commit(&index, repo, commit, head, 0, NULL));
+ cl_assert(merge_test_index(index, merge_index_entries, 7));
+
+ git_index_free(index);
+ git_commit_free(head);
+ git_commit_free(commit);
+}
+
+void test_cherrypick_bare__orphan(void)
+{
+ git_commit *head = NULL, *commit = NULL;
+ git_index *index = NULL;
+ git_oid head_oid, cherry_oid;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" },
+ { 0100644, "a661b5dec1004e2c62654ded3762370c27cf266b", 0, "file2.txt" },
+ { 0100644, "85a4a1d791973644f24c72f5e89420d3064cc452", 0, "file3.txt" },
+ { 0100644, "9ccb9bf50c011fd58dcbaa65df917bf79539717f", 0, "orphan.txt" },
+ };
+
+ git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+
+ git_oid_fromstr(&cherry_oid, "74f06b5bfec6d33d7264f73606b57a7c0b963819");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+ cl_git_pass(git_cherry_pick_commit(&index, repo, commit, head, 0, NULL));
+ cl_assert(merge_test_index(index, merge_index_entries, 4));
+
+ git_index_free(index);
+ git_commit_free(head);
+ git_commit_free(commit);
+}
+
diff --git a/tests/cherrypick/workdir.c b/tests/cherrypick/workdir.c
new file mode 100644
index 000000000..581a5f997
--- /dev/null
+++ b/tests/cherrypick/workdir.c
@@ -0,0 +1,429 @@
+#include "clar.h"
+#include "clar_libgit2.h"
+
+#include "buffer.h"
+#include "fileops.h"
+#include "git2/cherrypick.h"
+
+#include "../merge/merge_helpers.h"
+
+#define TEST_REPO_PATH "cherrypick"
+
+static git_repository *repo;
+static git_index *repo_index;
+
+// Fixture setup and teardown
+void test_cherrypick_workdir__initialize(void)
+{
+ repo = cl_git_sandbox_init(TEST_REPO_PATH);
+ git_repository_index(&repo_index, repo);
+}
+
+void test_cherrypick_workdir__cleanup(void)
+{
+ git_index_free(repo_index);
+ cl_git_sandbox_cleanup();
+}
+
+/* git reset --hard d3d77487660ee3c0194ee01dc5eaf478782b1c7e
+ * git cherry-pick cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick 964ea3da044d9083181a88ba6701de9e35778bf4
+ * git cherry-pick a43a050c588d4e92f11a6b139680923e9728477d
+ */
+void test_cherrypick_workdir__automerge(void)
+{
+ git_oid head_oid;
+ git_signature *signature = NULL;
+ size_t i;
+
+ const char *cherry_pick_oids[] = {
+ "cfc4f0999a8367568e049af4f72e452d40828a15",
+ "964ea3da044d9083181a88ba6701de9e35778bf4",
+ "a43a050c588d4e92f11a6b139680923e9728477d",
+ };
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" },
+ { 0100644, "a661b5dec1004e2c62654ded3762370c27cf266b", 0, "file2.txt" },
+ { 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
+
+ { 0100644, "38c05a857e831a7e759d83778bfc85d003e21c45", 0, "file1.txt" },
+ { 0100644, "bd8fc3c59fb52d3c8b5907ace7defa5803f82419", 0, "file2.txt" },
+ { 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
+
+ { 0100644, "f06427bee380364bc7e0cb26a9245158e4726ce0", 0, "file1.txt" },
+ { 0100644, "bd8fc3c59fb52d3c8b5907ace7defa5803f82419", 0, "file2.txt" },
+ { 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
+ };
+
+ cl_git_pass(git_signature_new(&signature, "Picker", "picker@example.org", time(NULL), 0));
+
+ git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
+
+ for (i = 0; i < 3; ++i) {
+ git_commit *head = NULL, *commit = NULL;
+ git_oid cherry_oid, cherry_picked_oid, cherry_picked_tree_oid;
+ git_tree *cherry_picked_tree = NULL;
+
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+
+ git_oid_fromstr(&cherry_oid, cherry_pick_oids[i]);
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+ cl_git_pass(git_cherry_pick(repo, commit, NULL));
+
+ cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
+ cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+
+ cl_git_pass(git_index_write_tree(&cherry_picked_tree_oid, repo_index));
+ cl_git_pass(git_tree_lookup(&cherry_picked_tree, repo, &cherry_picked_tree_oid));
+ cl_git_pass(git_commit_create(&cherry_picked_oid, repo, "HEAD", signature, signature, NULL,
+ "Cherry picked!", cherry_picked_tree, 1, (const git_commit **)&head));
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries + i * 3, 3));
+
+ git_oid_cpy(&head_oid, &cherry_picked_oid);
+
+ git_tree_free(cherry_picked_tree);
+ git_commit_free(head);
+ git_commit_free(commit);
+ }
+
+ git_signature_free(signature);
+}
+
+/* git reset --hard bafbf6912c09505ac60575cd43d3f2aba3bd84d8
+ * git cherry-pick e9b63f3655b2ad80c0ff587389b5a9589a3a7110
+ */
+void test_cherrypick_workdir__conflicts(void)
+{
+ git_commit *head = NULL, *commit = NULL;
+ git_oid head_oid, cherry_oid;
+ git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
+ { 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 1, "file2.txt" },
+ { 0100644, "bd6ffc8c6c41f0f85ff9e3d61c9479516bac0024", 2, "file2.txt" },
+ { 0100644, "563f6473a3858f99b80e5f93c660512ed38e1e6f", 3, "file2.txt" },
+ { 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 1, "file3.txt" },
+ { 0100644, "1124c2c1ae07b26fded662d6c3f3631d9dc16f88", 2, "file3.txt" },
+ { 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" },
+ };
+
+ git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
+
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+
+ git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+ cl_git_pass(git_cherry_pick(repo, commit, NULL));
+
+ cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
+ cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries, 7));
+
+ cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
+ TEST_REPO_PATH "/.git/MERGE_MSG"));
+ cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
+ "Change all files\n" \
+ "\n" \
+ "Conflicts:\n" \
+ "\tfile2.txt\n" \
+ "\tfile3.txt\n") == 0);
+
+ cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+ TEST_REPO_PATH "/file2.txt"));
+
+ cl_assert(strcmp(git_buf_cstr(&conflicting_buf),
+ "!File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2!!\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "File 2\n" \
+ "<<<<<<< HEAD\n" \
+ "File 2\n" \
+ "=======\n" \
+ "File 2!\n" \
+ "File 2\n" \
+ "File 2!\n" \
+ ">>>>>>> e9b63f3... Change all files\n") == 0);
+
+ cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+ TEST_REPO_PATH "/file3.txt"));
+
+ cl_assert(strcmp(git_buf_cstr(&conflicting_buf),
+ "!File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3!!\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "File 3\n" \
+ "<<<<<<< HEAD\n" \
+ "=======\n" \
+ "File 3!\n" \
+ "File 3!\n" \
+ ">>>>>>> e9b63f3... Change all files\n") == 0);
+
+ git_commit_free(commit);
+ git_commit_free(head);
+ git_buf_free(&mergemsg_buf);
+ git_buf_free(&conflicting_buf);
+}
+
+/* git reset --hard bafbf6912c09505ac60575cd43d3f2aba3bd84d8
+ * git cherry-pick -X ours e9b63f3655b2ad80c0ff587389b5a9589a3a7110
+ */
+void test_cherrypick_workdir__conflict_use_ours(void)
+{
+ git_commit *head = NULL, *commit = NULL;
+ git_oid head_oid, cherry_oid;
+ git_cherry_pick_options opts = GIT_CHERRY_PICK_OPTIONS_INIT;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
+ { 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 1, "file2.txt" },
+ { 0100644, "bd6ffc8c6c41f0f85ff9e3d61c9479516bac0024", 2, "file2.txt" },
+ { 0100644, "563f6473a3858f99b80e5f93c660512ed38e1e6f", 3, "file2.txt" },
+ { 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 1, "file3.txt" },
+ { 0100644, "1124c2c1ae07b26fded662d6c3f3631d9dc16f88", 2, "file3.txt" },
+ { 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" },
+ };
+
+ struct merge_index_entry merge_filesystem_entries[] = {
+ { 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
+ { 0100644, "bd6ffc8c6c41f0f85ff9e3d61c9479516bac0024", 0, "file2.txt" },
+ { 0100644, "1124c2c1ae07b26fded662d6c3f3631d9dc16f88", 0, "file3.txt" },
+ };
+
+ /* leave the index in a conflicted state, but checkout "ours" to the workdir */
+ opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS;
+
+ git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
+
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+
+ git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+ cl_git_pass(git_cherry_pick(repo, commit, &opts));
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries, 7));
+ cl_assert(merge_test_workdir(repo, merge_filesystem_entries, 3));
+
+ /* resolve conflicts in the index by taking "ours" */
+ opts.merge_opts.file_favor = GIT_MERGE_FILE_FAVOR_OURS;
+
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+ cl_git_pass(git_cherry_pick(repo, commit, &opts));
+
+ cl_assert(merge_test_index(repo_index, merge_filesystem_entries, 3));
+ cl_assert(merge_test_workdir(repo, merge_filesystem_entries, 3));
+
+ git_commit_free(commit);
+ git_commit_free(head);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick 2a26c7e88b285613b302ba76712bc998863f3cbc
+ */
+void test_cherrypick_workdir__rename(void)
+{
+ git_commit *head, *commit;
+ git_oid head_oid, cherry_oid;
+ git_cherry_pick_options opts = GIT_CHERRY_PICK_OPTIONS_INIT;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "19c5c7207054604b69c84d08a7571ef9672bb5c2", 0, "file1.txt" },
+ { 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 0, "file2.txt" },
+ { 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 0, "file3.txt.renamed" },
+ };
+
+ opts.merge_opts.flags |= GIT_MERGE_TREE_FIND_RENAMES;
+ opts.merge_opts.rename_threshold = 50;
+
+ git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+
+ git_oid_fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+ cl_git_pass(git_cherry_pick(repo, commit, &opts));
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+ git_commit_free(commit);
+ git_commit_free(head);
+}
+
+/* git reset --hard 44cd2ed2052c9c68f9a439d208e9614dc2a55c70
+ * git cherry-pick 2a26c7e88b285613b302ba76712bc998863f3cbc
+ */
+void test_cherrypick_workdir__both_renamed(void)
+{
+ git_commit *head, *commit;
+ git_oid head_oid, cherry_oid;
+ git_buf mergemsg_buf = GIT_BUF_INIT;
+ git_cherry_pick_options opts = GIT_CHERRY_PICK_OPTIONS_INIT;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "19c5c7207054604b69c84d08a7571ef9672bb5c2", 0, "file1.txt" },
+ { 0100644, "a58ca3fee5eb68b11adc2703e5843f968c9dad1e", 0, "file2.txt" },
+ { 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 1, "file3.txt" },
+ { 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt.renamed" },
+ { 0100644, "28d9eb4208074ad1cc84e71ccc908b34573f05d2", 2, "file3.txt.renamed_on_branch" },
+ };
+
+ opts.merge_opts.flags |= GIT_MERGE_TREE_FIND_RENAMES;
+ opts.merge_opts.rename_threshold = 50;
+
+ git_oid_fromstr(&head_oid, "44cd2ed2052c9c68f9a439d208e9614dc2a55c70");
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+
+ git_oid_fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+ cl_git_pass(git_cherry_pick(repo, commit, &opts));
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries, 5));
+
+ cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
+ TEST_REPO_PATH "/.git/MERGE_MSG"));
+ cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
+ "Renamed file3.txt -> file3.txt.renamed\n" \
+ "\n" \
+ "Conflicts:\n" \
+ "\tfile3.txt\n" \
+ "\tfile3.txt.renamed\n" \
+ "\tfile3.txt.renamed_on_branch\n") == 0);
+
+ git_buf_free(&mergemsg_buf);
+ git_commit_free(commit);
+ git_commit_free(head);
+}
+
+void test_cherrypick_workdir__nonmerge_fails_mainline_specified(void)
+{
+ git_reference *head;
+ git_commit *commit;
+ git_cherry_pick_options opts = GIT_CHERRY_PICK_OPTIONS_INIT;
+
+ cl_git_pass(git_repository_head(&head, repo));
+ cl_git_pass(git_reference_peel((git_object **)&commit, head, GIT_OBJ_COMMIT));
+
+ opts.mainline = 1;
+ cl_must_fail(git_cherry_pick(repo, commit, &opts));
+ cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
+ cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+
+ git_reference_free(head);
+ git_commit_free(commit);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick abe4603bc7cd5b8167a267e0e2418fd2348f8cff
+ */
+void test_cherrypick_workdir__merge_fails_without_mainline_specified(void)
+{
+ git_commit *head, *commit;
+ git_oid head_oid, cherry_oid;
+
+ git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+
+ git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+ cl_must_fail(git_cherry_pick(repo, commit, NULL));
+ cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
+ cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+
+ git_commit_free(commit);
+ git_commit_free(head);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick -m1 abe4603bc7cd5b8167a267e0e2418fd2348f8cff
+ */
+void test_cherrypick_workdir__merge_first_parent(void)
+{
+ git_commit *head, *commit;
+ git_oid head_oid, cherry_oid;
+ git_cherry_pick_options opts = GIT_CHERRY_PICK_OPTIONS_INIT;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "f90f9dcbdac2cce5cc166346160e19cb693ef4e8", 0, "file1.txt" },
+ { 0100644, "563f6473a3858f99b80e5f93c660512ed38e1e6f", 0, "file2.txt" },
+ { 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 0, "file3.txt" },
+ };
+
+ opts.mainline = 1;
+
+ git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+
+ git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+ cl_git_pass(git_cherry_pick(repo, commit, &opts));
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+ git_commit_free(commit);
+ git_commit_free(head);
+}
+
+/* git reset --hard cfc4f0999a8367568e049af4f72e452d40828a15
+ * git cherry-pick -m2 abe4603bc7cd5b8167a267e0e2418fd2348f8cff
+ */
+void test_cherrypick_workdir__merge_second_parent(void)
+{
+ git_commit *head, *commit;
+ git_oid head_oid, cherry_oid;
+ git_cherry_pick_options opts = GIT_CHERRY_PICK_OPTIONS_INIT;
+
+ struct merge_index_entry merge_index_entries[] = {
+ { 0100644, "487434cace79238a7091e2220611d4f20a765690", 0, "file1.txt" },
+ { 0100644, "e5183bfd18e3a0a691fadde2f0d5610b73282d31", 0, "file2.txt" },
+ { 0100644, "409a1bec58bf35348e8b62b72bb9c1f45cf5a587", 0, "file3.txt" },
+ };
+
+ opts.mainline = 2;
+
+ git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
+ cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
+ cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL, NULL));
+
+ git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
+ cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
+
+ cl_git_pass(git_cherry_pick(repo, commit, &opts));
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries, 3));
+
+ git_commit_free(commit);
+ git_commit_free(head);
+}
+
diff --git a/tests/clar_libgit2.c b/tests/clar_libgit2.c
index 9b062ef78..90e53c5e6 100644
--- a/tests/clar_libgit2.c
+++ b/tests/clar_libgit2.c
@@ -490,3 +490,24 @@ void clar__assert_equal_file(
clar__assert_equal(file, line, "mismatched file length", 1, "%"PRIuZ,
(size_t)expected_bytes, (size_t)total_bytes);
}
+
+void cl_fake_home(git_buf *restore)
+{
+ git_buf path = GIT_BUF_INIT;
+
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, restore));
+
+ cl_must_pass(p_mkdir("home", 0777));
+ cl_git_pass(git_path_prettify(&path, "home", NULL));
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
+ git_buf_free(&path);
+}
+
+void cl_fake_home_cleanup(git_buf *restore)
+{
+ cl_git_pass(git_libgit2_opts(
+ GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, restore->ptr));
+ git_buf_free(restore);
+}
diff --git a/tests/clar_libgit2.h b/tests/clar_libgit2.h
index 3de80bfa0..c2489db38 100644
--- a/tests/clar_libgit2.h
+++ b/tests/clar_libgit2.h
@@ -120,4 +120,7 @@ int cl_repo_get_bool(git_repository *repo, const char *cfg);
void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value);
+void cl_fake_home(git_buf *restore);
+void cl_fake_home_cleanup(git_buf *restore);
+
#endif
diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c
index 032e97f8d..cf5b16e7a 100644
--- a/tests/merge/workdir/simple.c
+++ b/tests/merge/workdir/simple.c
@@ -214,7 +214,7 @@ void test_merge_workdir_simple__automerge_crlf(void)
void test_merge_workdir_simple__mergefile(void)
{
- git_buf conflicting_buf = GIT_BUF_INIT;
+ git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT;
struct merge_index_entry merge_index_entries[] = {
ADDED_IN_MASTER_INDEX_ENTRY,
@@ -240,7 +240,15 @@ void test_merge_workdir_simple__mergefile(void)
cl_git_pass(git_futils_readbuffer(&conflicting_buf,
TEST_REPO_PATH "/conflicting.txt"));
cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_MERGE_FILE) == 0);
+ cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
+ TEST_REPO_PATH "/.git/MERGE_MSG"));
+ cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
+ "Merge commit '7cb63eed597130ba4abb87b3e544b85021905520'\n" \
+ "\n" \
+ "Conflicts:\n" \
+ "\tconflicting.txt\n") == 0);
git_buf_free(&conflicting_buf);
+ git_buf_free(&mergemsg_buf);
cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
diff --git a/tests/refs/branches/iterator.c b/tests/refs/branches/iterator.c
index 29ca59aca..76b35a7d6 100644
--- a/tests/refs/branches/iterator.c
+++ b/tests/refs/branches/iterator.c
@@ -48,7 +48,7 @@ static void assert_retrieval(unsigned int flags, unsigned int expected_count)
void test_refs_branches_iterator__retrieve_all_branches(void)
{
- assert_retrieval(GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE, 14);
+ assert_retrieval(GIT_BRANCH_ALL, 14);
}
void test_refs_branches_iterator__retrieve_remote_branches(void)
@@ -139,7 +139,7 @@ void test_refs_branches_iterator__mix_of_packed_and_loose(void)
r2 = cl_git_sandbox_init("testrepo2");
- cl_git_pass(git_branch_iterator_new(&iter, r2, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE));
+ cl_git_pass(git_branch_iterator_new(&iter, r2, GIT_BRANCH_ALL));
contains_branches(exp, iter);
git_branch_iterator_free(iter);
diff --git a/tests/repo/open.c b/tests/repo/open.c
index f7420bd3a..190adff1c 100644
--- a/tests/repo/open.c
+++ b/tests/repo/open.c
@@ -102,14 +102,13 @@ void test_repo_open__gitlinked(void)
void test_repo_open__from_git_new_workdir(void)
{
+#ifndef GIT_WIN32
/* The git-new-workdir script that ships with git sets up a bunch of
* symlinks to create a second workdir that shares the object db with
* another checkout. Libgit2 can open a repo that has been configured
* this way.
*/
- cl_git_sandbox_init("empty_standard_repo");
-#ifndef GIT_WIN32
git_repository *repo2;
git_buf link_tgt = GIT_BUF_INIT, link = GIT_BUF_INIT, body = GIT_BUF_INIT;
const char **scan;
@@ -122,6 +121,8 @@ void test_repo_open__from_git_new_workdir(void)
"HEAD", NULL
};
+ cl_git_sandbox_init("empty_standard_repo");
+
cl_git_pass(p_mkdir("alternate", 0777));
cl_git_pass(p_mkdir("alternate/.git", 0777));
diff --git a/tests/resources/cherrypick/.gitted/HEAD b/tests/resources/cherrypick/.gitted/HEAD
new file mode 100644
index 000000000..656ac0e0a
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/automerge-branch
diff --git a/tests/resources/cherrypick/.gitted/config b/tests/resources/cherrypick/.gitted/config
new file mode 100644
index 000000000..6c9406b7d
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/config
@@ -0,0 +1,7 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
+ precomposeunicode = true
diff --git a/tests/resources/cherrypick/.gitted/index b/tests/resources/cherrypick/.gitted/index
new file mode 100644
index 000000000..7291006c8
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/index
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/info/exclude b/tests/resources/cherrypick/.gitted/info/exclude
new file mode 100644
index 000000000..a5196d1be
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/info/exclude
@@ -0,0 +1,6 @@
+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/tests/resources/cherrypick/.gitted/objects/01/a2b453c2647c71ccfefc285f2266d1f00b8253 b/tests/resources/cherrypick/.gitted/objects/01/a2b453c2647c71ccfefc285f2266d1f00b8253
new file mode 100644
index 000000000..736a7f57b
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/01/a2b453c2647c71ccfefc285f2266d1f00b8253
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/02/67838e09bbc5969bba035be2d27c8a6de694d8 b/tests/resources/cherrypick/.gitted/objects/02/67838e09bbc5969bba035be2d27c8a6de694d8
new file mode 100644
index 000000000..4eacb26f5
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/02/67838e09bbc5969bba035be2d27c8a6de694d8
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/06/3fc9f01e6e9ec2a8d8f749885e931875e50d37 b/tests/resources/cherrypick/.gitted/objects/06/3fc9f01e6e9ec2a8d8f749885e931875e50d37
new file mode 100644
index 000000000..48fa6efcd
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/06/3fc9f01e6e9ec2a8d8f749885e931875e50d37
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/08/9ac03f76058b5ba0b44bb268f317f9242481e9 b/tests/resources/cherrypick/.gitted/objects/08/9ac03f76058b5ba0b44bb268f317f9242481e9
new file mode 100644
index 000000000..06d1c694e
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/08/9ac03f76058b5ba0b44bb268f317f9242481e9
@@ -0,0 +1,3 @@
+xA
+0@Q9i"`LBMӅܾ)籂#բ
+^CNb+%bRU!z1Jh)JO}딼 b>WI \qyϟ 祖QҔO`D6{tfm_sy@2("O- \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/0d/447a6c2528b06616cde3b209a4b4ea3dcb8d65 b/tests/resources/cherrypick/.gitted/objects/0d/447a6c2528b06616cde3b209a4b4ea3dcb8d65
new file mode 100644
index 000000000..9a3ea3209
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/0d/447a6c2528b06616cde3b209a4b4ea3dcb8d65
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/11/24c2c1ae07b26fded662d6c3f3631d9dc16f88 b/tests/resources/cherrypick/.gitted/objects/11/24c2c1ae07b26fded662d6c3f3631d9dc16f88
new file mode 100644
index 000000000..62abc3c5b
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/11/24c2c1ae07b26fded662d6c3f3631d9dc16f88
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/12/905f4ea5b76f9d3fdcfe73e462201c06ae632a b/tests/resources/cherrypick/.gitted/objects/12/905f4ea5b76f9d3fdcfe73e462201c06ae632a
new file mode 100644
index 000000000..162844a70
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/12/905f4ea5b76f9d3fdcfe73e462201c06ae632a
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/19/c5c7207054604b69c84d08a7571ef9672bb5c2 b/tests/resources/cherrypick/.gitted/objects/19/c5c7207054604b69c84d08a7571ef9672bb5c2
new file mode 100644
index 000000000..d5cd6d3f2
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/19/c5c7207054604b69c84d08a7571ef9672bb5c2
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/1c/2116845780455ecf916538c1cc27c4222452af b/tests/resources/cherrypick/.gitted/objects/1c/2116845780455ecf916538c1cc27c4222452af
new file mode 100644
index 000000000..f9a841d4f
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/1c/2116845780455ecf916538c1cc27c4222452af
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/1c/c85eb4ff0a8438fde1b14274c6f87f891b36a0 b/tests/resources/cherrypick/.gitted/objects/1c/c85eb4ff0a8438fde1b14274c6f87f891b36a0
new file mode 100644
index 000000000..98b792b64
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/1c/c85eb4ff0a8438fde1b14274c6f87f891b36a0
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/1e/1cb7391d25dcd8daba88f1f627f3045982286c b/tests/resources/cherrypick/.gitted/objects/1e/1cb7391d25dcd8daba88f1f627f3045982286c
new file mode 100644
index 000000000..10a5be6fe
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/1e/1cb7391d25dcd8daba88f1f627f3045982286c
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/20/fc1a4c9d994021f43d33ab75e4252e27ca661d b/tests/resources/cherrypick/.gitted/objects/20/fc1a4c9d994021f43d33ab75e4252e27ca661d
new file mode 100644
index 000000000..c8b26cd01
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/20/fc1a4c9d994021f43d33ab75e4252e27ca661d
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/28/d9eb4208074ad1cc84e71ccc908b34573f05d2 b/tests/resources/cherrypick/.gitted/objects/28/d9eb4208074ad1cc84e71ccc908b34573f05d2
new file mode 100644
index 000000000..80363b016
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/28/d9eb4208074ad1cc84e71ccc908b34573f05d2
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/2a/26c7e88b285613b302ba76712bc998863f3cbc b/tests/resources/cherrypick/.gitted/objects/2a/26c7e88b285613b302ba76712bc998863f3cbc
new file mode 100644
index 000000000..283113999
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/2a/26c7e88b285613b302ba76712bc998863f3cbc
@@ -0,0 +1 @@
+xMj0)f_j]`$*N1C=@{^YZlLOҙUzub/X1"iuWN9b҄ZS&r4mrY:Qo+6{/{?gҎ`\k-<k>U_u+5Οx9a?7W \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/2a/c3b376093de405b0a951bff578655b1c2b7fa1 b/tests/resources/cherrypick/.gitted/objects/2a/c3b376093de405b0a951bff578655b1c2b7fa1
new file mode 100644
index 000000000..a3294d764
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/2a/c3b376093de405b0a951bff578655b1c2b7fa1
@@ -0,0 +1 @@
+xJ0E]+fIwGLk ܞ{VG{כ*A9Ěc:PܔCJBk\2]}jPQD6b95xuO7v}{[c3 ޢԮ#E̻yɚgToPM/X \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/2c/acbcaabf785f1ac231e8519849d4ad38692f2c b/tests/resources/cherrypick/.gitted/objects/2c/acbcaabf785f1ac231e8519849d4ad38692f2c
new file mode 100644
index 000000000..74b48dd6b
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/2c/acbcaabf785f1ac231e8519849d4ad38692f2c
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/35/cb210149022c7379b0a67b0dec13cc628ff87d b/tests/resources/cherrypick/.gitted/objects/35/cb210149022c7379b0a67b0dec13cc628ff87d
new file mode 100644
index 000000000..c0466f46a
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/35/cb210149022c7379b0a67b0dec13cc628ff87d
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/38/c05a857e831a7e759d83778bfc85d003e21c45 b/tests/resources/cherrypick/.gitted/objects/38/c05a857e831a7e759d83778bfc85d003e21c45
new file mode 100644
index 000000000..d4f1cf8ac
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/38/c05a857e831a7e759d83778bfc85d003e21c45
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/3f/9eed8946df9e2c737d3b8dc0b8e78959aacd92 b/tests/resources/cherrypick/.gitted/objects/3f/9eed8946df9e2c737d3b8dc0b8e78959aacd92
new file mode 100644
index 000000000..8c4d6d94f
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/3f/9eed8946df9e2c737d3b8dc0b8e78959aacd92
@@ -0,0 +1,5 @@
+xMj0)fjH]dԸDq#޾
+-t=YJ`HOt.DSJN.1I#gUo $ eR8ɇgj/F]
+,MW8j-zپVxyk37d){pc
+hn
+bNzgUǡ}6xz*V8 \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/40/9a1bec58bf35348e8b62b72bb9c1f45cf5a587 b/tests/resources/cherrypick/.gitted/objects/40/9a1bec58bf35348e8b62b72bb9c1f45cf5a587
new file mode 100644
index 000000000..60d5dca4a
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/40/9a1bec58bf35348e8b62b72bb9c1f45cf5a587
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/44/cd2ed2052c9c68f9a439d208e9614dc2a55c70 b/tests/resources/cherrypick/.gitted/objects/44/cd2ed2052c9c68f9a439d208e9614dc2a55c70
new file mode 100644
index 000000000..8697c4e66
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/44/cd2ed2052c9c68f9a439d208e9614dc2a55c70
@@ -0,0 +1 @@
+xN0C9+推$M$đX&i!M%{ gɲZpכ.0c$etBPpLꃛ,RITtA4E.TFrI lOkNl,۴oxcoO[o3wZO`lD.V=vWzd(ءux8O.K%M?Z \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/48/7434cace79238a7091e2220611d4f20a765690 b/tests/resources/cherrypick/.gitted/objects/48/7434cace79238a7091e2220611d4f20a765690
new file mode 100644
index 000000000..a1fa599e1
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/48/7434cace79238a7091e2220611d4f20a765690
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/49/20ad2f17162dcc8823ad491444dcb87f5899c9 b/tests/resources/cherrypick/.gitted/objects/49/20ad2f17162dcc8823ad491444dcb87f5899c9
new file mode 100644
index 000000000..bf96fccad
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/49/20ad2f17162dcc8823ad491444dcb87f5899c9
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/tests/resources/cherrypick/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
new file mode 100644
index 000000000..adf64119a
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/4c/532774cc1fea37f6efc2256763a64d38c8cdde b/tests/resources/cherrypick/.gitted/objects/4c/532774cc1fea37f6efc2256763a64d38c8cdde
new file mode 100644
index 000000000..2e56d7403
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/4c/532774cc1fea37f6efc2256763a64d38c8cdde
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/51/145af30d411a50195b66517d825e69bf57ed22 b/tests/resources/cherrypick/.gitted/objects/51/145af30d411a50195b66517d825e69bf57ed22
new file mode 100644
index 000000000..3e01376bd
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/51/145af30d411a50195b66517d825e69bf57ed22
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/54/61de53ffadbf15be4dd6345997c15689573209 b/tests/resources/cherrypick/.gitted/objects/54/61de53ffadbf15be4dd6345997c15689573209
new file mode 100644
index 000000000..7d2b233a6
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/54/61de53ffadbf15be4dd6345997c15689573209
@@ -0,0 +1,4 @@
+xMj0)fjH]dԸDq#޾
+-t=YJ`HOt.DSJN.1I#gUo $ eR8ɇgj/F]
+,MW8j-zپVxyk37d){pc
+hn?Js=C:O #6V< \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/54/784f10955e92ab27e4fa832e40cb2baf1edbdc b/tests/resources/cherrypick/.gitted/objects/54/784f10955e92ab27e4fa832e40cb2baf1edbdc
new file mode 100644
index 000000000..2a5bcec27
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/54/784f10955e92ab27e4fa832e40cb2baf1edbdc
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/56/3f6473a3858f99b80e5f93c660512ed38e1e6f b/tests/resources/cherrypick/.gitted/objects/56/3f6473a3858f99b80e5f93c660512ed38e1e6f
new file mode 100644
index 000000000..8847ed689
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/56/3f6473a3858f99b80e5f93c660512ed38e1e6f
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/58/a957ef0061c1a8ef995c855dfab4f5da8d6617 b/tests/resources/cherrypick/.gitted/objects/58/a957ef0061c1a8ef995c855dfab4f5da8d6617
new file mode 100644
index 000000000..f161a1941
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/58/a957ef0061c1a8ef995c855dfab4f5da8d6617
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/5d/c7e1f440ce74d5503a0dfbc6c30e091475f774 b/tests/resources/cherrypick/.gitted/objects/5d/c7e1f440ce74d5503a0dfbc6c30e091475f774
new file mode 100644
index 000000000..77deeaf0b
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/5d/c7e1f440ce74d5503a0dfbc6c30e091475f774
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/5e/2206cda1c56430ad107a6866a829c159e0b9ea b/tests/resources/cherrypick/.gitted/objects/5e/2206cda1c56430ad107a6866a829c159e0b9ea
new file mode 100644
index 000000000..aa30f501f
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/5e/2206cda1c56430ad107a6866a829c159e0b9ea
@@ -0,0 +1 @@
+x+)JMU044d040031QHI5+(aU E9s\uIXvKY;7nM3KdF"cx?35זzѨ1* \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/5f/77a2a13935ac62a629553f8944ad57b1ed8b4a b/tests/resources/cherrypick/.gitted/objects/5f/77a2a13935ac62a629553f8944ad57b1ed8b4a
new file mode 100644
index 000000000..5e622a1fa
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/5f/77a2a13935ac62a629553f8944ad57b1ed8b4a
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/63/c0d92b95253c4a40d3883f423a54be47d2c4c8 b/tests/resources/cherrypick/.gitted/objects/63/c0d92b95253c4a40d3883f423a54be47d2c4c8
new file mode 100644
index 000000000..eafe2c30a
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/63/c0d92b95253c4a40d3883f423a54be47d2c4c8
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/6c/e83eb5f0fd34a10c3d25c6b36d2ed7ec0d6ce7 b/tests/resources/cherrypick/.gitted/objects/6c/e83eb5f0fd34a10c3d25c6b36d2ed7ec0d6ce7
new file mode 100644
index 000000000..1c1f5034d
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/6c/e83eb5f0fd34a10c3d25c6b36d2ed7ec0d6ce7
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/6d/1c2afe5eeb9e497528e2780ac468a5465cbc96 b/tests/resources/cherrypick/.gitted/objects/6d/1c2afe5eeb9e497528e2780ac468a5465cbc96
new file mode 100644
index 000000000..a98378a70
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/6d/1c2afe5eeb9e497528e2780ac468a5465cbc96
@@ -0,0 +1 @@
+x=j@@{ fvLpgp3̎FժmҾɺ,s7U$ 1 :HEc.d*1Qp5nzTh}A"I.SA:Hys }Z\YvminpymGYo`$DծBO{L|f^OA \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/74/f06b5bfec6d33d7264f73606b57a7c0b963819 b/tests/resources/cherrypick/.gitted/objects/74/f06b5bfec6d33d7264f73606b57a7c0b963819
new file mode 100644
index 000000000..732011fce
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/74/f06b5bfec6d33d7264f73606b57a7c0b963819
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/82/8b08c52d2cba30952e0e008f60b25b5ba0d41a b/tests/resources/cherrypick/.gitted/objects/82/8b08c52d2cba30952e0e008f60b25b5ba0d41a
new file mode 100644
index 000000000..302014bff
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/82/8b08c52d2cba30952e0e008f60b25b5ba0d41a
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/85/36dd6f0ec3ddecb9f9b6c8c64c6d322cd01211 b/tests/resources/cherrypick/.gitted/objects/85/36dd6f0ec3ddecb9f9b6c8c64c6d322cd01211
new file mode 100644
index 000000000..db6faa9e2
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/85/36dd6f0ec3ddecb9f9b6c8c64c6d322cd01211
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/85/a4a1d791973644f24c72f5e89420d3064cc452 b/tests/resources/cherrypick/.gitted/objects/85/a4a1d791973644f24c72f5e89420d3064cc452
new file mode 100644
index 000000000..7fe69b6f8
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/85/a4a1d791973644f24c72f5e89420d3064cc452
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/8b/5c30499a71001189b647f4d5b57fa8f04897ce b/tests/resources/cherrypick/.gitted/objects/8b/5c30499a71001189b647f4d5b57fa8f04897ce
new file mode 100644
index 000000000..8b1638fbb
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/8b/5c30499a71001189b647f4d5b57fa8f04897ce
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/96/4ea3da044d9083181a88ba6701de9e35778bf4 b/tests/resources/cherrypick/.gitted/objects/96/4ea3da044d9083181a88ba6701de9e35778bf4
new file mode 100644
index 000000000..2dec33f69
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/96/4ea3da044d9083181a88ba6701de9e35778bf4
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/9c/c39fca3765a2facbe31157f7d60c2602193f36 b/tests/resources/cherrypick/.gitted/objects/9c/c39fca3765a2facbe31157f7d60c2602193f36
new file mode 100644
index 000000000..00314454f
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/9c/c39fca3765a2facbe31157f7d60c2602193f36
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/9c/cb9bf50c011fd58dcbaa65df917bf79539717f b/tests/resources/cherrypick/.gitted/objects/9c/cb9bf50c011fd58dcbaa65df917bf79539717f
new file mode 100644
index 000000000..1266aff36
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/9c/cb9bf50c011fd58dcbaa65df917bf79539717f
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/a1/0b59f4280491afe6e430c30654a7acc67d4a33 b/tests/resources/cherrypick/.gitted/objects/a1/0b59f4280491afe6e430c30654a7acc67d4a33
new file mode 100644
index 000000000..7aa0a5dcd
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/a1/0b59f4280491afe6e430c30654a7acc67d4a33
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/a2/1b4bfe7a04ab18024fb57f4ae9a52a1acef394 b/tests/resources/cherrypick/.gitted/objects/a2/1b4bfe7a04ab18024fb57f4ae9a52a1acef394
new file mode 100644
index 000000000..07b7195d2
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/a2/1b4bfe7a04ab18024fb57f4ae9a52a1acef394
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/a4/3a050c588d4e92f11a6b139680923e9728477d b/tests/resources/cherrypick/.gitted/objects/a4/3a050c588d4e92f11a6b139680923e9728477d
new file mode 100644
index 000000000..4713fb2db
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/a4/3a050c588d4e92f11a6b139680923e9728477d
@@ -0,0 +1 @@
+xMj0uHBb4.J2G㽔qW9l=#`5GsDD5(ꋪlX!p!e$2N2{9IїWemו:y/om7pB]Q mw`^þA6 mT \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/a5/8ca3fee5eb68b11adc2703e5843f968c9dad1e b/tests/resources/cherrypick/.gitted/objects/a5/8ca3fee5eb68b11adc2703e5843f968c9dad1e
new file mode 100644
index 000000000..1c3f2fb01
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/a5/8ca3fee5eb68b11adc2703e5843f968c9dad1e
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/a6/61b5dec1004e2c62654ded3762370c27cf266b b/tests/resources/cherrypick/.gitted/objects/a6/61b5dec1004e2c62654ded3762370c27cf266b
new file mode 100644
index 000000000..d94a9541f
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/a6/61b5dec1004e2c62654ded3762370c27cf266b
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/a6/9ef8fcbb9a2c509a7dbf4f23d257eb551d5610 b/tests/resources/cherrypick/.gitted/objects/a6/9ef8fcbb9a2c509a7dbf4f23d257eb551d5610
new file mode 100644
index 000000000..69feba205
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/a6/9ef8fcbb9a2c509a7dbf4f23d257eb551d5610
@@ -0,0 +1 @@
+x10@ѭuA,!] `,/hrǰGHKs՛*he8J*(&rTlJI؅$JD%YF}ipt:kot9楞`p)95]?}nsSnjGPOL \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/a8/3c6f70297b805dedc549e6583582966f6ebcab b/tests/resources/cherrypick/.gitted/objects/a8/3c6f70297b805dedc549e6583582966f6ebcab
new file mode 100644
index 000000000..5a6db508e
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/a8/3c6f70297b805dedc549e6583582966f6ebcab
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/a9/020cd240774e4d672732bcb82d516d9685da76 b/tests/resources/cherrypick/.gitted/objects/a9/020cd240774e4d672732bcb82d516d9685da76
new file mode 100644
index 000000000..61741aff9
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/a9/020cd240774e4d672732bcb82d516d9685da76
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/ab/4115f808bc585b60f822da7020af86d20f62c8 b/tests/resources/cherrypick/.gitted/objects/ab/4115f808bc585b60f822da7020af86d20f62c8
new file mode 100644
index 000000000..08c4bef57
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/ab/4115f808bc585b60f822da7020af86d20f62c8
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/ab/e4603bc7cd5b8167a267e0e2418fd2348f8cff b/tests/resources/cherrypick/.gitted/objects/ab/e4603bc7cd5b8167a267e0e2418fd2348f8cff
new file mode 100644
index 000000000..4e4fe6f12
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/ab/e4603bc7cd5b8167a267e0e2418fd2348f8cff
@@ -0,0 +1,4 @@
+xKN0DY?B쐐8DӞHNqܞF'ƇT!`*<+,YZ
+%LވلM쓖X$N$S.cq89
+Dޚo{xFL)Ɣ}em] ^wv~z,&?iGz\//rS`^
+=ݣXfZ \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/b8/26e9b36e22e949ec885e7a1f3db496bbab6cd0 b/tests/resources/cherrypick/.gitted/objects/b8/26e9b36e22e949ec885e7a1f3db496bbab6cd0
new file mode 100644
index 000000000..e3bf3a017
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/b8/26e9b36e22e949ec885e7a1f3db496bbab6cd0
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/ba/fbf6912c09505ac60575cd43d3f2aba3bd84d8 b/tests/resources/cherrypick/.gitted/objects/ba/fbf6912c09505ac60575cd43d3f2aba3bd84d8
new file mode 100644
index 000000000..956da8b71
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/ba/fbf6912c09505ac60575cd43d3f2aba3bd84d8
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/bb/14296ffa9dfbf935ec9ce2f9ed7808d952226b b/tests/resources/cherrypick/.gitted/objects/bb/14296ffa9dfbf935ec9ce2f9ed7808d952226b
new file mode 100644
index 000000000..b5583685a
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/bb/14296ffa9dfbf935ec9ce2f9ed7808d952226b
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/bc/4dd0744364d1db380a9811bd264c101065231e b/tests/resources/cherrypick/.gitted/objects/bc/4dd0744364d1db380a9811bd264c101065231e
new file mode 100644
index 000000000..01d88a283
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/bc/4dd0744364d1db380a9811bd264c101065231e
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/bd/65d4083845ed5ed4e1fe5feb85ac395d0760c8 b/tests/resources/cherrypick/.gitted/objects/bd/65d4083845ed5ed4e1fe5feb85ac395d0760c8
new file mode 100644
index 000000000..6a0eccb5e
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/bd/65d4083845ed5ed4e1fe5feb85ac395d0760c8
@@ -0,0 +1,2 @@
+xA
+B!֞bA6BD[o^@$ݾj-ڛtf]#":dKi 51S@Rq:<b~Op^gmH/Q)z}jCpDvEK< \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/bd/6ffc8c6c41f0f85ff9e3d61c9479516bac0024 b/tests/resources/cherrypick/.gitted/objects/bd/6ffc8c6c41f0f85ff9e3d61c9479516bac0024
new file mode 100644
index 000000000..56f836779
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/bd/6ffc8c6c41f0f85ff9e3d61c9479516bac0024
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/bd/a51965cb36c0c5731c8cb50b80a36cac81018e b/tests/resources/cherrypick/.gitted/objects/bd/a51965cb36c0c5731c8cb50b80a36cac81018e
new file mode 100644
index 000000000..1187a7089
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/bd/a51965cb36c0c5731c8cb50b80a36cac81018e
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/ce/d8fb81b6ec534d5deaf2a48b4b96c799712507 b/tests/resources/cherrypick/.gitted/objects/ce/d8fb81b6ec534d5deaf2a48b4b96c799712507
new file mode 100644
index 000000000..569ee0c99
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/ce/d8fb81b6ec534d5deaf2a48b4b96c799712507
@@ -0,0 +1 @@
+xJ0@ay?] d2i+7)[~á6afYH1K%+E!(>q>qehM}P!:Cxεu!xXϟC>}ṟ,I炓ĥE9{0;KZq_˺Yt3V \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/cf/c4f0999a8367568e049af4f72e452d40828a15 b/tests/resources/cherrypick/.gitted/objects/cf/c4f0999a8367568e049af4f72e452d40828a15
new file mode 100644
index 000000000..d7deb0bff
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/cf/c4f0999a8367568e049af4f72e452d40828a15
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/d0/f21e17beb5b9d953b1d8349049818a4f2edd1e b/tests/resources/cherrypick/.gitted/objects/d0/f21e17beb5b9d953b1d8349049818a4f2edd1e
new file mode 100644
index 000000000..65c846fa4
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/d0/f21e17beb5b9d953b1d8349049818a4f2edd1e
@@ -0,0 +1 @@
+xAj0E)f_,]z<]"޾!<^l4f=iM0Hir: <kiFGhI}S] 4F qfʚl蔵6svׯ[i ]R-7  uà:OI)p[!/=;&WY \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/d3/d77487660ee3c0194ee01dc5eaf478782b1c7e b/tests/resources/cherrypick/.gitted/objects/d3/d77487660ee3c0194ee01dc5eaf478782b1c7e
new file mode 100644
index 000000000..b42df7e50
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/d3/d77487660ee3c0194ee01dc5eaf478782b1c7e
@@ -0,0 +1 @@
+xKJ1a9E!I@df%x!AooGp-~[[l O2AW 6Rّ=yFW @Փ5l(drXG[.cEKѻgmV!Pso0v *Wd \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/e2/33b9ed408a95e9d4b65fec7fc34943a556deb2 b/tests/resources/cherrypick/.gitted/objects/e2/33b9ed408a95e9d4b65fec7fc34943a556deb2
new file mode 100644
index 000000000..b344c9cc8
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/e2/33b9ed408a95e9d4b65fec7fc34943a556deb2
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/e5/183bfd18e3a0a691fadde2f0d5610b73282d31 b/tests/resources/cherrypick/.gitted/objects/e5/183bfd18e3a0a691fadde2f0d5610b73282d31
new file mode 100644
index 000000000..fdc05714f
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/e5/183bfd18e3a0a691fadde2f0d5610b73282d31
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/e6/ae8889c40c77d7be02758235b5b3f7a4f2a129 b/tests/resources/cherrypick/.gitted/objects/e6/ae8889c40c77d7be02758235b5b3f7a4f2a129
new file mode 100644
index 000000000..3345907db
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/e6/ae8889c40c77d7be02758235b5b3f7a4f2a129
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/e7/811a2bc55635f182750f0420da5ad232c1af91 b/tests/resources/cherrypick/.gitted/objects/e7/811a2bc55635f182750f0420da5ad232c1af91
new file mode 100644
index 000000000..238873025
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/e7/811a2bc55635f182750f0420da5ad232c1af91
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/e9/b63f3655b2ad80c0ff587389b5a9589a3a7110 b/tests/resources/cherrypick/.gitted/objects/e9/b63f3655b2ad80c0ff587389b5a9589a3a7110
new file mode 100644
index 000000000..ab0a27f37
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/e9/b63f3655b2ad80c0ff587389b5a9589a3a7110
@@ -0,0 +1,2 @@
+xMj0@u<!Eɣ?$/rzn}]HG+z"*k
+AHch]n RN-3Kp~}PK,J=dz#G?Vֲu:NvVfi cO;iZjEu y^-P@ \ No newline at end of file
diff --git a/tests/resources/cherrypick/.gitted/objects/eb/da71fe44dcb60c53b8fbd53208a1204d32e959 b/tests/resources/cherrypick/.gitted/objects/eb/da71fe44dcb60c53b8fbd53208a1204d32e959
new file mode 100644
index 000000000..19d0c5288
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/eb/da71fe44dcb60c53b8fbd53208a1204d32e959
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/f0/5ed049854c1596a7cc0e957fab34961077f3ae b/tests/resources/cherrypick/.gitted/objects/f0/5ed049854c1596a7cc0e957fab34961077f3ae
new file mode 100644
index 000000000..ab454399e
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/f0/5ed049854c1596a7cc0e957fab34961077f3ae
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/f0/a4e1c66bb548cd2b22eebefda703872e969775 b/tests/resources/cherrypick/.gitted/objects/f0/a4e1c66bb548cd2b22eebefda703872e969775
new file mode 100644
index 000000000..558dd0a44
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/f0/a4e1c66bb548cd2b22eebefda703872e969775
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/f2/ec8c8cf1a9fb7aa047a25a4308bfe860237ad4 b/tests/resources/cherrypick/.gitted/objects/f2/ec8c8cf1a9fb7aa047a25a4308bfe860237ad4
new file mode 100644
index 000000000..a0117515c
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/f2/ec8c8cf1a9fb7aa047a25a4308bfe860237ad4
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/f5/684c96bf40c709877b56404cd8a5dd2d2a7978 b/tests/resources/cherrypick/.gitted/objects/f5/684c96bf40c709877b56404cd8a5dd2d2a7978
new file mode 100644
index 000000000..83bb5a0cc
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/f5/684c96bf40c709877b56404cd8a5dd2d2a7978
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/objects/f9/0f9dcbdac2cce5cc166346160e19cb693ef4e8 b/tests/resources/cherrypick/.gitted/objects/f9/0f9dcbdac2cce5cc166346160e19cb693ef4e8
new file mode 100644
index 000000000..71be9f834
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/objects/f9/0f9dcbdac2cce5cc166346160e19cb693ef4e8
Binary files differ
diff --git a/tests/resources/cherrypick/.gitted/refs/heads/automerge-branch b/tests/resources/cherrypick/.gitted/refs/heads/automerge-branch
new file mode 100644
index 000000000..9330ef3d1
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/refs/heads/automerge-branch
@@ -0,0 +1 @@
+d3d77487660ee3c0194ee01dc5eaf478782b1c7e
diff --git a/tests/resources/cherrypick/.gitted/refs/heads/master b/tests/resources/cherrypick/.gitted/refs/heads/master
new file mode 100644
index 000000000..aa8913beb
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/refs/heads/master
@@ -0,0 +1 @@
+2a26c7e88b285613b302ba76712bc998863f3cbc
diff --git a/tests/resources/cherrypick/.gitted/refs/heads/merge-branch b/tests/resources/cherrypick/.gitted/refs/heads/merge-branch
new file mode 100644
index 000000000..ea5b277ec
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/refs/heads/merge-branch
@@ -0,0 +1 @@
+abe4603bc7cd5b8167a267e0e2418fd2348f8cff
diff --git a/tests/resources/cherrypick/.gitted/refs/heads/merge-conflicts b/tests/resources/cherrypick/.gitted/refs/heads/merge-conflicts
new file mode 100644
index 000000000..f63f17efb
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/refs/heads/merge-conflicts
@@ -0,0 +1 @@
+bafbf6912c09505ac60575cd43d3f2aba3bd84d8
diff --git a/tests/resources/cherrypick/.gitted/refs/heads/merge-mainline b/tests/resources/cherrypick/.gitted/refs/heads/merge-mainline
new file mode 100644
index 000000000..0ec5e458c
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/refs/heads/merge-mainline
@@ -0,0 +1 @@
+cfc4f0999a8367568e049af4f72e452d40828a15
diff --git a/tests/resources/cherrypick/.gitted/refs/heads/orphan b/tests/resources/cherrypick/.gitted/refs/heads/orphan
new file mode 100644
index 000000000..f4d6a7467
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/refs/heads/orphan
@@ -0,0 +1 @@
+74f06b5bfec6d33d7264f73606b57a7c0b963819
diff --git a/tests/resources/cherrypick/.gitted/refs/heads/renames b/tests/resources/cherrypick/.gitted/refs/heads/renames
new file mode 100644
index 000000000..df5587173
--- /dev/null
+++ b/tests/resources/cherrypick/.gitted/refs/heads/renames
@@ -0,0 +1 @@
+44cd2ed2052c9c68f9a439d208e9614dc2a55c70
diff --git a/tests/resources/cherrypick/file1.txt b/tests/resources/cherrypick/file1.txt
new file mode 100644
index 000000000..38c05a857
--- /dev/null
+++ b/tests/resources/cherrypick/file1.txt
@@ -0,0 +1,15 @@
+!File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
+File 1
diff --git a/tests/resources/cherrypick/file2.txt b/tests/resources/cherrypick/file2.txt
new file mode 100644
index 000000000..a661b5dec
--- /dev/null
+++ b/tests/resources/cherrypick/file2.txt
@@ -0,0 +1,15 @@
+!File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
+File 2
diff --git a/tests/resources/cherrypick/file3.txt b/tests/resources/cherrypick/file3.txt
new file mode 100644
index 000000000..85a4a1d79
--- /dev/null
+++ b/tests/resources/cherrypick/file3.txt
@@ -0,0 +1,15 @@
+!File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
+File 3
diff --git a/tests/revert/workdir.c b/tests/revert/workdir.c
index 694f24710..e3d7e968a 100644
--- a/tests/revert/workdir.c
+++ b/tests/revert/workdir.c
@@ -66,7 +66,7 @@ void test_revert_workdir__conflicts(void)
git_reference *head_ref;
git_commit *head, *commit;
git_oid revert_oid;
- git_buf conflicting_buf = GIT_BUF_INIT;
+ git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT;
struct merge_index_entry merge_index_entries[] = {
{ 0100644, "7731926a337c4eaba1e2187d90ebfa0a93659382", 1, "file1.txt" },
@@ -112,9 +112,21 @@ void test_revert_workdir__conflicts(void)
"File one\n" \
">>>>>>> parent of 72333f4... automergeable changes\n") == 0);
+ cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
+ cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
+ TEST_REPO_PATH "/.git/MERGE_MSG"));
+ cl_assert(strcmp(mergemsg_buf.ptr,
+ "Revert \"automergeable changes\"\n" \
+ "\n" \
+ "This reverts commit 72333f47d4e83616630ff3b0ffe4c0faebcc3c45.\n"
+ "\n" \
+ "Conflicts:\n" \
+ "\tfile1.txt\n") == 0);
+
git_commit_free(commit);
git_commit_free(head);
git_reference_free(head_ref);
+ git_buf_free(&mergemsg_buf);
git_buf_free(&conflicting_buf);
}
diff --git a/tests/status/ignore.c b/tests/status/ignore.c
index acdc8fb58..d6c26a847 100644
--- a/tests/status/ignore.c
+++ b/tests/status/ignore.c
@@ -228,6 +228,32 @@ void test_status_ignore__subdirectories(void)
cl_assert(ignored);
}
+static void make_test_data(void)
+{
+ static const char *files[] = {
+ "empty_standard_repo/dir/a/ignore_me",
+ "empty_standard_repo/dir/b/ignore_me",
+ "empty_standard_repo/dir/ignore_me",
+ "empty_standard_repo/ignore_also/file",
+ "empty_standard_repo/ignore_me",
+ "empty_standard_repo/test/ignore_me/file",
+ "empty_standard_repo/test/ignore_me/file2",
+ "empty_standard_repo/test/ignore_me/and_me/file",
+ NULL
+ };
+ static const char *repo = "empty_standard_repo";
+ const char **scan;
+ size_t repolen = strlen(repo) + 1;
+
+ g_repo = cl_git_sandbox_init(repo);
+
+ for (scan = files; *scan != NULL; ++scan) {
+ cl_git_pass(git_futils_mkdir(
+ *scan + repolen, repo, 0777, GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST));
+ cl_git_mkfile(*scan, "contents");
+ }
+}
+
void test_status_ignore__subdirectories_recursion(void)
{
/* Let's try again with recursing into ignored dirs turned on */
@@ -235,6 +261,9 @@ void test_status_ignore__subdirectories_recursion(void)
status_entry_counts counts;
static const char *paths_r[] = {
".gitignore",
+ "dir/a/ignore_me",
+ "dir/b/ignore_me",
+ "dir/ignore_me",
"ignore_also/file",
"ignore_me",
"test/ignore_me/and_me/file",
@@ -242,49 +271,30 @@ void test_status_ignore__subdirectories_recursion(void)
"test/ignore_me/file2",
};
static const unsigned int statuses_r[] = {
- GIT_STATUS_WT_NEW,
- GIT_STATUS_IGNORED,
- GIT_STATUS_IGNORED,
- GIT_STATUS_IGNORED,
- GIT_STATUS_IGNORED,
- GIT_STATUS_IGNORED,
+ GIT_STATUS_WT_NEW, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+ GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+ GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
};
static const char *paths_nr[] = {
".gitignore",
+ "dir/a/ignore_me",
+ "dir/b/ignore_me",
+ "dir/ignore_me",
"ignore_also/",
"ignore_me",
"test/ignore_me/",
};
static const unsigned int statuses_nr[] = {
GIT_STATUS_WT_NEW,
- GIT_STATUS_IGNORED,
- GIT_STATUS_IGNORED,
- GIT_STATUS_IGNORED,
+ GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+ GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
};
- g_repo = cl_git_sandbox_init("empty_standard_repo");
-
+ make_test_data();
cl_git_rewritefile("empty_standard_repo/.gitignore", "ignore_me\n/ignore_also\n");
- cl_git_mkfile(
- "empty_standard_repo/ignore_me", "I'm going to be ignored!");
- cl_git_pass(git_futils_mkdir_r(
- "empty_standard_repo/test/ignore_me", NULL, 0775));
- cl_git_mkfile(
- "empty_standard_repo/test/ignore_me/file", "I'm going to be ignored!");
- cl_git_mkfile(
- "empty_standard_repo/test/ignore_me/file2", "Me, too!");
- cl_git_pass(git_futils_mkdir_r(
- "empty_standard_repo/test/ignore_me/and_me", NULL, 0775));
- cl_git_mkfile(
- "empty_standard_repo/test/ignore_me/and_me/file", "Deeply ignored");
- cl_git_pass(git_futils_mkdir_r(
- "empty_standard_repo/ignore_also", NULL, 0775));
- cl_git_mkfile(
- "empty_standard_repo/ignore_also/file", "I'm going to be ignored!");
-
memset(&counts, 0x0, sizeof(status_entry_counts));
- counts.expected_entry_count = 6;
+ counts.expected_entry_count = 9;
counts.expected_paths = paths_r;
counts.expected_statuses = statuses_r;
@@ -299,7 +309,7 @@ void test_status_ignore__subdirectories_recursion(void)
memset(&counts, 0x0, sizeof(status_entry_counts));
- counts.expected_entry_count = 4;
+ counts.expected_entry_count = 7;
counts.expected_paths = paths_nr;
counts.expected_statuses = statuses_nr;
@@ -313,6 +323,103 @@ void test_status_ignore__subdirectories_recursion(void)
cl_assert_equal_i(0, counts.wrong_sorted_path);
}
+void test_status_ignore__subdirectories_not_at_root(void)
+{
+ git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+ status_entry_counts counts;
+ static const char *paths_1[] = {
+ "dir/.gitignore",
+ "dir/a/ignore_me",
+ "dir/b/ignore_me",
+ "dir/ignore_me",
+ "ignore_also/file",
+ "ignore_me",
+ "test/.gitignore",
+ "test/ignore_me/and_me/file",
+ "test/ignore_me/file",
+ "test/ignore_me/file2",
+ };
+ static const unsigned int statuses_1[] = {
+ GIT_STATUS_WT_NEW, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+ GIT_STATUS_IGNORED, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
+ GIT_STATUS_WT_NEW, GIT_STATUS_IGNORED, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
+ };
+
+ make_test_data();
+ cl_git_rewritefile("empty_standard_repo/dir/.gitignore", "ignore_me\n/ignore_also\n");
+ cl_git_rewritefile("empty_standard_repo/test/.gitignore", "and_me\n");
+
+ memset(&counts, 0x0, sizeof(status_entry_counts));
+ counts.expected_entry_count = 10;
+ counts.expected_paths = paths_1;
+ counts.expected_statuses = statuses_1;
+
+ opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+
+ cl_git_pass(git_status_foreach_ext(
+ g_repo, &opts, cb_status__normal, &counts));
+
+ cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+ cl_assert_equal_i(0, counts.wrong_status_flags_count);
+ cl_assert_equal_i(0, counts.wrong_sorted_path);
+}
+
+void test_status_ignore__leading_slash_ignores(void)
+{
+ git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+ status_entry_counts counts;
+ git_buf home = GIT_BUF_INIT;
+ static const char *paths_2[] = {
+ "dir/.gitignore",
+ "dir/a/ignore_me",
+ "dir/b/ignore_me",
+ "dir/ignore_me",
+ "ignore_also/file",
+ "ignore_me",
+ "test/.gitignore",
+ "test/ignore_me/and_me/file",
+ "test/ignore_me/file",
+ "test/ignore_me/file2",
+ };
+ static const unsigned int statuses_2[] = {
+ GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
+ GIT_STATUS_IGNORED, GIT_STATUS_IGNORED, GIT_STATUS_IGNORED,
+ GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW, GIT_STATUS_WT_NEW,
+ };
+
+ make_test_data();
+
+ cl_fake_home(&home);
+ cl_git_mkfile("home/.gitignore", "/ignore_me\n");
+ {
+ git_config *cfg;
+ cl_git_pass(git_repository_config(&cfg, g_repo));
+ cl_git_pass(git_config_set_string(
+ cfg, "core.excludesfile", "~/.gitignore"));
+ git_config_free(cfg);
+ }
+
+ cl_git_rewritefile("empty_standard_repo/.git/info/exclude", "/ignore_also\n");
+ cl_git_rewritefile("empty_standard_repo/dir/.gitignore", "/ignore_me\n");
+ cl_git_rewritefile("empty_standard_repo/test/.gitignore", "/and_me\n");
+
+ memset(&counts, 0x0, sizeof(status_entry_counts));
+ counts.expected_entry_count = 10;
+ counts.expected_paths = paths_2;
+ counts.expected_statuses = statuses_2;
+
+ opts.flags = GIT_STATUS_OPT_DEFAULTS | GIT_STATUS_OPT_RECURSE_IGNORED_DIRS;
+
+ cl_git_pass(git_status_foreach_ext(
+ g_repo, &opts, cb_status__normal, &counts));
+
+ cl_assert_equal_i(counts.expected_entry_count, counts.entry_count);
+ cl_assert_equal_i(0, counts.wrong_status_flags_count);
+ cl_assert_equal_i(0, counts.wrong_sorted_path);
+
+ cl_fake_home_cleanup(&home);
+}
+
void test_status_ignore__adding_internal_ignores(void)
{
int ignored;