2

I have 2 branches, the main one and the one I'm working on a parallel release.

A --> B --> C (master)
  \
   -> E --> F (parallel)

The parallel branch will always merge from master. Always. And modify upon it.

A --> B --> C --> D --> H  (master)
  \           \ *merge*
   -> E --> F --> G --> J  (parallel)

This is easy to do if I switch branches.

But, if I'm working on parallel, can I do this without switching branches? The problem with switching is that it takes a long time to go back and forth (specially on Unity 3D)!

So say I'm on F, while master is still on A. Then I wanted to make few commits on master B and C then merge them into G. How would I do it, again, without switching branches?

Community
  • 1
  • 1
cregox
  • 17,674
  • 15
  • 85
  • 116
  • How do you plan to make commits on `master` without switching to it? – Neil Forrester Sep 12 '13 at 18:00
  • @NeilForrester that's my question. What do you mean?! – cregox Sep 12 '13 at 18:07
  • Well in that case, I don't think it's possible to do this in one repository. Try making two repositories, and keeping one on each branch. Other than that, you're on your own. – Neil Forrester Sep 12 '13 at 18:27
  • Well, can I make 2 repositories in the same folder? Would you bother posting any of this as an elaborated answer @NeilForrester ? – cregox Sep 12 '13 at 18:42
  • Taking long time to rebuild a project is a C++ issue when the file timestamps are touched. git checkout touches file timestamps. – linquize Sep 13 '13 at 03:50
  • @linquize git sure does touch. But that's a topic to the other question. ;-) – cregox Sep 13 '13 at 03:55
  • Create at least 2 working copies. One for master, One for parallel. This can minimize the number of files to be **touched** when merging because no `git checkout` is required. – linquize Sep 13 '13 at 04:16
  • I would ask this and the linked questions on the [main Git list](http://vger.kernel.org/vger-lists.html#git) because SO is not frequented by those who develop Git, and your questions appear to be hardcore enough. Please see [this](https://gist.github.com/tfnico/4441562) for more info. Please be sure to not just post links to SO questions though -- no one will bother to read them, -- post full text instead. – kostix Sep 13 '13 at 08:54
  • @kostix wow, hardcore, huh? Cool, thanks. I'll try that! Now... What do you mean by "post links to SO questions"? – cregox Sep 13 '13 at 13:02
  • @Cawas, 1) yes, I think they're hard-core because basically you're struggling with mtime changes on your files when they're touched by Git, arent' you? 2) Some people, when told to re-ask their questions elsewhere, just post links to their already asked questions (and "SO" is a common abbreviation for "Stack Overflow", sorry for confusion), and this is usually frowned upon or merely ignored so please don't do that. And consider stressing that the root cause of your problems is mtime changes triggering rebuilds. – kostix Sep 13 '13 at 13:41
  • @kostix (2) I see, so you mean when I ask a question on main git list to not simply link here. To me that's common sense, but I see where you come from now. Don't worry! (1) I'm not struggling with touch only, though and, as I see it, regardless of my reason, this question still has legs on its own. A very big repository does take some time to checkout. Saving that time in this situation can be quite handy. Don't know why you guys insist in changing the topic here. – cregox Sep 13 '13 at 14:24
  • Thanks for nudging, @Cawas -- I've provided an answer which, I hope, might solve this particular problem. – kostix Sep 13 '13 at 14:59

3 Answers3

2

There is (nowadays) a much easier solution utilising git worktree: You will get additional worktrees (i.e. checkouts) which share the same repository data.

The manpage states:

A git repository can support multiple working trees, allowing you to check out more than one branch at a time.

That means you do not need to switch branches but just change directories when "switching" your activities from master to parallel or vice-versa. Since there is no additional (cloned) repository, there is no overhead in managing it like push, merge or fetch operations as well as no configuration hassle.

Add an additional worktree for branch parallel:

git worktree add path/to/new-worktree parallel
doak
  • 809
  • 9
  • 24
1

To work simultaneously on two branches, push between paralleled clones.

# one-time setup: 
new=parallel-master
git clone . ../$new -b master
git remote add $new ../$new

Switch to master:

cd ../parallel-master
# work work commit commit lalala

Switch back:

git push origin master
cd ../main

and that's all it takes, git merge works normally. If you're ever going to merge from parallel to master, just push the other way before switching, it works the same both ways.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • Love the simple solutions to apparently complex problems! Awesome!! – cregox Sep 17 '13 at 21:16
  • @doak i think you meant to notify me with this comment... just want to let you know you only notified jthill with it. which is a nice side effect. :) – cregox Jan 08 '19 at 02:21
0

What you want could possibly be achieved using low-level (plumbing) Git commands and a separate work tree and the index.

As explained in the git(1) manual page, through the usage of environment variables it's possible to make a separate work tree for a given Git repository, basically:

$ mkdir foo && cd $_
$ export GIT_DIR=/path/to/the/repo/.git
$ export GIT_INDEX_FILE="$(pwd)/.index"
$ git read-tree master
$ git checkout-index -a -u

Now update the files in the work tree and stage the changes (git add etc) and then

$ editor /tmp/COMMIT_MSG
$ git update-ref refs/heads/master $(git commit-tree $(git write-tree) -p $(git rev-parse master) </tmp/COMMIT_MSG)

This:

  1. Creates a tree from the index (git write-tree) and writes its SHA-1 name to stdout.
  2. Obtains the SHA-1 name of the commit pointed to by the branch "master".
  3. Creates a commit object using the SHA-1 name of the commit obtained on the previous step as the parent commit. The name of the commit object is printed to stdout.
  4. Updates the branch "master" to point to that new commit object.

This operates on a pretty low level using only the plumbing commands but not touch HEAD in the repository and hence allows to work normally in the original work tree.

This is scriptable but is too cumbersome so I'd just try to use the git-new-workdir script available in the contrib section of the Git proper — it sets up a separate work tree linked to the original repository excluding the crucial stuff like HEAD which might disrupt the work in the original work tree. So you could create the new work tree, check out "master" into it, record new commits on it then safely merge them in the original work tree which has "parallel" checked in.

kostix
  • 51,517
  • 14
  • 93
  • 176
  • Wow, it will take me some time to test all that! Thanks. Keep your pants there, I'll be back on this next week. :) – cregox Sep 13 '13 at 15:03