Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doing a Git Pull with libgit2

Tags:

c++

git

libgit2

I've looked at the answer in this post (libgit2 (fetch & merge & commit)) but I am struggling to get a Git Pull to work. I get no error messages. The Fetch appears to work but the Merge doesn't occur. Doing a Git Status shows that my branch is behind by 1 commit...

On branch Branch_1_1.
Your branch is behind 'origin/Branch_1_1' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)
nothing to commit, working directory clean

My code is below...

static int fetchhead_ref_cb(const char *name, const char *url,
   const git_oid *oid, unsigned int is_merge, void *payload)

{
   if ( is_merge )
   {
      strcpy_s( branchToMerge, 100, name );
      memcpy( &branchOidToMerge, oid, sizeof( git_oid ) );
   }
   return 0;
}

void GitPull()
{
   git_libgit2_init();

   git_repository *repo = NULL;
   git_remote *remote;

   int error = git_repository_open( &repo, "C:\\work\\GitTestRepos\\Repo1" );
   CHECK_FOR_ERROR

   error = git_remote_lookup( &remote, repo, "origin" );
   CHECK_FOR_ERROR

   git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
   error = git_remote_fetch( remote, NULL, &options, NULL );
   CHECK_FOR_ERROR

   git_repository_fetchhead_foreach( repo, fetchhead_ref_cb, NULL );

   git_merge_options merge_options = GIT_MERGE_OPTIONS_INIT;
   git_checkout_options checkout_options = GIT_CHECKOUT_OPTIONS_INIT;
   git_annotated_commit *heads[ 1 ];
   git_reference *ref;

   error = git_annotated_commit_lookup( &heads[ 0 ], repo, &branchOidToMerge );
   CHECK_FOR_ERROR
   error = git_merge( repo, (const git_annotated_commit **)heads, 1, &merge_options, &checkout_options );
   CHECK_FOR_ERROR

   git_annotated_commit_free( heads[ 0 ] );
   git_repository_state_cleanup( repo );
   git_libgit2_shutdown();
}

What am I doing that's causing the merge not to work ?

like image 930
Anthony Avatar asked Sep 23 '16 01:09

Anthony


People also ask

Does git use libgit2?

libgit2 is used to power Git GUI clients like GitKraken and gmaster and on Git hosting providers like GitHub, GitLab and Azure DevOps.

Should you git pull every day?

Pull frequently You should endeavor to keep your local machine as close to the remote repository as possible. The way to do that is to pull all the changes on the remote server to your local copy. You can do this as often as you like, and should do it frequently — at least once a day if not more.

Does git pull do a merge?

The git pull command is actually a combination of two other commands, git fetch followed by git merge . In the first stage of operation git pull will execute a git fetch scoped to the local branch that HEAD is pointed at. Once the content is downloaded, git pull will enter a merge workflow.

What is git pull shorthand for?

In its default mode, git pull is shorthand for git fetch followed by git merge FETCH_HEAD . More precisely, git pull runs git fetch with the given parameters and calls git merge to merge the retrieved branch heads into the current branch.


Video Answer


1 Answers

First, git_checkout_options.checkout_strategy has a rather surprising default. It defaults to dry run. So you probably want to change it to something like GIT_CHECKOUT_SAFE.

The second thing to understand is that git_merge doesn't actually commit the merge. It only sets up your working directory and index for a merge. You still have to check for conflicts and call git_commit_create to finish the merge.

However, it looks like you don't really need to merge in this specific case. Your branch can be fast-forwarded. Call git_merge_analysis to determine which kind of merge to do. To fast-forward call git_reference_set_target on the current branch with the new fetch head.

like image 184
Jason Haslam Avatar answered Sep 21 '22 17:09

Jason Haslam