Git
Git notes
Branch Management
Note: in most cases, remote_name
will be origin
To delete a local branch
Use git branch -d <branch>
to delete a local branch
To delete a remote branch
Use git push <remote_name> -d <branch>
To delete a local remote tracking branch
git branch --delete --remotes <remote_name>/<branch>
git branch -dr <remote_name>/<branch> # Shorter
To push local branch to remote
git push -u <remote_name> <branch>
will push <branch>
to remote by creating a new branch on remote_name
and setting local branch
to track remote branch on remote_name
Note: -u
option is the shortcut for the --set-upstream
option (e.g., git push --set-upstream origin master
– remember, origin
is an alias to the remote)
To pull and track a remote branch
git checkout --track <remote_name>/<branch>
: this command will create a local branch named branch
, tracking the remote branch <remote/daves_branch
Note: --track
is shorthand for git checkout -b [branch] [remotename]/[branch]
where [remotename]
is origin
in this case and [branch]
is twice the same, daves_branch
in this case
To create a new branch off of the current branch
git checkout -b <branch>
To print what origin
points to
origin
is an alias on your system for a particular remote repository
git remote show origin
References
- https://stackoverflow.com/questions/2003505/how-do-i-delete-a-git-branch-locally-and-remotely
- https://stackoverflow.com/questions/9537392/git-fetch-remote-branch
File management
The “index” holds a snapshot of the content of the working tree, and it is this snapshot that is taken as the contents of the next commit. Thus after making any changes to the working tree, and before running the commit command, you must use the add command to add any new or modified files to the index.
To add all modified files to the index
git add .
To add a specific file or directory to the index
git add <filename>
To remove file matching pathspec from the index
git rm --cached <filename>
Stashing
git stash
can be used to “stash” some changes so that they are no longer in your working tree. This allows you to checkout other branches without having to add changes to the index. Usually, this is used when you begin to work on some branch and then realise you are working on the wrong branch. You can use git stash
to “stash” these changes (out of the working tree), checkout to the appropriate branch, and apply the stashed changes.
git stash # to save your un-committed changes in a "stash"
git checkout <branch> # to change to correct branch
git stash list # to list stashes
git stash apply stash@{12} # to apply some stash to current branch (in this case its stash `12`)
git stash drop stash@{0} # to remove from stash list
git stash pop stash@{1} # to apply selected stash and drop it from stash list
Alternative workaround:
- Make a commit with those desired changes on current “wrong” branch
- Checkout to the branch you want those changes to be on.
- From that branch
git cherry-pick 23h123kjb
(replace23h123kjb
with the hash found in the Git log specific to the commit you want to bring in)
References
- https://stackoverflow.com/questions/3689838/whats-the-difference-between-head-working-tree-and-index-in-git
- https://dzone.com/articles/beyond-beginning-git-working-tree-index-and-head
- https://stackoverflow.com/questions/37417792/apply-stash-to-different-branch/41978867
Git Working Tree, Index, and HEAD
The “working tree” refers to the directory (and its files and subdirectories) on your file system that is associated with a repository.
The “index” refers to where you place files that you want to commit to the git repository. The index itself is not the git repository, instead it can be seen as a staging ground for files that you want to commit. Before you can run a git commit, you need to first place the files in the git index by using git add
. You can also use the git status
command which will return all the files in your working directory which have been added to the git index.
HEAD
is a pointer to the branch or commit that you last checked out and which will be the parent of a new commit if you make it. For instance, if you’re on the master
branch, then HEAD
will point to master, and when you commit, that new commit will be a descendent of the revision that master pointed to, and master will be updated to point to the new commit. If the branch commit history is a linked list, then HEAD
would be the head of the linked list (where the head of the linked list is the latest commit).
Reverting Changes
git reset [--soft | --mixed [-N] | --hard | --merge | --keep]
soft
reset
When using git reset --soft HEAD~1
you will remove the last commit from the current branch, but the file changes will stay in your working tree. Also the changes will stay on your index, so following with a git commit
will create a commit with the exact same changes as the commit you “removed” before.
mixed
reset
This is the default mode and quite similar to soft. When “removing” a commit with git reset HEAD~1
you will still keep the changes in your working tree but not on the index; so if you want to “redo” the commit, you will have to add the changes (git add
) before commiting.
hard
reset
When using git reset --hard HEAD~1
you will lose all uncommited changes in addition to the changes introduced in the last commit. The changes won’t stay in your working tree so doing a git status command will tell you that you don’t have any changes in your repository.
References
- https://stackoverflow.com/questions/24568936/what-is-difference-between-git-reset-hard-head1-and-git-reset-soft-head
Merging
To merge a branch foo
into bar
:
git checkout bar
git merge foo
Creating a repository
origin
: when you clone a repository for the first time origin
is a default alias given to the original remote repository url that you clone, from where you want to push
and pull
changes. By saying git push origin <branch_name>
, you are saying to push to the original repository.
master
: this is the name of the default branch that Git creates for you when first create a repository. In most cases, master
means “the main branch”. It’s the branch that represents production code, and that all other branches come from and generally eventually rejoin.
git init
: creates an empty Git repository or re-initialize an existing one (basically a .git directory with subdirectories forobjects
,refs/heads
,refs/tags
, andtemplate
files. An initialHEAD
file that references theHEAD
of themaster
branch is also created)git add .
: adds all file contents to the “index” (the index holds a snapshot of the content of the working tree, and it is this snapshot that is taken as the contents of the next commit)git commit -m "first commit"
: create a new commit containing the current contents of the index and the given log message describing the changes. The new commit is a direct child ofHEAD
, usually the tip of the current branch, and the branch is updated to point to itgit remote add origin https://github.com/gutucristian/probable-robot.git
: creates a new remote calledorigin
located athttps://github.com/gutucristian/probable-robot.git
. Once you do this, in yourpush
andpull
commands, you can useorigin
instead of typing out the whole URLgit push -u origin master
: sets localmaster
branch to “track”origin
and pushesmaster
’s working tree to remote defined byorigin
. (equivalent command:git push --set-upstream origin master
)
Tracking branches are local branches that have a direct relationship to a remote branch. If you’re on a tracking branch and type git push, Git automatically knows which server and branch to push to. Also, running git pull while on one of these branches fetches all the remote references and then automatically merges in the corresponding local branch.
References
- https://stackoverflow.com/questions/4693588/what-is-a-tracking-branch
Miscellaneous
To modify or “ammend” the latest commit message
git commit --amend -m "new commit message"
Git bisect
Uses a binary search algorithm to find which commit in your project’s history introduced a bug.
You use it by first telling it a “bad” commit that is known to contain the bug, and a “good” commit that is known to be before the bug was introduced. Then git bisect
picks a commit between those two endpoints and asks you whether the selected commit is “good” or “bad”. It continues narrowing down the range until it finds the exact commit that introduced the change.
If the search range is of N
commits, we should expect to test 1 + log2(N)
commits with git bisect
instead of roughly N / 2
commits with a linear search.
References
- https://stackoverflow.com/questions/4713088/how-to-use-git-bisect