2

I have developed a site with some functionality and some basic pages like "about us", "contacts" and some pages for SEO. It is in a git repository.

And now I want to make a copy of this site with other data in simple pages and without these seo-pages.

So I git branch second'ed it and made some modifications and deletions of files in that branch. Then I came back into master and added some features, bugfixes and some other stuff.

Now I want make these changes in the common part of the site to appear in second branch.

I git checkout second, and git rebase master. Git asked to resolve conflicts to continue. Ok, I fixed a lot of conflicts and finally it rebased and even pushed into my remote repo.

BUT! If I try right now to git rebase master again, i'll get the same conflicts all over again (even if i did zero modifications!) and have to re-do the crazy conflict resolution :(

I thought it will remember my actions in each conflict situation and will ask me only in new places with new features/bugfixes. But it doesn't.

How can I setup my two branches to maintain 2 sites with no hurt? Maybe merge? Some other command?

j0k
  • 21,914
  • 28
  • 75
  • 84
outluch
  • 842
  • 7
  • 15
  • 1
    You need to use `git rerere` to remember conflict reslutions. – Carl Norum Jul 29 '13 at 23:09
  • Why did you do the same rebase twice? – CharlesB Jul 29 '13 at 23:13
  • My suggestion was^ i rebased this branch, so all code from master is now in this branch and there is no new code to rebase to, so it will say something like: branch is up to date or smth.. – outluch Jul 29 '13 at 23:15
  • then you should have said `git merge second` from the `master` branch. It means you want to merge the `second` branch into the `master` one, and as it's a fast-forward merge it just makes `master` point to `second` – CharlesB Jul 29 '13 at 23:49
  • 1
    @CharlesB that doesn't sound right; it sounds to me that he wants new commits in `master` to appear in `second`, but `git merge second` will do the opposite; make commits from `second` appear in `master`. – Leigh Brenecki Jul 30 '13 at 01:19
  • 1
    @outluch your assumption should be correct - because the first rebase would have made `master` an ancestor of `second`, the second rebase shouldn't have done anything (assuming there were no new commits in `master`) - instead, it'd just return "`Current branch second is up to date.`". Could you post a screenshot of `gitk` or SourceTree or something, so we can see your commits' ancestry? – Leigh Brenecki Jul 30 '13 at 01:31

2 Answers2

3

Branches are the wrong tool to maintain parallel versions.

The 3-way merge algorithm has a property that if you merge branch A to branch B and than branch B to branch A, both branches will have exactly the same content. In case of git they will actually point to the same revision, but even in version control systems that can't do that and have separate revisions, their content will be the same, because it is inherent in the merge algorithm. This makes branches great for doing work in parallel that should eventually be combined together, but pretty bad for maintaining independent versions. You can do it, but at least must have a base branch with only common code and it's tedious and there are many ways to screw up.

There are two ways:

  1. Have a single branch and separate files for the common code and separate files with the site-specific data and use either some preprocessing step or server side includes to generate the final HTML. This is what one usually does with software and is proven by experience to scale easily to tens or more versions. What you want to use is called static site generator. You can start by looking here.

  2. Have a branch with the common code only (C) and branches with the versions (A and B) derived from that. You than make changes only applicable to A on A, those only applicable to B on B and those applicable to C and rebase both A and B. This is going to work, but you'll be doing a lot of switching back and forth and if you make a change in the wrong place, it will take some careful cherry-picking to apply it where you need it. It won't need any preprocessing step though.

Jan Hudec
  • 65,662
  • 12
  • 114
  • 158
1

First rebasing is not ideal workflow when you want to merge stuff between long-lived branches. Merging from times to times master into second is certainly easier to maintain, and you will keep a trace in your history of the merges.

As for your problem, as Adam points out, there must be something else that happened because when a rebase is successful the second one has no effect. Maybe you didn't do git rebase --continue after solving your conflicts, and thought you had to re-do the git rebase?

If conflicts happen during a rebase, correct thing to do is:

  1. solve your conflicts with your favorite tool
  2. stage files that has been solved: git add .
  3. let Git finish the rebase with git rebase --continue

Maybe you'll want to take some time to undo the rebase, and make the right thing to merge.

Community
  • 1
  • 1
CharlesB
  • 75,315
  • 26
  • 174
  • 199
  • Actually rebase _is_ the right tool here, but the base must only contain the common code and both versions of the content must live on branches. But that assumes branches are good tool for this which they are not. – Jan Hudec Jul 30 '13 at 06:53
  • @JanHudec good point, wanted to make a more broad-point answer like yours but was short of time, so I answered on the specific problem of the OP. However rebase being better than merge in this case is questionable, as always rewriting history can lead to problems (having the branches pushed during development being one of these) – CharlesB Jul 30 '13 at 06:59
  • Yes, both should actually give the same result. And each has it's advantages. Merge will keep actual history, rebase will keep logical grouping of the differences. – Jan Hudec Jul 30 '13 at 07:05