Search code examples
gitshellmercurialdotfiles

Partial branch or partial merge or other way to help me to sync dotfiles?


I don't know how to make my requirement short in title, sorry if it is not meaningful. I will explain here:

Many people put their dotfiles on bitbucket or github, to ease later installation or configuration, sync over different pc. I did the same, however I want to do something special, I am not sure how mecurial/git could help.

What I have:

I have 3 machines, say Home, Office and Client, all linux OS (could be different distributions). To make the example simple, say I just want to put one file the .zshrc into repo. The problem is, the three OS have different system variables(or other settings). e.g.

  • Office has JBOSS installed, then in .zshrc I need export JBOSS_HOME var.
  • Client has Oracle installed, then export different set of vars.
  • Office has to export HTTP_PROXY, but HOME not, Client needs it too, but different proxy value etc.

Now what I did is, I extract those machine specific settings (mostly export, alias statement) to another file, say myVar.sh. and source it at the end of the .zshrc.

So 3 machines have common part (same .zshrc), and different parts (myVar.sh).

What I want:

  • on any machine, if I found some nice settings, I change the .zshrc file (common part) and push. The changes should be easily sync to other machines (by pull, for example)

  • if I changed the myVar.sh (different part) on HOME, and push, it should not affect Office's myVar.sh if I do pull on Office machine.

What I am doing:

now I have one Repo on bitBucket, and three branches (H,O,C). On Home PC, I just play with Home branch. Same for Office, Client.

The problem is, if I changed the common part on one pc, the change is in its own branch, a little bit difficult to sync to the other two. Because I would never merge those branches.

I also think about to mk different directories for different pc. e.g.

/.zshrc
|--/HOME/myVar.sh
|--/Office/myVar.sh
|--/Client/myVar.sh

and write shell script, e.g. check $HOST to decide writing myVar.sh to which directory. but I doubt that if it is the best way to achieve my goal. And when I look my dotfiles dir, I see all 3 pcs' setting. I should be careful and enter the correct one to read the file.

In real world, the common part contains much more than .zhsrc (tmux,vimrc,xdefault..), so does the different part.

I don't know can we somehow make a partial branch or do a partial merge on a repository...

I use hg much more than git, if hg can solve it I would prefer hg, if not, git is also acceptable. I don't have much git experience except for clone, push, pull, up, merge,ci.

now, how should I do?

and, thank you for reading this...


EDIT more about the different part

I would thank you all guys for giving me answers. As I said above, the different part in my real machines is not as simple as myVar.sh. For example, I take my company-laptop (Office) to different clients (There are about 6 clients, not all clients provide us PCs, it is good because I could work with Linux everywhere), and configured printers for each by cups. I would put those configurations in Repo too. Because if one day I have to refresh my system, or harddisk failed, I could setup those printers very easy. Other things that belongs to different part but I cannot simply "source xxx" like

  • Xorg.conf for trackpoint

  • .hgrc file (since in company we have our own repo, uid, pwd, proxy..)

  • some pre-configured systemd modules, basically .conf files. But machine specific, e.g. radeon.conf only for my Home laptop. And Client pc has no systemd installed at all.

    That's why I thought about different directory for PCs.

As I said right now I am with 3 branches way, and have a myConf directory, within this directory I have getConf.sh, to copy dotfiles, different confs etc to myConf. In fact the getConf.sh belongs to different part too, because the script is not same for all pcs.

Therefore I think the if-else/switch then source may not work in this case.

Yesterday I just took the .zshrc, and try to make the example simple. If it mislead you guys, sorry about that.


Solution

  • My preferred way to do this is to have a host-specific version for each file all in the same directory -- similar to your same file multiple directories, and then include it via variable interpolation in my main file. So ~/.bashrc has inside of this this:

    if [ -f ~/.bashrc-$HOSTNAME ] ; then
         source ~/.bashrc-$HOSTNAME
    fi
    

    Presumably that's even prettier in zsh, but the idea is if a host-specific file exists source it at the end, and of course anything that applies on all machines goes in the main ~/.bashrc itself.