0

I'm trying to parse the branch I'm currently checked out into to my bash prompt. This is quite easy using the following bash function in your PS1:

parse_git_branch() {
 git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\[$(tput setaf 3)\]\u\[$(tput setaf 2)\]@\[$(tput setaf 4)\]\h \[$(tput setaf 5)\]\w\[$(tput setaf 7)\]\[$(tput setaf 3)\]\$(parse_git_branch) \[$(tput setaf 7)\]\\$ \[$(tput sgr0)\]"

My problem arises when the prompt still shows a 'checked out' branch from within a folder inside the .gitignore file. For instance: Let's suppose /home/rbroggi/workspace/project_one is the root of my repository tracked by git ( e.g.: the place where the .git folder is to be found). And within this repository I have a .gitignore file /home/rbroggi/workspace/project_one/.gitignore with the following record: ignoredfolder/. I would assume an empty output/result from git branch once changing directory into the ignoredfolder but instead it keeps outputting the branch I'm checked out in the parent folder. This is very annoying and maybe if I had visibility over how the command git branch works I could avoid getting the output for ignored folders.

rbroggi@arch ~/workspace/project_one (master) $ pwd
/home/rbroggi/workspace/project_one
rbroggi@arch ~/workspace/project_one (master) $ cat .gitignore
ignoredfolder/
rbroggi@arch ~/workspace/project_one (master) $ cd ignoredfolder/
rbroggi@arch ~/workspace/project_one/ignoredfolder (master) $ git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
 (master)
rbroggi@arch ~/workspace/project_one/ignoredfolder (master) $

Thank you for taking the time to trying and helping me.

Rodrigo Broggi

  • I believe that's how Git works. Any child folder/file to the Git's root directory (the `.git` folder at) is part of the Git source control. `.gitignore` is used to instruct Git that you're not interested in source controlling the files/folders reference in that file. This doesn't mean you can't source control it by `git add -f ignoredfolder`, this will still work. If you really want the branch name to disappear on them folders. You'll need to factor in a way to read the `.gitignore` do some path matching. So I would say don't get hung up on this. – Prav Jan 19 '19 at 14:41
  • It is just an indication to the user that anything you're changing on that repo will be committed under that branch. Most people don't remeber to chacke the working branch before good part of the work is done. This functionality to just to make it easier to work with git, so you don't need to stash and apply just because you're on the wrong branch. – Prav Jan 19 '19 at 14:45
  • BTW: The functionality to add the git branch (and other info) to the prompt is already available. I don't know your environment, but you can just try to execute `__git_ps1` (while in a git repo). This function comes with git. On Ubuntu it is loaded by `/etc/bash_completion.d/git-prompt` and the file in the git installation is named `git-sh-prompt` (part of git-core i think). Most likely also `__git_ps1` displays the branch while in a ignored folder. – Ralf Jan 19 '19 at 15:16
  • 1
    Git largely does not care about directories, all it cares is whether it can find a valid `.git` directory while climbing "up" the chain. Having reached the top level of your work-tree with the `.git` in it, Git decides that, yes, you are in a Git repository—it doesn't matter *where* in it, just that you *are* in it. If Git needs to operate on a file in any given directory, for any reason, it will create that directory if required. If not, it will leave that directory alone. So you're in a directory Git won't need to touch, and it will leave it alone, but that's the extent of it. – torek Jan 19 '19 at 18:15
  • I thought that it worked like that (climbing up mechanism). What I'm trying to accomplish would work if only once the algorithm finds the ".git" directory it could also check if the directory where it comes from is outside of the ```.gitignore``` file, returning, only in this case, the checked out branch. – Rodrigo Broggi Jan 20 '19 at 15:30

1 Answers1

0

You are assuming that different parts of your worktree could be checked out differently. That is incorrect.

(You can use git checkout to update specific worktree files to match the version from a different commit, but that doesn't change what version is checked out; it just means you have uncommitted changes to that file, which if committed would cause that file to match the other commit's version.)

A given branch (or, in detached head state, a given commit) is checked out for the entire repo. .gitignore has nothing to do with that, and no matter where you go in your worktree, it will be the same. If you see a situation where cding seems to change what branch you're on, it's because you've changed what worktree you're in.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • HI Mark, actually my assumption was that the ```.gitignore``` file would map what should be considered **out of my worktree** by git. It seems it does not work like that but I can't figure out a reason why git couldn't **really ignore** children folders altogether. – Rodrigo Broggi Jan 20 '19 at 15:36
  • 1
    @RodrigoBroggi - Why couldn't it be that way? For one thing, ignore rules generally apply to files, not folders. (You can specify a pattern that means "all paths under this folder", and there is a quirk in how other paths are interpreted when you do, but for the most part git doesn't know/care about folders and ignores the *files* that match that pattern). And ignore rules only apply to *untracked* files, so if something was already in the repo in that folder, it would still be there and still check out to that folder. And even if the folder is empty now, you could force add something to it – Mark Adelsberger Jan 20 '19 at 17:12
  • I didn't thought about that case (case where a file inside a folder has been added before marking the folder to as ignored). This is pretty satisfying as explanation. My only frustration is that I was hoping to have a git repo in my home directory to track the changes on my `dotfiles` but I wold need to ignore all the other folders in my home. It seems that the best solution is to replicate the repo in another directory instead of using the home as a git repo it... – Rodrigo Broggi Jan 21 '19 at 18:38