I have a base repository with a "base site" that I clone to make my clients sites, so I work, make commits, push to the client fork, then I realize that in the middle of my commits there is one or more that must be merge to the base repository. That's what I did:
git format-patch -1 SHA
Then I go to the "base site" repository and do:
git am -3 patch_file
It's ok. The problem is when I want to pull changes from the "base site" to the client repo the commit is duplicated.
Is there a way to avoid that? Maybe a different workflow?
EDIT:
In fact I'm still having problems, my explanation isn't so clear. Let me try again:
I have a base repository that contains a 'docs', 'layout', 'pub' and 'sql' folder, there is just a blank 'index.html' in the 'docs' and 'layout' folder. In the 'pub' folder I have Joomla installed.
When I have a new client I make his directory and init a repository, then I add a remote 'base' pointing to the base bare repository, fetch it, checkout base/master and then do 'checkout -b master' to create the master branch from the base's master branch. Then I make a 'clone --bare' in my local server and clone from it in local workstations. We save docs when needed, the designer makes the layout then all of it is commited and pushed to the client's bare repo. We always do a 'rebase origin/master' before pushing, to make sure the local repo is up to date.
So when the layout is done and pushed, I pull it and start to make the Joomla template. So I make a lots of commits, then I realise that I have to make changes in our Joomla components to something to work as it should. Ok, I change a component, commit and continue to making the template, commit, ...
Now I want to bring all the component's commits to the 'base repo' because I want all my clients to have the same changes. When I tried @jleedev solution, all my client's commits went to the top, rewriting it's SHA's that were already in the client's bare repo.
Any ideas?
Thanks!
Yes! The
git-pull
command performs a fetch followed by a merge. The merge yells at you since you have the same patch expressed as two commits with different names.If you do
git-pull --rebase
, or the two-step equivalent ofgit fetch; git rebase origin/master
, then it will rebase your local changes onto the upstream.Let's say your repo looks like this;
master
contains the work you've done in client, andorigin/master
represents the upstream base onto which you've applied the emailed patch. After you fetch, you see two divergent branches, but the commit that you've exported is in both lines.It looks like this in GitX:
After the fetch http://grab.by/m1T
When you rebase, it takes all your commits on
client
that aren't inbase
, converts them from commits to patches, and applies them one by one onto the upstream head. When it notices that two commits express the same patch, they get smooshed into one (the upstream commit lives and the local one dies).After the rebase http://grab.by/m1X
As @roe mentions, there are probably better ways to keep your repositories in sync, such as cherry-picking the commit you need and then pushing it. It's quite possible to run into issues when you rebase, but the way you described your workflow of exporting a patch using format-patch and am seems pretty safe.