One way of combining data from two branches is to use merging tool. Merge can be done by fast-forward
or by recursive-strategy
. Fast-forward
is used when commits on a branch we want to merge to the current one are directly ahead of current HEAD. Git just moves pointer to the last commit. In other cases git looks for a common ancestor in two branches and starts from there trying to add changes to current branch. Sometimes this may result in conflicts which need to be resolved. Merging tool can be used by git mergetool
.
This is the second way of integrating data of branches. Rebase works little different than merge. After merge git history shows that there was parallel work done, with rebase it looks like its continous. Rebase works by going to the common ancestor of the two branches (the one you’re on and the one you’re rebasing onto), getting the diff introduced by each commit of the branch you’re on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn.
Rebase offers powerful interactive interface in which we can use squash command. It is helpful when we want to remove from history not meaningful commits. It works by melting down any number of commits and forming a new one with all changes preserved.
Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the HEAD commit.
Stashed changes are listed under git stash list
. To apply last stashed: git stash apply
or git stash pop
- the latter removes stashed changes from stash. To clear stash: git stash clean
Evertime the tip of a branch is changed git tracks it and makes a log of it. It is called reflog. A special type of reflog is also kept for stash. You can check reflog of specific branch or all branches at once. refs
can be used to point to specific commit in some git commands like so: git diff stash@{0} otherbranch@{0}
. Reflog can be filtered by a time: git diff master@{0} master@{1.day.ago}
. Refs from reflog can be deleted. Refs in reflog are preserved even when we use destructive
commands like rebase. We can still revert history by for ex. git reset HEAD@{2}
This is very dangerous command which rewrites git's commit history on specific remote. If You make a mistake, You are in trouble. Fortunately everything can be reverted. Just follow the steps: help I forcefuly pushed to master. Also it is a good idea to use --force-with-lease
instead of just --force
Sometimes some merge conflicts may occur while trying to pull work from remote or while merging branches. Conflicted files are explicitly listed by git. Each of those files will have conflict markers which point to specific lines of code. To resolve the conflict You have to decide which code to use, remove markers, stage and commit changes.
Always think twice while writing commit message. There are rules for that: rules set 1 and rules set 2 and rules set 3 Especially avoid messages like here