Hi there! Today I want to share with you some cool git tricks that I recently learned from a book, “Aprendiendo Git & GitHub” (Learning Git & GitHub), and maybe it can be interesting to someone, and it's also a self-recap for me. I will split the post into three parts for a better reading and writing experience.
In this book, we can find many pieces of advice and mentions of the importance of key concepts in the Git world, like good commit messages, descriptive PRs, and more. But here, I only want to share some useful commands I’ve learned. I’m at a trainee/junior level, so don’t judge me too harshly if the topics here are basic to you! Maybe you’ll learn something anyway 🤣. So, let's go on...
Git config
git config
allows to us to personalize somes core aspects of our git installation.
- You can list your current config like this :
# To see all your config
$ git config --list
# To see only your global scope config
$ git congit --global --list
# To see your local scope config
$ git config --local --list
# To see your system config
$ git config --system --list
# You can add the --show-scope parameter to see the scope of any config
# only available from 2.26.0 version of git
$ git config --list --show-scope
# You will see something like this
# system diff.astextplain.textconv=astextplain
# system filter.lfs.clean=git-lfs clean -- %f
# system filter.lfs.smudge=git-lfs smudge -- %f
# system filter.lfs.process=git-lfs filter-process
# system filter.lfs.required=true
# system http.sslbackend=openssl
# system http.sslcainfo=C:/Program Files/Git/mingw64/etc/ssl/certs/ca-bundle.crt
# system core.autocrlf=true
# system core.fscache=true
# system core.symlinks=false
# system core.editor=nano.exe
# system pull.rebase=false
# system credential.helper=manager
# system credential.https://dev.azure.com.usehttppath=true
# system init.defaultbranch=main
# global user.email=myMail@gmail.com
# global user.name=MyName
# global safe.directory=C:/xampp/htdocs
- You can change some configuration like, for example, the default text editor…
$ git config --global core.editor "code"
Here we tell Git that we want VS Code as our global default text editor instead of the nano editor. You can specify another scope or text editor if you want to.
- An other interesting thing you can do is set a global gitignore
$ git config --global core.excludefile path_to_the_file/.gitignore_global
Git checkout & git switch
We often use the checkout command to create and/or switch between branches in Git repositories.
It’s fine, but in fact, the checkout command is an old and powerful command that can do more things than just switching branches:
# Switch to a specific branch
$ git checkout <existing_branch_name>
# Create and switch to a new branch
$ git checkout -b <new_branch_name>
# Restore a file or many
# (Note: if you don't use the -- directive you are creating a new branch...)
# It will to restore the file to its state in the last commit
$ git checkout -- <file_1> <file_2> ...
# Restore a file to a specific commit state
$ git checkout <commit_id> -- <file>
# Switch to a specific commit
# Note: If you do this, you won't be on any branch. This state is called "detached HEAD."
# Any changes you make here can be lost because HEAD is not attached to a branch.
# To save your changes, you need to create a new branch from this point.
# In other words, you are not working on any branch at this moment.
$ git checkout <commit_id>
# Restore all the working tree
# It will to restore all to its state in the last commit
$ git checkout .
As you can see, the checkout command can do many things, and we may be doing something that we actually don’t want to do…
To solve these potential confusions, Git introduced the switch command in version ≥2.23:
# Switch to a specific branch
$ git switch <branch_name>
# Create and switch to a new branch
$ git switch -c <new_branch_name>
So to restore one o more files to the last commit state we have de restore command:
# Restore une o more files
$ git restore <file1>, <file2>
# Restore all working tree
$ git restore .
# Restore all files with js expension
$ git restore '*.js'
# Restore a file to a specific commit state
$ git restore --source <commit> <file>
Git reset
- If you accidentally add one or more files into the stashing area, you can run the reset command to solve this problem:
# Exit a file from the staging area
$ git reset <file>
- Git reset allows you to restore your branch to a specific commit
# Go back to the previous commit and SAVE THE CHANGES 😉
$ git reset --soft HEAD~1
# Go back to the previous commit and DISCARD ALL the changes
$ git reset --hard HEAD~1
# Go back to the second commit in this relative position
$ git reset --hard HEAD~2
# Reset the branch to the remote repo state
# WARNING: This will eliminate your local commits!
$ git reset --hard origin/<branch_name>
I use this git reset
when working on a feature or issue in my local branch, I might make several progressive commits, but I prefer not to "clutter" the commit history of the main branch with these intermediate commits. Instead, I aim to deliver a clean and concise PR with a single, well-organized commit.
This approach ensures that only one commit is added to the main branch's history, making it easier for the team or the person responsible for reviewing and merging the PR.
# Here we see only the commits in my local branch
$ git log --oneline --no-merges --branches --not --remotes
0f56980 (HEAD -> preprod) add_FTP_to_GA
1342e47 update_GA
# So, I want only one commit
# First, we reset to the last commit
# ⚠️ use --soft !! 😂
$ git reset --soft HEAD~2
# Then we can do a new sigle commit
$ git commit -m 'Add FTP integration and update GA configuration'
# And now we have only one commit
$ git log --oneline --no-merges --branches --not --remotes
e6bc2e1 (HEAD -> preprod) Add FTP integration and update GA configuration
Git rm
Imagine you added a .env
file, committed it, and then realized you forgot to add it to .gitignore
... maybe it's not too hard to imagine 🤣.
To fix this, you can use the git rm
command. While rm
itself is a shell command, git rm
is part of Git and provides additional functionality to help us manage files in our repository
# Remove the file from the repository but KEEP it locally
$ git rm --cached .env
# Add it to .gitignore to ensure it's ignored in the future
$ echo ".env" >> .gitignore
# Commit the changes
$ git add .gitignore
$ git commit -m "Remove .env and add it to .gitignore"
Note if you already push le .env file to your remote repo, is always recommended to update yours sensitives keys because one’s the .env file is in the remote repo this information can maybe already by exposed…
Git rebase
The git rebase
command is particularly useful when you want to keep your branch up-to-date with the main branch without introducing unnecessary merge commits. For example, if you're working on a feature branch (feature-branch
) and the main branch (main
) has received updates, you can use git rebase
to synchronize your branch with the latest changes. This repositions your commits so they appear as if they were made directly after the latest commits in main
, creating a cleaner and more linear history.
This approach makes the commit history easier to read and avoids introducing extra merge commits. It’s especially helpful when collaborating in teams, as it minimizes potential conflicts and simplifies the process of merging your changes back into the main branch.
# In your feature-branch
$ git pull --rebase origin main
# or
$ git fetch origin
$ git rebase origin/main
To ilustrate the situation :
with rebase : A---B---C---D'---E'---F’
without rebase : A---B---C---Merge---D---E---F
Another use case for git rebase
is when you want to modify your local branch's commit history before publishing it. It’s important to note that you should avoid making this type of modification if your branch has already been published, as it can generate conflicts by overwriting the existing commit history. You can squash multiple commits into one or change the commit’s messages and more.
# Here, -i is for interactive rebase
# HEAD~4 tells Git that we want to rebase the last 4 commits
$ git rebase -i HEAD~4
# In your text editor, you will see something like this:
pick <hash> Commit message A
pick <hash> Commit message B
pick <hash> Commit message C
pick <hash> Commit message D
# Now, you can modify the commit history:
# - 'reword' allows you to change the commit message of one or more commits.
# - 'squash' tells Git to combine commits into one.
# Example: Changing the message of the second commit and squashing the last two commits into one.
pick <hash> Commit message A
reword <hash> Commit message B # Change the message of this commit
squash <hash> Commit message C # Combine this commit with the previous one
squash <hash> Commit message D # Combine this commit with the previous one
# After saving and closing the editor:
# - If you used 'reword', Git will open an editor to change the commit message.
# - If you used 'squash', Git will prompt you to combine the commit messages.
# This way, you can clean up your commit history, making it more concise and readable before pushing or creating a PR.
I invite you to see more details in the documentation https://git-scm.com/docs/git-rebase
Conclusion
I think that's enough for this post. I have more things to share, but I'll save them for the next one. I'm looking forward to your comments and I hope you've learned something! If you have any recommendations or corrections, please let me know!
Thanks for reading, and see you next time!
Top comments (0)