DEV Community

Two Bash scripts I cannot live without when working with Git

Eryk Napierała on November 16, 2019

That's maybe an overstatement, but just a little. I use these two simple scripts for over five years now and I just cannot imagine to not have them...
Collapse
 
moopet profile image
Ben Sinclair

I do something similar to your git_clean_local_branches here: git-tidy

It's interesting to see how we both went for basically the same experience but approached it in different ways.

Collapse
 
erykpiast profile image
Eryk Napierała

Believe or not, but I didn't know that script. Thanks! Multiple discovery hipothesis confirmed! :)

Collapse
 
jsn1nj4 profile image
Elliot Derhay

Interesting. I use Linux on my personal laptop. But being a Windows user at work, I've found myself using PowerShell instead. Will see if I can reimplement these in PS and share. :)

Collapse
 
jsn1nj4 profile image
Elliot Derhay • Edited

I have a suggestion though. For cleaning untracked files, can you prevent having to run git clean -f -d -n twice by storing the output once and then running it through wc -l for checking in the if condition?

Similarly for cleaning branches, what about storing the output of git branch -r | awk "{print \\$1}" | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk "{print \\$1}"?

I should add I'm suggesting this as someone who doesn't do that much bash scripting, so maybe there's an issue you ran into that I'm not aware of when just reading those one-liners.

Collapse
 
erykpiast profile image
Eryk Napierała

It turned out that echo -n trick isn't correct neither. I've decided to add the second condition for empty string, so the final version is:

TO_REMOVE=`git clean -f -d -n`;
if [[ "$TO_REMOVE" != "" ]] && [[ `echo $TO_REMOVE | wc -l | bc` != "0" ]]; then
Thread Thread
 
jsn1nj4 profile image
Elliot Derhay • Edited

What about wc -l "$TO_REMOVE"?

Thread Thread
 
erykpiast profile image
Eryk Napierała

I don't think it gonna work. It tries to read a file under the path saved in $TO_REMOVE variable. That's not what we want to do.

Thread Thread
 
jsn1nj4 profile image
Elliot Derhay

Oh interesting. Never mind then. Thanks for helping me understand all of this.

Collapse
 
erykpiast profile image
Eryk Napierała

You're perfectly right! Back then I had some issues with the "clean" solution and no idea how to do it better. It just worked, so I kept it like this :)

You made me feel a bit challenged, though, so I've decided I'll try to fix the issue.

Basically, the ideal solution would look like this:

TO_REMOVE=`git clean -f -d -n`;
if [[ `echo $TO_REMOVE | wc -l` -ne "0" ]]; then

For some reason, it doesn't work in the case when there is nothing to clean - line count is always equal or greater to one. I cannot remember it, but I suppose that was the exact issue five years ago when I was writing the script.

But now I'm smarter (or just know Bash a bit more :) ) and I know how to do it right! echo adds a new line to the end of the printed string, even when it's empty. Unless -n switch is specified! So the code below works perfectly in all cases.

TO_REMOVE=`git clean -f -d -n`;
if [[ `echo -n $TO_REMOVE | wc -l` -ne "0" ]]; then

I'll update the scripts in the article. Thank you!

Collapse
 
msfjarvis profile image
Harsh Shandilya

For anything augmenting Git I either build an alias for one-liners, or save it into a file titled git-<action> in PATH which lets me do git <action> like any other git subcommand. You should try that! git clean-safely is probably easier and quicker to type than git_clean_untracked_safely :D

Collapse
 
erykpiast profile image
Eryk Napierała

Totally agree! I'm really into three-letter aliases so this command is for me gcl :)

Collapse
 
pavelloz profile image
Paweł Kowalski

git clean is a very cool thing in general. I use it in npm scripts to clear things before build (build is usually gitignored). No need for additional packages like rimraf (and not every OS has rm)

Collapse
 
euphnutz profile image
Brian Cuerdon

You should change your test statement to:

if [[ -n "$TO_REMOVE" ]]; then

This will remove the dependency on bc.

Collapse
 
erykpiast profile image
Eryk Napierała

That's smart! So instead of counting lines, I'm checking if the string is not empty, right?

Collapse
 
euphnutz profile image
Brian Cuerdon

Yep! Using the bash string comparison operator -n: tldp.org/LDP/abs/html/comparison-o...

Thread Thread
 
erykpiast profile image
Eryk Napierała

Wonderful! Thank you for the suggestion :)

Collapse
 
tgu profile image
T-G-U

Hello,

I'd suggest little change for your gcl alias - in linux, this one refers to lisp interpreter.

Collapse
 
erykpiast profile image
Eryk Napierała

Huh, I wasn't aware of that. My experience with lisps didn't go beyond Clojure so far. Thank you for the suggestion, I'll add a note to the article!

Collapse
 
flavius profile image
Flavius Aspra

I would rewrite them in xonsh.