0

thanks for reading!

I was starting to setup my dotfiles configuration with git and GitHub and came across a problem: I am using my $HOME as my git work tree and have the .git-directory in my $HOME/.dotfiles-directory, by using an alias:

alias dotfiles="git --git --git-dir=$HOME/.dotfiles/.git/ --work-tree=$HOME" 

I created a new Repository on GitHub and added the LICENSE and the README there. When I clone my Repository like this:

git clone \<url to the repository\> $HOME/.dotfiles 

The LICENSE and the README are located in the .dotfiles-directory, but the command:

dotfiles status 

lists them as removed!

I do not want the LICENSE and the README in my $HOME-directory. They should stay where they are in the $HOME/.dotfiles-directory.

What can I do about that?

1
  • Is it helpful to provide the real link? There is nothing in the Repository, except the LICENSE and the README. Commented Nov 23, 2020 at 14:11

1 Answer 1

1

It is actually possible to have LICENSE and README file in a master branch that github and gitlab will honor (be displayed on your project home in github or gitlab), but not in your home directory. The easiest solution is to put README in .github folder at project home, but it only works for github.

But what I actually did to have LICENSE and README displayed at project home in gitlab and github is this:

1. Initiate a bare git repository or replicate existing repository

First initiate a bare git repo for xadf and make initial commits without readme and/or license, and make your alias. The alias can be anything you want (eg. dotfiles), but I use gitdf so it is easier to type.

# Initialize a bare git directory git init --bare $HOME/.dotfiles # Sets up an alias so you don't have to type long commands alias gitdf='git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME' # Adds a remote where you'd push your changes gitdf remote add origin [email protected]:yourusername/dotfiles.git # Do not display untracked files (it would be a ton of untracked files in an actual home tree gitdf config status.showUntrackedFiles no 

Or if you already have a dotfiles repository, you may want to replicate it to your home:

# Clone existing repo with separate git directory (here it is ~/.dotfiles), and the work tree in a separate, temporary directory .dotfiles-temp git clone --separate-git-dir=$HOME/.dotfiles https://github.com/yourusername/dotfiles.git .dotfiles-temp # Copy the content of the temporary work tree to ~/ rsync --recursive --verbose --exclude '.git' .dotfiles-temp/ $HOME/ # Remove the temporary work tree rm --recursive .dotfiles-temp # Sets up an alias so you don't have to type long commands alias gitdf='git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME' # Sets remote directory gitdf remote set-url origin [email protected]:yourusername/dotfiles.git 

Note that you may need to add the alias to your .bashrc so it will persist for each login.

2. Then we make a branch

This is the actual branch you would have checked out in your real home tree. Say, a home branch.

# Make branch 'home' gitdf checkout -b home # You may need to also add the branch to gitlab or github gitdf push --set-upstream origin home 

3. In branch master, adds README and LICENSE

Then in branch master, you can safely adds a readme file and a license if you like. This will only be used to provide information in project home at gitlab or github. This file will not be present at commit history of branch home, and should never be introduced in your home branch.

# Switch back to branch 'master' gitdf checkout master # Make readme and license touch ~/LICENSE ~/README.md # Add them to your bare git repo gitdf add LICENSE README.md # Commit gitdf commit # Push gitdf push 

4. Only make changes to actual working branch

Then move back to branch home, this should be the actual checked out branch for your dotfiles, where a readme file or a LICENSE file is never present in its commit history.

gitdf checkout home 

Post set up

Afterwards, changes to config files are done from home branch only, or any branch derived from branch home. You may need to occasionally (or routinely) merged them to master:

# Go to branch master gitdf checkout master # merge branch home to branch master gitdf merge home # push to remote gitdf push 

Since branch home does not have LICENSE and README.md, the merge will not result in conflicts.

But you should never do it the other way around (eg. from branch home, gitdf merge master), as it will also add LICENSE and README.md to your working home directory.

Multiple machine-specific configurations in each specific branch

As an added bonus, you may want to derive branch home for other specific uses (for example in branch work that is supposed to be based from home but with work-specific configs):

# Check if we're in branch home gitdf status -sb # Checkout to branch home if we are not gitdf checkout home # Note that the -b flag means make branch if it does not exist gitdf checkout -b work # Add new branch to remote gitdf push --set-upstream origin work # Configure or add work-specific changes then commit gitdf add .config/work/related/configfile gitdf commit # Push to remote gitdf push 

Later when you make changes in your home branch, all you have to do to also have it in your work branch is just:

# move to branch work gitdf checkout work # merge branch home to branch home gitdf merge home # Push to remote gitdf push 

If you have other branch (all branched from home, meaning you have to start from branch home and make the new branch), like laptop, you can also merge home to them when necessary. You can also merge the changes made there to home if needed.

Though, really, I would advise to make shared configs from home and later merge them to necessary branch and master.

Therefore, you can visualize the merge direction like this:

master < home <> work <> laptop 

only merge home to master, work, or laptop, or from work, laptop, to home, but never merge master to home.

Real life application

As a shameless plug, you can see how I set up this git alias methods in my dotfiles repository. It is a more polished and moderately sophisticated implementation of the steps described above. To install that, all I have to do is to download the installer and controller script (xadf), make it executable, and place it somewhere in my PATH.

# Make directory, if it isn't present already mkdir -p ~/.local/bin # Download the executable into your local bin directory wget -O ~/.local/bin/xadf https://gitlab.com/heno72/xadf/-/raw/master/.local/bin/xadf # Make it executable chmod +x ~/.local/bin/xadf # Export path to local bin if it isn't set up already PATH=~/.local/bin:$PATH # Install xadf minimally xadf --minimal-install 

The script can take care of step 1 (replication), checks out to a working branch (default to trunk, equivalent to home branch in my example above), including generation of configuration file for future use (alias and some functions) in ~/.config/xadf:

# initialize, configure, load, and manage xadf --init-bare --seat ~/.dotfiles xadf --custom-install --seat ~/.dotfiles . ~/.bashrc xadf config status.showUntrackedFiles no 

Or if you already have your own bare git repository available in a remote:

# Clone and configure from a custom url, load, and manage xadf -i -s [email protected]:heno72/xadf-gb.git --seat ~/.dotfiles . ~/.bashrc xadf status -sb 

If you already have your bare git directory in your home folder, you can use xadf to manage them instead with:

xadf --custom-install --seat ~/.dotfiles . ~/.bashrc 

After installation (and .bashrc is sourced), I can use the script like any git commands:

# Adds a new config file to tracked file xadf add .config/new/config/file # Commit changes xadf commit # Push changes to remote xadf push # Change working branch xadf checkout newbranch 

Or some predetermined actions:

xadf -l # list all tracked files xadf -l .config # list all tracked files in ~/.config 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.