# Git: How to boost your performance

Git is an amazing tool that help us developers a lot to control the version of our projects, it has a lot of build in features, but we can improve it to have a better experience.

In this article, I'll share my configuration of git and a documentation about what each thing does.

## Template

```js
const name = ""
const email = ""
const defaultBranch = "master"

const foo = () => {
	if (name === "") {
		throw new Error("You must fill your name")
	}
	if (email === "") {
		throw new Error("You must fill your email")
	}

    console.log(`
# Version: 1.6.0

[user]
	name = ${name}
	email = ${email}

[init]
	defaultBranch = ${defaultBranch}

[pull]
	default = current

[push]
	default = current

[core]
	eol = lf # Defines eol using Linux format
	autocrlf = input

[url "ssh://git@github.com/"]
	insteadOf = https://github.com/

[alias]
	# Clean
	gone = "!f() { git fetch -p && git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' | xargs git branch -D; } ; f" # https://medium.com/darek1024/how-to-clean-local-git-branches-that-were-removed-on-the-remote-4d76f7de93ac
	cln = prune -v --progress # Remove Branches That No Longer Exists In Repository
	ignore = "!f() { git rm --cached \`git ls-files -i -c --exclude-from=.gitignore\`; } ; f" # Removes Files That Are In .gitignore From The Repository
	# Clone
	cn = clone # Clone Project
	cnsb = "!f() { git clone -b $* $*; } ; f" # Clone specific branch from project
	# Fork
	updfork = git fetch upstream # Update your fork
	# Remote
	rls = remote -v # Return a List of All Branches In Repository
	rrem = "!f() { git remote remove origin; } ; f" # Remove Origin Repository
	radd = "!f() { git remote add origin $*; } ; f" # Add a Repository as Origin
	ratt = "!f() { git remote remove origin && git remote add origin $*; } ; f" # Updates the Origin Repository
	ups = "!f() { git branch --set-upstream-to=origin/$1 $1; } ; f" # Set Branches Upstream
	# ${defaultBranch} Branch
	pum = pull origin ${defaultBranch} # Pull From ${defaultBranch}
	pom = push origin ${defaultBranch} -u # Push to ${defaultBranch}
	# Add
	a = add . # Stage All Changes
	# Pull
	pl = pull # Get Project From Repository
	# Push
	ps = "!f() { git push -f; } ; f" # Push Changes to Repository
	psn = "!f() { git push -f --no-verify; } ; f" # Push Changes to Repository
	psu = "!f() { git push --set-upstream; } ; f" # Create a Link Between Local Branch And Repository Branch
	acips = "!f() { git a && git ci $* && git ps; } ; f" # Stage Changes, Create Commit And Push To Repository
	acaps = "!f() { git a && git ca $* && git ps; } ; f" # Stage Changes, Amend Commit And Push To Repository
	acipsn = "!f() { git a && git commit -m \"$*\" --no-verify && git push -f --no-verify; } ; f" # git acips With --no-verify
	acapsn = "!f() { git a && git commit --amend -m \"$*\" --no-verify && git push -f --no-verify;  } ; f" # Stage Changes, Amend Commit And Push To Repository
	# Commit
	ci = "!f() { git commit -m \"$*\"; } ; f" # Stage Changes and Create Commit
	ca = "!f() { git commit --amend -m \"$*\"; } ; f" # Stage Changes and Amend Commit
	author = "!f() { git commit --amend --author=\"${name} <${email}>\"; } ; f" # Change Commit Author
	# Branch
	b = branch # List All Local Branches
	bd = "!f() { git branch -D $*; } ; f" # Delete Local Branch
	bn = "!f() { git branch -m $*; } ; f" # Change Branch Name
	# Checkout
	ckm = "!f() { git checkout ${defaultBranch} && git pull origin ${defaultBranch}; } ; f" # Change To ${defaultBranch} Branch And Git Pull
	ckd = "!f() { git checkout dev && git pull origin dev; } ; f" # Change To dev Branch And Git Pull
	ckp = "!f() { git checkout $* && git pull; } ; f" # Change Branch And Git Pull
	ck = "!f() { git checkout $*; } ; f" # Change Branch
	cb = "!f() { git checkout -b $*; } ; f" # Create New Branch
	# Rebase
	rbd = "rebase dev" # Rebase Actual Branch With dev Branch
	rbm = "rebase ${defaultBranch}" # Rebase Actual Branch With ${defaultBranch} Branch
	rbh = "!f() { git rebase -i HEAD~$*; } ; f" # Rebase commits (Merge multiple commits in one)
	rbc = "!f() { git a && git rebase --continue; } ; f" # Incase of conflict, you will have to fix it, and then, use this command to continue
	rmm = "!f() { git rebase -i origin/${defaultBranch}~$* ${defaultBranch}; } ; f" # Merge all the commits of ${defaultBranch} branch
	# Stash
	sts = stash
	sta = stash apply
	std = stash drop
	stl = stash list
	stc = stash clear
	# Merge
	mg = merge --no-ff
	cat = checkout --theirs . # Resolve all conflicts accepting INCOMING changes
	cao = checkout --ours . # Resolve all conflicts accepting CURRENT changes
	# History
	sf = show --name-only
	lg = log --pretty=format:'%Cred%h%Creset %C(bold)%cr%Creset %Cgreen<%an>%Creset %s' --max-count=7 # Show the 7 latest commits minified
	# Diff
	st = status # List Changes
	su = "!f() { git status --short | grep --color -E '^(AA|UU)'; } ; f"
	ss = "!f() { git status --short | grep --color -E '^(M |A |C )'; } ; f"
	incoming = !(git fetch --quiet && git log --pretty=format:'%C(yellow)%h %C(white)- %C(red)%an %C(white)- %C(cyan)%d%Creset %s %C(white)- %ar%Creset' ..@{u})
	outgoing = !(git fetch --quiet && git log --pretty=format:'%C(yellow)%h %C(white)- %C(red)%an %C(white)- %C(cyan)%d%Creset %s %C(white)- %ar%Creset' @{u}..)
	# Undo
	unstage = reset HEAD --
	undo = checkout . # Undo Changes
	rollback = reset --soft HEAD~1 # Undo last commit
	# Transfer
	tsf = "!f() { git show $1:$2 > $2 } ; f" # Move changes from a file to another
`)
}

foo()
```

## How to setup

* Copy the template
    
* Paste it on your browsers console
    
* Add your name and email to the variables at the beginning of the template
    
* Execute it
    
* Copy the output
    
* Open your `.gitconfig` file, usually at `~/.gitconfig`
    
    * I personally use VSCode, so I can run the command `code ~/.gitconfig` to open it
        
* Paste the output in there and save
    
* Restart your terminal to apply the changes
    

## Documentation

```plaintext
# Version: 1.4.1
```

This is the version of the gitconfig file (probably it's different from the template, because I'll for sure forget to update it in here, but you get the idea), to help you know when new things are added or things are fixed.

```plaintext
[init]
	defaultBranch = ${defaultBranch}
```

This is for when you start a new git repository, your default branch is called `master`, you can change it if you want.

```plaintext
[pull]
	default = current

[push]
	default = current
```

This defines that wherever you run `git pull` or `git push` it understands that you want to pull/push the current branch and not some other branch.

```plaintext
[core]
	eol = lf # Defines eol using Linux format
	autocrlf = input
```

This part is extremely important when you are working in projects where people may use different OS. To know more about it, please hear [this article](https://www.aleksandrhovhannisyan.com/blog/crlf-vs-lf-normalizing-line-endings-in-git/).

```plaintext
[alias]
```

This is the beginning of the [git aliases](https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases) definition.

```plaintext
	# Clean
	gone = "!f() { git fetch -p && git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' | xargs git branch -D; } ; f" # https://medium.com/darek1024/how-to-clean-local-git-branches-that-were-removed-on-the-remote-4d76f7de93ac
	cln = prune -v --progress # Remove Branches That No Longer Exists In Repository
	ignore = "!f() { git rm --cached \`git ls-files -i -c --exclude-from=.gitignore\`; } ; f" # Removes Files That Are In .gitignore From The Repository
```

These are commands for cleaning your git things.

`gone` \[WIP\] prunes all the branches that doesn't exist in the remote repository (like GitHub).

`cln` \[WIP\] prunes all the branches that doesn't exist in the remote repository (like GitHub).

`ignore` remove all the files that were added to `.gitignore`. Ex: You commit `foo.txt` and later adds it to `.gitignore`, it will continue to exist and be tracked by git. To prevent it, you need to run this command.

```plaintext
	# Checkout
	ckm = "!f() { git checkout ${defaultBranch} && git pull origin ${defaultBranch}; } ; f" # Change To ${defaultBranch} Branch And Git Pull
	ckd = "!f() { git checkout dev && git pull origin dev; } ; f" # Change To dev Branch And Git Pull
	ckp = "!f() { git checkout $* && git pull; } ; f" # Change Branch And Git Pull
	ck = "!f() { git checkout $*; } ; f" # Change Branch
	cb = "!f() { git checkout -b $*; } ; f" # Create New Branch
```

`ckm` change to the `defaultBranch` and runs `git pull`

`ckd` change to the `dev` branch and runs `git pull`

`ckp` change to the branch that you specify and runs `git pull`

`ck` change to the branch that you specify (shortcut for `git checkout`)

`cb` creates a new branch and checkouts to it (shortcut for `git checkout -b`)

```plaintext
	# Rebase
	rbd = "rebase dev" # Rebase Actual Branch With dev Branch
	rbm = "rebase ${defaultBranch}" # Rebase Actual Branch With ${defaultBranch} Branch
	rbh = "!f() { git rebase -i HEAD~$*; } ; f" # Rebase commits (Merge multiple commits in one)
	rbc = "!f() { git a && git rebase --continue; } ; f" # Incase of conflict, you will have to fix it, and then, use this command to continue
	rmm = "!f() { git rebase -i origin/${defaultBranch}~$* ${defaultBranch}; } ; f" # Merge all the commits of ${defaultBranch} branch
```

> WIP

```plaintext
	# Stash
	sts = stash
	sta = stash apply
	std = stash drop
	stl = stash list
	stc = stash clear
```

Shortcuts to work with [git stash](https://git-scm.com/docs/git-stash).

```plaintext
	# Merge
	mg = merge --no-ff
	cat = checkout --theirs . # Resolve all conflicts accepting INCOMING changes
	cao = checkout --ours . # Resolve all conflicts accepting CURRENT changes
```

> WIP

```plaintext
	# History
	sf = show --name-only
	lg = log --pretty=format:'%Cred%h%Creset %C(bold)%cr%Creset %Cgreen<%an>%Creset %s' --max-count=7 # Show the 7 latest commits minifiedwhite)- %C(cyan)%d%Creset %s %C(white)- %ar%Creset' @{u}..)
```

Shows the commits history.

> WIP

```plaintext
	# Diff
	st = status # List Changes
	su = "!f() { git status --short | grep --color -E '^(AA|UU)'; } ; f"
	ss = "!f() { git status --short | grep --color -E '^(M |A |C )'; } ; f"
	incoming = !(git fetch --quiet && git log --pretty=format:'%C(yellow)%h %C(white)- %C(red)%an %C(white)- %C(cyan)%d%Creset %s %C(white)- %ar%Creset' ..@{u})
	outgoing = !(git fetch --quiet && git log --pretty=format:'%C(yellow)%h %C(white)- %C(red)%an %C(white)- %C(cyan)%d%Creset %s %C(white)- %ar%Creset' @{u}..)
```

Shows the difference between a branch and another.

> WIP

```plaintext
	# Undo
	unstage = reset HEAD --
	undo = checkout . # Undo Changes
	rollback = reset --soft HEAD~1 # Undo last commit
```

Undo your changes.

> WIP

```plaintext
	# Transfer
	tsf = "!f() { git show $1:$2 > $2 } ; f" # Move changes from a file to another
```

Kinda complicate, but very useful in some cases.

> WIP
