Juan Carlos Méndez Juan Carlos Méndez - 1 month ago 8
Git Question

Workflow for delivering code to a client using two git repositories (internal and external)

I have a situation where the client will receive source code, under version control using Git. Client wants the progress of weekly sprints to be tracked, diff'd and controlled into their repo. Eventually, client personnel will also make commits into that repo.

My team (let's call internal team) is using Git as well, and the git-flow workflow. So every release of the internal repo should translate into a commit on the client repo. We don't want every commit on the internal repo to show on the client repo.

So my current thinking/solution is to have a script that uses rsync to copy the working directory from internal to client (on the local filesystem) then commit into the client repo. This could be placed as a post-receive hook on the internal server or something similar.

The solution seems too clunky to me, and perhaps there are better ways to achieve what I need. What are other thoughts?




EDIT to include accepted solution:

As Scott Weldon pointed on the accepted response,
git-merge
allows to do this in a good workflow. However, to make it work, other flags are needed. One is to allow git to effectively merge the two stories, and the second one to give the appropriate strategy for resolving the conflicts.

So, assuming the reference that I'm merging from the internal repo is
release/x.x.x.
, the flow is

git fetch internal
git merge --allow-unrelated-histories -s recursive -Xtheirs --squash internal/release/x.x.x
git commit
git push origin master

Answer

One way to do this would be to use Git's ability to add and merge disjoint histories.

Add the internal repository as a remote to your external repository:

git remote add internal ssh://user@host/path.git

Whenever you do a release in the internal repo, do the following in the external repo:

git fetch internal
git merge --squash internal/master
git commit
git push origin master

This will create a single commit in the external repo that contains any changes from internal/master since the last merge.

From the man page for git merge:

--squash

Produce the working tree and index state as if a real merge happened (except for the merge information), but do not actually make a commit, move the HEAD, or record $GIT_DIR/MERGE_HEAD (to cause the next git commit command to create a merge commit). This allows you to create a single commit on top of the current branch whose effect is the same as merging another branch (or more in the case of an octopus).

So without the --squash flag, the history from internal would be included in the external repo.

Comments