3

I have several repositories that I always have to merge one core repository into. The core repository is setup as a remote repository in every repository.

Generally, my workflow to update repositories goes like this:

git reset --hard origin/master
git pull origin master
git fetch core master

I then do a git merge --squash core/master and fix any conflicts before pushing the repository back to remote.

This is fine, except it is a little redundant because aside from everything in the .gitignore file for each repository, everything in these repositories should technically be the same as the core repository.

As the number of repositories expand, I'm wondering what a more efficient way of pulling the core branch into these repositories would be given that I need to replace all existing files except the ones specifically mentioned in .gitignore for every one of them while maintaining integrity in git history and logs.

Kamran Khan
  • 453
  • 1
  • 5
  • 19
  • Can't you use [submodule](https://git-scm.com/docs/git-submodule)? – lee-pai-long Sep 13 '17 at 19:32
  • Do you want `git checkout branch -- files...` perhaps? – o11c Sep 16 '17 at 01:02
  • Git is working at project level. Unless you are using submodules, there is no way to "select" an alternate remote for specific files. – Fabien Bouleau Sep 18 '17 at 06:32
  • I'm confused what you are accomplishing here. You are using some terms in ways I would not - core is a remote **repo**, not a remote **branch**, with a remote version of the `master` branch. You also have a second remote, `origin`, which is also a remote repo with it's own copy of the `master` branch. Are you just trying to sync multiple remote repos through a single local repo? If they are diverging through development changes/commits, is there a reason you aren't using different branches for each set of changes rather than having them all develop in `master`? – LightCC Sep 20 '17 at 05:30
  • Someone above mentioned submodules. I would add subtrees to your options to consider - however I would like to first understand the reason for the code being in separate repositories to begin with. Just so that we understand the relationship between the core repo and the other several repos your using. – eddiemoya Sep 20 '17 at 19:24
  • @LightCC I'm sorry for the confusion and I see the problem with my wording. You are correct: `core` is a remote repository in the project where my framework files are. I'm trying to sync this `core` repository into other project repositories. The `core` repository is where all my development happens so that is where I make use of feature branches for development. The other repositories have some custom files, but all contain the main framework which is the `core` remote repository. My question was to find a better approach for replacing framework files in these project repositories easily. – Kamran Khan Sep 21 '17 at 17:55
  • @KamranKhan That is helpful, but one more question - you are starting out with `origin`, and then pulling in `core`. Are you doing this in a local repo, and setting up `origin` in turn for each remote repo that needs `core` merged in? – LightCC Sep 21 '17 at 22:19
  • @KamranKhan whats wring with my answer? Have I missed anything that you want me to add? Please give some sort of feedback so I can improve it. – TheChetan Sep 22 '17 at 03:11

1 Answers1

1

You can do it with a combination of git and bash. I've written a sample script to show how it can be done. You can always modify it and make it better. I've provided some explanation also. This file is called adder.sh.

#!/bin/bash
# $1 -> Files from the branch you want (core)
# $2 -> Branch you want to merge into (master)

git checkout $2
git diff --name-status $1..$2 | grep '^\(D\|M\)\s*' | cut -f2 > ~/.dummy
git checkout $1 -- $(cat ~/.dummy)
git add .

To invoke it, just use $ sh adder.sh core master. After this all newly added and modified files from the core branch will be added to the master repo. With a git status you can see what's new, then commit and push accordingly.

$ git commit -m "Skipping Conflicts"
$ git push

Some explanation to how it works:

$ git diff --name-status master..core

Produces the following output:

M       public/stylesheets/main.css              # Modified
D       public/templates/createUser.html         # Present in core branch and not master (new file)
A       public/templates/dashboard.html          # Present in master and not in the core branch (don't touch)

So write a simple regex to select only the modified and new files and modify it to a proper format and then store it in a temporary file.

$ cat ~/.dummy

public/templates/createUser.html
public/stylesheets/main.css

Then we need to add those files to our current branch, so we use git checkout. See this answer for how to do so with git checkout.


There is another way to do this. The official way, using git rerere. From the man page:

In a workflow employing relatively long lived topic branches, the developer sometimes needs to resolve the same conflicts over and over again until the topic branches are done (either merged to the "release" branch, or sent out and accepted upstream).

This command assists the developer in this process by recording conflicted automerge results and corresponding hand resolve results on the initial manual merge, and applying previously recorded hand resolutions to their corresponding automerge results.

Note: You need to set the configuration variable rerere.enabled in order to enable this command.

This article gives a decent overview of the command and its use case.

Community
  • 1
  • 1
TheChetan
  • 4,440
  • 3
  • 32
  • 41
  • Unless I'm doing this wrong, this doesn't maintain git history of the original repository. It overrides it with the core repository. – Kamran Khan Sep 28 '17 at 15:30
  • @KamranKhan, yeah thats right. You should venture the second option, if you want to maintain commit history – TheChetan Sep 28 '17 at 17:24
  • @KamranKhan, I was going over the git merge documentation today and I found [this answer](https://stackoverflow.com/a/13307342/4110233) on SO, see if it helps you. – TheChetan Feb 14 '18 at 20:42