Git: How to configure git to push only your current branch
You can change which branches will be pushed when saying git push
. Our recommendation is to set it to current
.
From the git-config
documentation:
push.default
Defines the action git push should take if no refspec is given on the command line, no refspec is configured in the remote, and no refspec is implied by any of the options given on the command line. Possible values are:
nothing
- do not push anything.- `matchin...
Git: Restore
tl;dr
git checkout
is the swiss army of git commands. If you prefer a semantically more meaningful command for restoring tasks, usegit restore
instead.With this command you can ...
- ... do unstaging -
git restore --staged
- ... discard staged changes -
git restore --staged --worktree
- ... discard unstaged changes -
git restore
- ... restore deleted files -
git restore
- ... restore historic versions -
git restore --source
- ... recreate merge conflicts -
git restore --merge
- ... specifiy...
Git commands to discard local changes
Use case
You have uncommited changes (you can always check by using git status
), which you want to discard.
Context
Now there are several options to discard these depending on your exact situation.
The headlines will differentiate the cases whether the files are staged or unstaged.
- Staged and unstaged changes
- [Staged changes](https://makandracards.com/makandra/516559-git-commands-to-discard-local-changes#s...
Git: Removing feature branches on merge
When working with feature branches, stale branches pile up over time. It's best to remove them right after merge, locally and on the remote, but it is a little tedious: you need to remember it, and perform the few steps manually each time.
Enter Git hooks. The folks at Liquid Light have built a little post-merge hook that will delete a feature branch on confirmation....
Git: rebase dependent feature branch after squash
This card will show you how to use git rebase --onto
without confusion.
Use case:
You've got two feature branches (one
and two
), where two
depends on one
. Now commits of branch one
have changed after you branched two
from it (i.e. after code review the commits of branch one
are squashed). Thus the commit history of branch one
has changed. Branch two
's history however didn't change.
Solution:
To make the branches share the same commit history again you will have to rebase and replay (attach) the a...
Automated "git bisect" will make your day
So you're hunting down a regression (or just a bug) and want to use git bisect
to find out when it was introduced? Smart kid.
If you have a shell command ready to reveal if your current state is good or bad, you can have git do most of the work for you.
Using git bisect run <your command>
you can tell git that your command will reveal the issue; git on the other hand will use the return value of that call to decide if the state is good or bad.
...
Recommended Git workflow for feature branches
This is a guide on how to effectively use Git when working on a feature branch. It is designed to get out of your way as much as possible while you work, and ensure you end up with clean commits in the end.
We assume you are the only person working on this branch. We also assume the branch has never been "partially" merged into master.
You want to start a feature branch
git checkout master
git checkout -b my-feature-branch
git push -u origin my-feature-branch
You've added code that works ind...
Use the Git stash without shooting yourself in the foot
The Git stash does not work like a one-slot clipboard and you might shoot yourself in the foot if you pretend otherwise.
In particular git stash apply
does not remove the stashed changes from the stash. That means you will probably apply the wrong stash when you do git stash apply
after a future stashing.
To keep your stash clean, you can use
git stash pop
instead.
Another way to look at it:
git stash pop
is the same as
git stash apply && git stash drop
Notice: In case of a conflict git will not pop th...
How to push to Git without running CI on GitLab CI, GitHub Actions, or Travis CI
If a project ist configured to spawn CI runners for tests or deployment when pushing to the Repo, a habit of pushing WIP commits regularly may conflict with that.
Here are two solutions that allow you to keep pushing whenever you feel like it.
Special commit message
To skip a CI run, simply add [ci skip]
or [skip ci]
to your commit message. Example:
git commit -m "wip authentication [ci skip]"
Git push options (GitLab)
In addition to that, GitLab CI supports Git push options. Instead of changing your commit message, ...
Git shortcut to fixup a recent commit
git --fixup
is very handy to amend a change to a previous commit. You can then autosquash your commits with git rebase -i --autosquash
and git will do the magic for you and bring them in the right order. However, as git --fixup
wants a ref to another commit, it is quite annoying to use since you always have to look up the sha of the commit you want to amend first.
Inspired by the [shortcut to checkout recent branches with fzf](https://makandracards.com/makandra/505126-g...
Git: How to rebase your feature branch from one branch to another
In a nutshell: Use git rebase --onto target-branch source-commit
-
target-branch
means "branch you want to be based on" -
source-commit
means "commit before your first feature commit"
Let's say my-feature-branch
is based on master
and we want it to be based on production
. Consider this history:
%%{init: { 'gitGraph': {'showCommitLabel': true, 'mainBranchName': 'production'}} }%%
gitGraph
commit id: "1"
commit id: "2"
branch master
commit id: "3"
commit id: "4"
branch my-feature...
Ignore commits when git blaming
You can ignore certain commits when using git blame with the --ignore-revs-file
option. This is handy to ignore large rubocop commits or big renamings in your project. You can add and commit a .git-blame-ignore-revs
file in your project to track a list of commits that should be ignored.
# a list of commit shas
123...
456...
Use git blame with the --ignore-revs-file
option and ignore the SHAs specified in .git-blame-ignore-revs
.
git blame --ignore-revs-file .git-blame-ignore-revs
If you want to use this flag by def...
How to split up a git commit
Quick steps
-
git rebase -i
-> mark your commit withedit
-
git reset HEAD~
(remove the marked commit, but keep its changes) - Make several commits (optionally setting the previous author manually)
git rebase --continue
Detailed instructions
Basically, you will review the last n
commits and stop at the splittable commit. Then you'll undo that commit and put its changes into new commits at your liking.
-
Review commits (
rebase
)git rebase -i HEAD~3 # or git rebase -i origin/master
...
Git stash: Working with old entries
First find the reference for the entry you want through looking at the stash:
$ git stash list
stash@{0}: WIP on feature/foo
stash@{1}: WIP on feature/bar
stash@{2}: WIP on fix/baz
Now you can simply use that reference, but curly braces must be escaped:
git stash pop stash@\{1\}
or quoted:
git stash apply "stash@{1}"
Quick reminder to [not shoot yourself in the foot](https://makandracards.com/makandra/634-use-the-git-stash-withou...
Git: How to stage hunks with a single key press
In interactive commands, Git allows the user to provide one-letter input with a single key without hitting enter (docs).
# Enabled this feature globally
git config --global interactive.singlekey true
# Or enable this feature locally for a single repository
git config interactive.singlekey true
This allows you to hit "y
" instead of "y + ENTER
" to move to the next hunk.
Stage this hunk [y,n,q,a,d,s,e,?]?
Parallelize Development Using Git Worktrees
You can use git worktree
to manage multiple working trees attached to the same repository. But why should I use git worktree
?
You can use more than one working tree to ...
... run tests while working on another branch
... compare multiple versions
... work on a different branch without disturbing your current branch
Creating a new working tree is as simple as creating a new branch. You only need to execute git worktree add <path> <branch>
. When you are done, you can remove the working tree with git worktree remove <Worktree>
...
Git: Advisory for cherry-picks to production branches
We often have a separate production branch that lags a bit behind the more cutting edge main branch. Sometimes you want to move some, but not all commits from main to production. This can be done with a git cherry-pick
.
However, this may lead to considerable pain later, since git does not understand the commits are actually "the same". Hazards are unnecessary and hard to resolve conflicts as well as incorrect auto-merges.
In order to avoid this, always merge the production branch back to the main after the cherry-pick. Even t...
Git restore vs. reset for reverting previous revisions
The git doc states on the difference of these two commands:
- git-restore[1] is about restoring files in the working tree from either the index or another commit. This command does not update your branch. The command can also be used to restore files in the index from another commit.
- git-reset[1] is about updating your branch, moving the tip in order to add or remove commits from the branch. This operation changes the commit history.
git reset can also be used to restore th...
Git: Switching back to the previous branch
Using git checkout -
you can switch back to the branch you previously worked on.
(master) $ git checkout foobar
Switched to branch 'foobar'
(foobar) $ git checkout -
Switched to branch 'master'
(master) $
This also works with other commands like git merge
:
(master) $ git checkout foobar
Switched to branch 'foobar'
(foobar) $ git merge -
Merged branch 'master'
Git: Splitting up changes into several commits
Splitting up commits makes the process of reviewing often easier, since you can create several merge requests or review every commit one by one.
So when you find out that you have portions of the code that you initially didn't intend to change or when you do some refactoring along the current changes, you can use one of the following processes to split up the changes into several commits in a logical order:
#1 Splitting up the last n commits into m commits
#2 Adding changes to a previous commit
2.1 While adding new changes
2.2 S...
Git: Improve your commits by reviewing changes one-by-one
Git commits should be very deliberate, and only contain changes that you really want to be in there. In order to reduce the chance to accidentally commit something you didn't intend, review your changes before committing.
My preferred way of doing this is (only using git)
git add -N . # Add all paths, but not their contents
git add -p
Git will now show you all your changes in small chunks and ask you in an interactive mode whether you really want to add them.
The most helpful commands are
- y: yes (add the change)
- ...
Rails developers: Have better context in Git diffs
Git diffs show the surrounding contexts for diff hunks. It does so by applying regular expressions to find the beginning of a context. When it comes to Ruby, however, it will not find method heads and travel up to the class definition:
@@ -24,7 +24,7 @@ class TicketPdf # <=== Actually expected here: the method definition
ApplicationController.render(
"tickets/index.html.haml",
layout: "tickets",
- assigns: { tickets: tickets }
+ assigns: { tickets: tickets, event_name: event_name }
)
end
end
```...
Style Guide for Git commit messages
- Separate subject from body with a blank line
- Limit the subject line to 50 characters (max. 72), include reference (unique story ID) to requirements tracker (Linear in our case)
- Capitalize the subject line
- Do not end the subject line with a period
- Use the imperative mood in the subject line
- Wrap the body at 72 characters
- Use the body to explain what and why vs. how.
Tip
As an alternative, use a commit message that refers to a GitHub issue (
fixes #321
) or [story ID](https://makandracards.com/makandra/620718-b...
Configuring Git with .gitconfig
Basic configuration
Please keep this config simple. It should be a starting point for new developers learning Git.
[user]
name = Your Name
email = your.name@domain.com
[branch]
sort = -committerdate
[color]
ui = auto
[color "branch"]
current = yellow reverse
local = yellow
remote = green
[color "diff"]
whitespace = white reverse
meta = blue reverse
frag = blue reverse
old = red
new = green
[color "status"]
added = green
changed = yellow
untracked = cyan
[interactive]
singlekey = true # Do not requir...