1

I'd like to version ~/.bashrc and ~/.bash_profile using git, best if in-place (at the actual location), rather than creating a new repo and copy the file over and do the versioning there.

Is there a way to do that? I think the difficulty is, if I create a repo at ~, it includes every folder in my home directory and is not desirable.

Is there some way to tell git: version only these files or folder, and disregard everything else and don't consider them to be submodules? If it can be like that, it might be a solution, except it seem like a super big repo to be at the home directory but at the same time ignoring almost everything.

nonopolarity
  • 146,324
  • 131
  • 460
  • 740

4 Answers4

5

You can create a repo in another directory, and then use a symbolic link in your home directory (~) to point to the new file.

mkdir -p ~/path/to/repo
mv ~/.bashrc ~/path/to/repo/

cd ~
ln -s ~/path/to/repo/.bashrc .bashrc

cd ~/path/to/repo
# edit .bashrc
git init
git add .bashrc
git commit -m "Initial commit"

This way, you have a plain repository that contains only the files you want to version control, and the rest of your system uses ~/.bashrc as before, transparently following the link to the version controlled file. No .gitignore or shell aliases needed.

remcycles
  • 1,246
  • 13
  • 14
  • so you always have to remember what that repo folder is and and go there and do the git commands? And (2) it treats the symbolic link as an actual file in the repo? – nonopolarity Feb 19 '20 at 01:39
  • `ls -l .bashrc` will show you where the symbolic link points to, so you don't have to remember. But yes, you will perform the git commands in that directory. – remcycles Feb 19 '20 at 01:51
  • The contents of the symbolic link are basically a string with the path to the target file, but the system will interpret the link file as if it were a real file (the target file). https://kb.iu.edu/d/abbe and Wikipedia have good info on the subject. – remcycles Feb 19 '20 at 01:58
  • it seemed to work, except it probably needs to be `ln -s ~/.bashrc ~/path/to/repo/.bashrc` The `~` in `~/.bashrc` is important or else it links to `.bashrc` of the current folder, it seems – nonopolarity Feb 19 '20 at 01:59
  • actually, I did `more .bashrc` in that repo and it seems to show the proper content, but if I go to GitLab (or GitHub if you want) and look at that file, it merely shows a link – nonopolarity Feb 19 '20 at 02:03
  • It always pays to double check the man page before making a symbolic link. It creates a confusing situation if you get it backwards, which is easy to do. `ln [OPTION]... [-T] TARGET LINK_NAME (1st form)`. In your case, you'll want to move the existing `~/.bashrc` to your repo directory, commit it, and then make the link. – remcycles Feb 19 '20 at 02:12
  • oh... like that...? Then I don't like it as my system depends on a repo... – nonopolarity Feb 19 '20 at 03:17
  • It's just a suggestion, and one that works well for me. I'm not sure I understand the concern. Your goal is to version control your dot file, so your system will depend on a repo no matter which strategy you choose. Symbolic links are also a great tool for moving files to directories that are automatically backed up, or mounted over a network, etc. – remcycles Feb 20 '20 at 18:02
  • I'd rather the system works well without the repo, and just copy the .bashrc to a repo to version it occasionally. – nonopolarity Feb 20 '20 at 20:36
3

The bare repo approach is another option:

No extra tooling, no symlinks, files are tracked on a version control system, you can use different branches for different computers, you can replicate you configuration easily on new installation.

The technique consists in storing a Git bare repository in a "side" folder (like $HOME/.cfg or $HOME/.myconfig) using a specially crafted alias so that commands are run against that repository and not the usual .git local folder, which would interfere with any other Git repositories around.

Coupled with the alias

alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
config config --local status.showUntrackedFiles no

You then add only the files you want:

config add .vimrc
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
2

You could try gitignore.

cd ~
git init
echo '*' >> .git/info/exclude
echo '!.bashrc' >> .git/info/exclude
git add .bashrc
git commit -m'foo'

The patterns ignore all except .bashrc.

*
!.bashrc
ElpieKay
  • 27,194
  • 6
  • 32
  • 53
  • it looks like I can use a `.gitignore` too? oh... but then since it is my home directory, it can have effect to all my other repo – nonopolarity Feb 19 '20 at 07:00
  • @nonopolarity Yes, `.gitignore` is also okay. It does not have effect to all your other repos. One of the differences between `.gitignore` and `.git/info/exclude` is that the former can be committed as part of the source files (you can choose not to by ignoring `.gitignore` itself) and the latter can't. – ElpieKay Feb 19 '20 at 07:08
  • 1
    is it true "`~/.gitignore` applies to all the repositories on your computer (local, not shared with others)." https://stackoverflow.com/a/22906950/325418 – nonopolarity Feb 19 '20 at 07:16
  • @nonopolarity yes, you are right. I forgot that it's `~/.gitignore`. – ElpieKay Feb 19 '20 at 08:21
  • your solution seems to work best, but there is also something dangerous: in some folders under my home directory, I am seeing it treats it as part of the repo, and always telling me my `~/.bashrc` has uncommitted change. It feels really dangerous to have my home directory and every subfolder to be a giant repo constantly and if by any accident, I can be add or pushing files to the Internet, publicly, even my `~/.ssh/` private keys (if by any accident) – nonopolarity Feb 20 '20 at 02:53
  • For example, `create-react-app` is doing some `git` commands... I don't want any public script doing things under my `~/sourcecode` while my `~` is a git repo as seen in `~/sourcecode/react-app-01`. A react app that says "hello world" has 300MB of source code, and with massive amount of scripts... I really can't tell what they really are doing. When something doesn't work, I can google it. *But* when it adds everything to the repo and with me `git push` to the Internet, that's not good – nonopolarity Feb 20 '20 at 03:01
  • @nonopolarity You are right. It's a bad practice to initialize the home directory as a git repository. It could be annoying, and dangerous as you have realized. Don't insist on a git approach to this task. – ElpieKay Feb 20 '20 at 03:02
  • 1
    I guess one way is for me to have an alias or a function, so that I can do something like `cp ~/.bashrc ~/bashrc-repo && cd ~/bashrc-repo && git com -am "ok" && git push && cd -` – nonopolarity Feb 20 '20 at 03:08
  • That alias might be all you want, though `git diff` won't tell you if there have been any changes, or what they are, until you manually copy the file to the repo directory. – remcycles Feb 20 '20 at 21:55
  • @nonopolarity https://unix.stackexchange.com/questions/152733/bashrc-in-custom-folder might help. – ElpieKay Feb 21 '20 at 00:44
1

Check out Simple Revision Control SRC, a simple modern version control system for managing individual files (not collections of files changed in lockstep). Or look for the granddaddy of them all, Revision Control System RCS (probably even available as an official package for your favorite Linux distribution).

Fluff trivia of the day, not too long ago IBM's AIX code was managed with RCS (perhaps still as of today, that came out in the SCO vs IBM lawsuit).

vonbrand
  • 11,412
  • 8
  • 32
  • 52
  • is this a lightweight version control system... can it push to something just in case of hard drive issue? It probably is not aimed to replace git, right? `git` something is difficult to use with all those rebase and git stash complicated operations (to get really good by reading a book, it is a book with 450 pages) – nonopolarity Feb 19 '20 at 03:36
  • @nonopolarity, SRC handles git's fast-import and fast-export protocols, so you can send stuff offsite (never fiddled with that, though). It's repository format is just a hidden directory called `.src` with a file containg all history for each managed file in the current directory. – vonbrand Feb 19 '20 at 12:17