diff options
author | Vicent Martà <tanoku@gmail.com> | 2011-05-02 15:29:50 -0700 |
---|---|---|
committer | Vicent Martà <tanoku@gmail.com> | 2011-05-02 15:29:50 -0700 |
commit | cc3b82e376e0216c1af4ad46d24327d61e9efd99 (patch) | |
tree | f3d617b50af44f28caa440fd012947a6498c76e2 | |
parent | fde97669ec7f07b339233601f39100ecfc089c53 (diff) | |
parent | 79b61557366db4550d1122bfa88b9851a5e2f5aa (diff) | |
download | libgit2-cc3b82e376e0216c1af4ad46d24327d61e9efd99.tar.gz |
Merge pull request #151 from carlosmn/root-commit.
Support root commits
-rw-r--r-- | src/commit.c | 13 | ||||
-rw-r--r-- | src/refs.c | 3 | ||||
-rw-r--r-- | tests/t04-commit.c | 68 |
3 files changed, 81 insertions, 3 deletions
diff --git a/src/commit.c b/src/commit.c index 9621703c3..0c37ec59b 100644 --- a/src/commit.c +++ b/src/commit.c @@ -224,9 +224,18 @@ int git_commit_create( if (error < GIT_SUCCESS) return error; - if (git_reference_type(head) == GIT_REF_SYMBOLIC) { - if ((error = git_reference_resolve(&head, head)) < GIT_SUCCESS) + error = git_reference_resolve(&head, head); + if (error < GIT_SUCCESS) { + if (error != GIT_ENOTFOUND) return error; + /* + * The target of the reference was not found. This can happen + * just after a repository has been initialized (the master + * branch doesn't exist yet, as it doesn't have anything to + * point to) or after an orphan checkout, so if the target + * branch doesn't exist yet, create it and return. + */ + return git_reference_create_oid_f(&head, repo, git_reference_target(head), oid); } error = git_reference_set_oid(head, oid); diff --git a/src/refs.c b/src/refs.c index 8c845401f..ea968196f 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1482,8 +1482,9 @@ int git_reference_resolve(git_reference **resolved_ref, git_reference *ref) for (i = 0; i < MAX_NESTING_LEVEL; ++i) { reference_symbolic *ref_sym; + *resolved_ref = ref; + if (ref->type & GIT_REF_OID) { - *resolved_ref = ref; return GIT_SUCCESS; } diff --git a/tests/t04-commit.c b/tests/t04-commit.c index 3e02df996..36f3e66b5 100644 --- a/tests/t04-commit.c +++ b/tests/t04-commit.c @@ -474,6 +474,72 @@ BEGIN_TEST(write0, "write a new commit object from memory to disk") git_repository_free(repo); END_TEST +#define ROOT_COMMIT_MESSAGE "This is a root commit\n\ +This is a root commit and should be the only one in this branch\n" + +BEGIN_TEST(root0, "create a root commit") + git_repository *repo; + git_commit *commit; + git_oid tree_id, commit_id; + const git_oid *branch_oid; + const git_signature *author, *committer; + const char *branch_name = "refs/heads/root-commit-branch"; + git_reference *head, *branch; + char *head_old; + + must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + + git_oid_mkstr(&tree_id, tree_oid); + + /* create signatures */ + committer = git_signature_new(COMMITTER_NAME, COMMITTER_EMAIL, 123456789, 60); + must_be_true(committer != NULL); + + author = git_signature_new(COMMITTER_NAME, COMMITTER_EMAIL, 987654321, 90); + must_be_true(author != NULL); + + /* First we need to update HEAD so it points to our non-existant branch */ + must_pass(git_reference_lookup(&head, repo, "HEAD")); + must_be_true(git_reference_type(head) == GIT_REF_SYMBOLIC); + head_old = git__strdup(git_reference_target(head)); + must_be_true(head_old != NULL); + + must_pass(git_reference_set_target(head, branch_name)); + + must_pass(git_commit_create_v( + &commit_id, /* out id */ + repo, + "HEAD", + author, + committer, + ROOT_COMMIT_MESSAGE, + &tree_id, + 0)); + + git_signature_free((git_signature *)committer); + git_signature_free((git_signature *)author); + + /* + * The fact that creating a commit works has already been + * tested. Here we just make sure it's our commit and that it was + * written as a root commit. + */ + must_pass(git_commit_lookup(&commit, repo, &commit_id)); + must_be_true(git_commit_parentcount(commit) == 0); + must_pass(git_reference_lookup(&branch, repo, branch_name)); + branch_oid = git_reference_oid(branch); + must_pass(git_oid_cmp(branch_oid, &commit_id)); + must_be_true(!strcmp(git_commit_message(commit), ROOT_COMMIT_MESSAGE)); + + /* Remove the data we just added to the repo */ + must_pass(git_reference_lookup(&head, repo, "HEAD")); + must_pass(git_reference_set_target(head, head_old)); + must_pass(git_reference_delete(branch)); + must_pass(remove_loose_object(REPOSITORY_FOLDER, (git_object *)commit)); + free(head_old); + git_commit_close(commit); + git_repository_free(repo); +END_TEST BEGIN_SUITE(commit) ADD_TEST(parse0); @@ -483,4 +549,6 @@ BEGIN_SUITE(commit) ADD_TEST(write0); //ADD_TEST(write1); + + ADD_TEST(root0); END_SUITE |