Git Notes
Compiled by Jeremy Kelly
www.anthemion.org
Printed UNKNOWN
These are my Git notes, covering basic features of Git 2.0. If you find a mistake, please let me know.
This page includes a two-column print style. For best results, print in landscape, apply narrow margins, change the Scale setting in your browser’s print options to 70%, and enable background graphics. Firefox and Chrome each have their own set of printing bugs, but one of them usually works.
Contents
These are largely complete, but there is more to be written about merging, rebasing, and log options. Some day I will also add a quick reference for commonly-used actions. Check back later!
- Overview
- Commits
- Snapshots
- The index
- Branches
- The HEAD
- Unreferenced commits
- Remote repositories
- Sharing changes
- Configuration
- git config
- Basic setup
- Ignore files
- Custom commands
- Creating repositories
- git init
- git clone
- Staging changes
- git status
- git add
- git rm
- git mv
- Retaining file history
- Unstaging files
- Committing changes
- Branching
- git checkout
- Checking out specific files
- git branch
- Editing the history
- git reset
- git revert
- Sharing work
- git fetch
- git pull
- git push
- Miscellanea
- File globs
- Sources
Overview
Commits
A Git repository stores project history as a series of commits. Each commit contains:
- A snapshot that gives the state of the working folder at the time of the commit;
- The author of the changes, and the author date, which tells when the changes were first committed or added to a patch;
- The committer of the changes, and the commit date, which tells when the commit was last applied, rebased, or otherwise modified;
- A commit message that describes the changes;
- References to a number of parent commits from which the new snapshot is said to derive.
Snapshots
Unlike many version control systems, Git stores each version of a particular file in whole, rather than storing a series of differences. Snapshots are represented by a set of blob and tree files within the .git
folder. Each blob stores the content of one file. Each tree lists the content of one folder, with files being represented by blobs, and subfolders by additional trees:
$ git ls-tree b623a43
040000 tree 579dc5d4713ce8632d8e7c2b335540f263a73ad5 Lib
100644 blob 2445c091a62c88085cf255e3e0c04e0163547050 Main.cpp
100644 blob b50e8a717d291406281093d10999b18d20d0287b Main.h
Every blob or tree has an object ID, a 160-bit SHA-1 hash of the object's content, which determines the object's location within the .git
folder hierarchy. Changing a working file produces a new blob with a new ID. Each tree contains the object IDs of the files and subfolders in one folder, so changing a file also changes the tree's content, and therefore its own object ID. As a result, a change in the lowest levels of the folder hierarchy produces a new series of trees that uniquely identify the new snapshot. IDs are probabilistically unique, so blobs and trees from different snapshots can coexist within the .git
folder, with common elements being shared between them.
Each commit also has an object ID. The full ID is a forty-digit hex number, but commits are commonly referenced by their first seven digits. Git can cryptographically sign a commit with GnuPG to prove that it originated from a particular source.
The index
The index defines the snapshot for the next commit:
$ git ls-files --abbrev --stage
100644 019f287 0 Lib/Rnd.cpp
100644 49aaef6 0 Lib/Rnd.h
100644 2445c09 0 Main.cpp
100644 b50e8a7 0 Main.h
Git also uses the index to detect changes in the working tree. Files in the index are said to be tracked. Though it resembles a tree, the index lists every file in the folder hierarchy, while only implicitly listing the folders themselves. Because folders are not explicitly tracked, empty folders cannot be committed.
Checking out a commit sets the working folder and the index to match that commit's snapshot. Local changes are then staged with the Git add
, mv
, and rm
commands, which create blobs and trees within the .git
folder, and then update or remove lines within the index. This means that modifications made after a file is staged will not be committed, unless the file is added again.
Branches
Commits can be arranged to form a commit graph that documents the project history:
Each arrow points from a child commit to one of its ancestors. A root commit is one with no parents. Usually, there is only one root, but it is possible for a repository to contain more. A branch is implemented as a reference to a commit, which is then called the branch tip. The branch as a whole contains the tip and all commits that contribute to it. This includes commits made before the branch was created. It also includes commits in parallel histories that were joined by a merge, so branches frequently overlap. By default, the first branch is called master.
The HEAD
The HEAD marks the user's location within the project history; it references a branch or a commit. The HEAD can be moved with the checkout
command, which also updates the working folder. When HEAD is set to a branch, each new commit takes the branch's tip as its parent, then the branch reference is moved to the new commit, so that it becomes the tip. Because HEAD references the branch, it necessarily follows to the new tip. When HEAD is set to a commit, the user is said to be in the detached HEAD state. Because commits are not part of any particular branch, no branch is selected in this case. Additional commits can be added, and these will reference the current commit as their ancestor, but unless a branch is made to reference them, they will eventually be garbage-collected.
Commits before the HEAD are identified by appending a tilde and an optional number. HEAD~n references the nth commit before HEAD. HEAD~ is equivalent to HEAD~1.
Unreferenced commits
Deleting a branch removes the branch reference without deleting any commits, at least not directly. If a series of commits are no longer referenced by any branch, they will be deleted when Git collects garbage. The reset
command can be used to move the branch to a previous commit, and this can also leave commits unreferenced.
Though these commits are no longer part of the commit graph, their existance is recorded in the reflog, which tracks the commits that have recently been referenced by the HEAD:
$ git reflog
80d518e (HEAD) HEAD@{0}: checkout: moving from master to HEAD~3
4c8ff10 (master, dev) HEAD@{1}: merge dev: Fast-forward
a6c290a HEAD@{2}: checkout: moving from dev to master
4c8ff10 (master, dev) HEAD@{3}: commit: Add Clip
2bcbcd9 HEAD@{4}: commit: Update FFT
a6c290a HEAD@{5}: checkout: moving from master to dev
a6c290a HEAD@{6}: commit: Update ZTrans
80d518e (HEAD) HEAD@{7}: commit: Remove Post
de4c279 HEAD@{8}: commit: Add Auto
As long as the commits are not garbage-collected, they can be retrieved with the reset
command.
Remote repositories
Repositories are often cloned from other other locations, producing local copies that can be modified independently. Cloning creates a reference called a remote that links to the original repository, and other remotes can be added later. Adding a remote also adds remote-tracking branches to the local repository, one for each branch in the remote. By default, the first remote is named origin, so the main branch in the first repository typically produces a remote-tracking branch called origin/master:
Remote-tracking branches show the state of the remote branches when the remote was last accessed. Most local changes do not affect remote-tracking branches. Instead, they move automatically when Git fetches from the remote:
This allows the local history to diverge without losing track of the remote state. Also, if the user checks out a branch that does not exist locally, and if its name matches that of a remote-tracking branch, Git will set configuration values that associate the new branch with the upstream branch on the remote. The new branch will start at the remote-tracking position. When the new branch is used to push or pull changes, Git will target the upstream branch automatically.
Note that the phrase tracking branch may be used in different ways. Some authors use it to reference the new branch. By contrast, the Git man pages rarely use the phrase without qualifying it, and when they do, they use it to reference the remote-tracking branch, not the new branch.
Sharing changes
Fetching updates the remote-tracking branches, and downloads the objects needed to complete the new history. Pulling causes a fetch to be performed, then it merges the relevant remote-tracking branch into the current branch.
When merging, if only one branch has changed, Git performs a fast-forward merge that simply adds the new commits, and advances the branch to the new tip. If both branches have changed, merging produces a merge commit. Git creates new, merged files where necessary, and a new snapshot that represents the project in its merged state. This commit claims both branch tips as its parents.
Pushing uploads new objects and merges the current branch into the remote, but only if a fast-forward merge can be performed. If it can't, the user must pull before pushing. After merging the remote changes, the user can push to produce a fast-forward merge.
Configuration
git config
Git settings can be changed with the config
command:
git config setting [value]
If setting and value are specified, config
updates that setting. If value is omitted, config
prints the current value of setting. If setting does not exist, a blank line is displayed.
config
supports these options, among others:
-
--local
- Applies the command to the repository settings file. Local settings override global and system settings.
-
--global
- Applies the command to the user settings file. Global settings override system settings.
-
--system
- Applies the command to the system settings file.
-
-e
-
--edit
- Launches an editor to edit the specified settings file, or the local file if no scope is specified.
-
-l
-
--list
- Lists the settings in the specified file, or all settings in all files, if no scope is specified.
-
--unset
- Removes a setting.
Local settings are stored in .git/config
. Other configuration files vary by system.
Other config
options allow setting names to be matched with regular expressions. It is also possible to associate multiple values with a single setting, even in the same file.
Basic setup
After installing Git, the user should store their name and e-mail in the settings. These values will be attached to commits:
git config --global user.name "Jane Smith"
git config --global user.email jane@example.com
By default, Git uses vi to accept certain input from the user. To replace vi with Windows Notepad:
git config --global core.editor notepad
Other editors can be used, but they sometimes require additional configuration.
Git can also be made to abbreviate commit IDs in the log, where they would otherwise be printed in full:
git config --global log.abbrevCommit on
Ignore files
Git can be made to ignore certain files by adding names and patterns to one or more ignore files:
-
Adding a
.gitignore
file to any repository folder causes the rules in that file to be applied to the folder and all the folders beneath it..gitignore
files in subfolders override those in parent folders.By default,
.gitignore
is considered to be a working file, so it will be added to the repository and shared with other users. An ignore file can itself be ignored by adding its name to its content.When creating a file, Windows Explorer requires a name before the extension. To specify a name like
.gitignore
, add a period before and after the file extension. Windows will discard the trailing period. -
Rules can also be specified in
.git/info/exclude
. This file is not shared with other repository users. -
A custom ignore file can be specified by assigning its name to the
core.excludesfile
setting:git config --global core.excludesfile ~/GitIgnore.txt
Ignore file comments begin with a pound sign. Matches are specified with glob patterns:
# Ignore files produced by the CGV process:
exec-cgv*.b??
Patterns that end with a slash match folders only; others match both folders and files. The 'root' folder for a particular glob is the folder that contains the ignore file, if that file is in the working tree. If the file is outside the tree, as .git/info/exclude
is, the 'root' is the repository folder.
Prefixing a pattern with an exclamation point causes matching files to be included, even if they were ignored by a preceding rule, so long as the preceding rule does not cause any parent folder to be excluded. Re-included files are ignored again if a succeeding rule excludes them.
Finally, only untracked files are ignored. If a file is ignored after being staged or committed, it will continue to be tracked.
Custom commands
Within each settings file, the alias
section stores command aliases. To create an alias, assign a command string to alias.cmd
:
git config --global alias.logs "log -n 16 --pretty=oneline"
Note that git
is not included in the string. Invoke cmd as if it were a Git command:
$ git logs
822ea8f (HEAD -> master) Add window manager
a7d1a7a Add Rnd library
b623a43 Create repository
Begin the command string with an exclamation point to have it executed in the shell.
It is also possible to define a new command by giving a script or other executable the name git-cmd
, and then adding it to the git-core
folder or the user's path. Like an alias, the command can then be invoked with git cmd
.
Creating repositories
git init
New repositories are created with the init
command:
git init [folder]
If folder is specified, that folder will be created, if necessary, and the repository will be initialized within it. If it is not specified, the repository will be added to the current folder. The folder need not be empty when the repository is created, and running init
a second time will not damage an existing repository.
init
supports these options, among others:
-
--bare
-
Normally,
init
creates a.git
subfolder to store blobs, tree files, and other Git data. This option places Git files directly in the target folder, leaving no room for project files. This bare repository has no index, and cannot be used to check out. This is appropriate for a central repository that is meant to share work without itself being used for development. Bare repository folders are often given names that end with.git
. -
--shared
-
Ordinarily, files in the
.git
folder are writable only for the owner. This option causes the files to be writable for all users in the owner's group, and it also sets thereceive.denyNonFastForwards
flag, which prevents users from pushing any change that cannot be applied with a fast-forward merge. The option also supports variations that allow more specific control over permissions.
git clone
The clone
command copies the content of a remote repository:
git clone source [folder]
It also sets the source repository as the remote origin, and creates remote-tracking branches for each branch in that repository. Then it checks out the HEAD branch.
source can specify the remote with a file path or a URL. Git can access the remote with SSH, HTTP/HTTPS, or its own GIT protocal. FTP/FTPS access is now deprecated.
If folder is specified, the command creates the folder, if necessary, and places the repository within it. If it is not specified, clone
chooses the folder name itself.
clone
supports these options, among others:
-
-o name
-
--origin name
- Uses name for the remote, rather than the default, origin.
-
-b name
-
--branch name
- Checks out branch or tag name after cloning, instead of the HEAD branch.
-
-n
-
--no-checkout
- No branch is checked out after cloning.
-
--bare
-
Places Git files directly in the target folder, leaving no room for project files, like the corresponding option in
git init
.
Staging changes
git status
The current commit represents the state of the project at a particular time. The index shows the content that will be stored if a commit is made. The working folder contains the project as it is now, on the local machine. The status
command facilitates staging by showing the differences between these sets:
git status
Differences between the commit and the index are produced by changes that have been staged. These are listed under 'Changes to be committed':
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: Bl.cpp
modified: Bl.h
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: FFT.h
modified: Bl.h
Untracked files:
(use "git add <file>..." to include in what will be committed)
Auto.h
Differences between the index and the working folder are produced by changes that have not been staged. If a given file is tracked, it will be listed under 'Changes not staged for commit'. If a file has been changed, added, and then changed again, it will be listed under 'Changes to be committed' and 'Changes not staged for commit'. Files that have never been added will be listed under 'Untracked files'.
By default, status
also shows the selected branch. The command supports these options, among others:
-
--ignored
- Causes ignored files to be listed in a separate section.
-
-s
-
--short
-
Displays information in the 'short' format:
M FFT.h M Lib/Bl.cpp MM Lib/Bl.h ?? Auto.h
Before each file, characters give the index and working folder status, respectively.
git add
New or changed files must be added to the index to be included in the next commit. This is done with the add
command:
git add [files]
add
also creates blobs and new trees. It supports these options, among others:
-
-u
-
--update
- Adds all tracked, changed files to the index, including deleted files. New files are not added.
-
-A
-
--all
- Adds all changed files to the index, including deleted and new files.
-
-f
-
--force
- Adds elements in files that would otherwise be ignored.
-
-p
-
--patch
- Allows the user to stage changes interactively. If files are specified, Git steps through them, asking the user how to stage each particular file. Changes in a single file are grouped into hunks. The user can stage all hunks, or none, or only some of them. If files are not specified, all changed, tracked files are iterated.
git rm
Deleting a file in the shell and then adding it causes it to be removed from the index. Files can be deleted and the index updated in one step with the rm
command:
git rm [files]
Each file is listed as it is removed:
$ git rm Win.*
rm 'Win.cpp'
rm 'Win.h'
The command can be applied to already-deleted files. It does not delete untracked files.
rm
supports these options, among others:
-
-r
- Removes all files from the specified folder, plus all files in contained folders, recursively.
-
--cached
- Removes files from the index without deleting them in the file system.
git mv
Moving or renaming a file in the shell and then adding both the original and the new location causes it to be renamed or moved in the index. This can be done in one step with the mv
command:
git mv old new
Note that reset
will undo the change to the index, but it will not return the file to its original name or location in the file system.
mv
supports this option, among others:
-
-f
-
--force
- Move or rename the file even if there is already a file at the new location.
Retaining file history
Presumably, a file is moved in order to retain its place in the Git history. Git does not record file moves, however; it merely infers them when it displays the history. Unfortunately, some operations can prevent Git from completing that inference:
-
If the file content has not changed,
status
will describe the file as 'renamed' if it is moved withgit mv
, or if it is moved in the shell and added. If the file is then committed, the history will be retained. - If the file has changed significantly, and if it is moved in the shell and then added, Git will treat the moved file as if it were new, and the history will not be retained.
-
If the file has changed, and if it is moved with
git mv
but not added,status
will describe it as 'renamed', yet the file in the new location will also be marked 'modified', and it will be listed under 'Changes not staged for commit'. Committing at this point will cause the move to be recorded in the history, but the changes will not be recorded. Adding the moved file after the first commit, and committing a second time will record the changes and retain the history. -
If the changed file is moved with
git mv
, and if the new location is immediately added,status
will no longer describe the file as 'renamed'. Instead, it will describe the original file as 'deleted', and it will list a 'new' file at the new location. If the file has changed significantly, committing at this point is not likely to conserve the history.
In general, it is safest to store content changes and moves as separate commits.
Unstaging files
Among its other uses, the reset
command can return some or all of the index to its state as of the last checkout:
git reset [files]
If files are specified, only those files are unstaged; otherwise, the entire index is targeted. reset
does not change files in the working folder.
reset
supports this staging-related option, among others:
-
-p
-
--patch
-
Iterates and resets the staged files interactively, like the corresponding option in
git add
.
Neither files nor the --patch
option can be combined with the --soft
, --mixed
, or --hard
options described elsewhere.
Committing changes
The commit
command creates a new commit that matches the content of the index, and then adds it to the current branch:
git commit [files]
The command is typically used without specifying files. If files are specified, they are committed even if they have not been staged, so long as they are tracked.
commit
supports these options, among others:
-
-a
-
--all
- Stages all modified, tracked files before committing.
-
-p
-
--patch
-
Selects and commits files interactively, like the corresponding option in
git add
. -
-m msg
-
--message msg
- Uses msg for the commit message. If this option is not used, Git launches an editor that accepts message input. The commit is processed when the editor closes.
-
-C commit
-
--reuse-message commit
- Reuses the message in commit.
-
--amend
- Causes the new commit to replace the one at the tip of the branch, rather than adding to the branch. As usual, the index matches the last commit immediately after that commit was made, so changes have been staged relative to the commit that will be replaced, not the commit that will precede the replaced commit in the history. If nothing is staged, the new commit will have the same content, with a possibly different message. If no message is specified, the tip message will be displayed in the editor for modification or reuse.
Branching
git checkout
The checkout
command can be used in different ways. Most often, it targets a branch or a commit:
git checkout [target]
This form moves the HEAD to the target, and then updates the index and working folder to match the associated snapshot. If no target is specified, the HEAD is checked out.
If the working folder contains tracked, modified files, and if those files are not tracked in target, or if their content in target differs from their content in the current commit, the command fails, since updating them would lose the changes.
checkout
supports these options, among others:
-
-f
-
--force
- Proceeds with the checkout, even if this causes changes in the working folder to be lost.
-
-m
-
--merge
-
Proceeds with the checkout, even if changes in the working folder conflict with target. For every file that does conflict, a three-way merge will be performed, with conflicts being marked in the file. The merge is completed by editing each file and then staging it, or by explicitly removing it with
git rm
. -
-b name
- Creates the specified branch at target before checking it out. The command fails if the branch already exists.
-
-B name
- Creates the specified branch at target before checking it out. If the branch already exists, it is moved to the target.
-
-t
-
--track
-
Creates and associates a branch with the remote-tracking branch target. If the
-b
option is specified, that name is applied to the new branch. Otherwise, the name derives from the remote-tracking branch.This is done automatically after attempting to check out a branch that does not exist, if a remote-tracking branch has the same name.
Checking out specific files
checkout
can also be used to update specific files in the working folder:
git checkout [commit] files
If a commit is specified, the files are drawn from that commit, and they are also updated in the index. If a commit is not specified, the files are drawn from the index, and they are updated in the working folder only. If staged changes conflict with the checkout, the command will fail. Unstaged changes are overwritten without warning.
One checkout
option is specific to this form:
-
-p
-
--patch
-
Instead of being overwritten, files with unstaged changes are merged interactively, like the corresponding option in
git add
.
git branch
Branches can be managed with the branch
command. When no branch name is specified, the command lists branches. The current branch is marked with an asterisk:
git branch
In this mode, branch
supports these options, among others:
-
-r
-
--remotes
- Lists only remote-tracking branches.
-
-a
-
--all
- Lists ordinary branches and remote-tracking branches.
-
-v
-
--verbose
- Displays the object ID and commit message for each tip within the branch listing.
-
-vv
- Displays the object ID and commit message for each tip within the branch listing, along with the name of the upstream branch, if any.
-
--contains [commit]
- Lists branches that count commit among their ancestors. If no commit is specified, branches that descend from the HEAD are listed.
-
--no-contains [commit]
- Lists branches that do not count commit among their ancestors. If no commit is specified, branches that do not descend from the HEAD are listed.
-
--merged [commit]
- Lists branches that are ancestors of commit, or of the HEAD, if no commit is specified. These are branches that have been fully merged to the commit.
-
--no-merged [commit]
- Lists branches that are not ancestors of commit, or of the HEAD, if no commit is specified. These are branches that have not been fully merged to the commit.
Branches can also be created, edited, or deleted with this command:
git branch name [position]
Unless an option indicates otherwise, this form creates the specified branch at position, or at the HEAD, if no position is specified. The position can be given as a commit, a tag, or another branch. The new branch is not checked out.
When used this way, branch
supports these options, among others:
-
-m [name] new
-
--move [name] new
- Renames branch name, or the current branch, unless a branch with the new name already exists.
-
-M [name] new
- Renames the branch even if a branch with the new name already exists.
-
-c [name] new
-
--copy [name] new
- Copies branch name, or the current branch, unless a branch with the new name already exists.
-
-C [name] new
- Copies the branch even if a branch with the new name already exists.
-
-d
-
--deletes
- Deletes the branch. The operation fails if the branch has not been fully merged to the current branch, or to the upstream associated with the branch to be deleted. A branch is fully merged if its tip is an ancestor of a second branch tip, so that the second contains every commit in the first.
-
-D
- Deletes the branch even if it has not been fully merged.
-
-f
-
--force
- Moves the specified branch to position, or to HEAD, if no position is specified. Also allows copy, move, and delete operations to proceed even if another branch would be overwritten, or if the target branch is not fully merged.
-
-t
-
--track
- Associates the new branch name with the remote-tracking branch position.
Branches can be created and checked out in one step with the -b
option of the checkout
command:
git checkout -b name
Editing the history
git reset
As already seen, the reset
command can be used to unstage some or all of the staged changes. It can also be used to move the current branch to a particular commit, and, optionally, to update the index, or the index and the working folder:
git reset [commit]
If a commit is specified, the current branch is moved to that commit. If HEAD references that branch, it follows the branch as it moves. If no commit is specified, the command targets HEAD.
reset
supports these modes, which are not compatible with the --patch
option, or with the files argument that is used to unstage specific changes:
-
--soft
- Moves the branch without updating the index. Changes committed or staged since the target commit will remain staged after the reset.
-
--mixed
- Moves the branch and updates the index. This is the default mode. Changes made since the target commit will persist in the working folder, but they will not be staged.
-
--hard
- Moves the branch, updates the index, and changes all working files to match the target commit, including those with unstaged changes. Untracked files are not affected.
-
--merge
- Moves the branch, updates the index, and changes some working files to match the target commit. Files that changed between the current commit and the target commit are updated, as are files with staged changes. Files that did not change, and that now contain unstaged changes are not updated. If any file changed between the commits, and now contains unstaged changes, the operation will fail.
-
--keep
- Moves the branch, updates the index, and changes some working files to match the target commit. Files that changed between the current commit and the target commit are updated. Files that did not change, and that now contain staged or unstaged changes are not updated. If any file changed between the commits, and now contains staged or unstaged changes, the operation will fail.
git revert
The revert
command creates a new commit that undoes the changes in the target commit, and all the commits that follow it:
git revert commit
This reproduces the snapshot of the commit just before the target, but in a different commit, with different metadata. The reverted commits remain in the history. All working files are updated to match the new snapshot, except those with unstaged changes, which are unaffected. The operation fails if any changes have been staged.
revert
supports this option, among others:
-
-n
-
--no-commit
- Updates the working files and the index, but does not add the new commit. All working files are updated to match the new snapshot, except those with changes, whether staged or unstaged. Staged changes do not cause the operation to fail.
Sharing work
git fetch
The fetch
command updates the tags and remote-tracking branches associated with another repository, and downloads the objects needed to complete the updated history:
git fetch [remote] [target]
target can specify a branch or a tag. If neither remote nor target are provided, fetch
targets the remote associated with the upstream that is tied to the current branch, or origin, if there is no upstream.
fetch
supports these options, among others:
-
--all
- Fetches from all remotes.
-
-p
-
--prune
- Also removes remote-tracking branches referencing branches that have been removed from remote.
git pull
The pull
command fetches from another repository and then merges changes to the current branch:
git pull [remote] [target]
As in the fetch
command, target can specify a branch or a tag. If neither remote nor target are provided, the fetch targets the remote of the upstream associated with the current branch, or origin, if there is no upstream.
By default, unless the operation can be completed with a fast-forward merge, pull
adds a merge commit to the history to represent the new, merged state.
pull
supports these options, among others:
-
--all
- Fetches from all remotes before merging.
-
--no-commit
- Fetches and merges as normal, then stages any merged files, but does not create the merge commit. Committing immediately after this operation produces an equivalent merge commit.
-
--squash
- Fetches changes and updates the working files and index as if a merge had been performed, but without recording a merge. Where a merge commit would claim both branch tips as parents, committing immediately after this operation produces an ordinary commit with only the current HEAD as its parent.
-
-r
-
--rebase[=mode]
-
Fetches remote changes and then rebases local changes into one or more commits that follow the pulled commits. The rebase can be controlled by specifying a mode:
-
true
causes local commits to be reimplemented as an equal number of new commits. This is the default mode when the--rebase
option is used. -
interactive
starts an interactive rebase. Local commits are displayed in an editor, allowing each to be picked, squashed, edited, or dropped. -
false
causes changes to be merged rather than rebased. This is useful when a branch has been set to rebase by default.
-
-
--ff-only
- Cancels the pull if it cannot be completed with a fast-forward merge.
-
--no-ff
- Creates a merge commit even if a fast-forward merge could be performed.
-
-e
-
--edit
- Launches an editor, allowing the user to change the message for the merge commit, if any.
git push
The push
command updates remote branches and tags, after uploading the objects necessary to complete the new history:
git push [remote] [branch]
If no remote is specified, Git reads it from the branch.name.pushRemote
, remote.pushDefault
, or branch.name.remote
setting, with name being the current branch. Otherwise it pushes to origin.
If a branch is specified, the command pushes to that branch. If not, Git reads it from the remote.name.push
setting, with name being the current branch. Otherwise, the outcome depends on the value of the push.default
setting:
-
current
pushes from the current branch to the remote branch with the same name. -
upstream
pushes from the current branch to that branch's upstream branch. -
simple
pushes from the current branch to that branch's upstream branch, but only if they share the same name. This is the default in Git 2.0. -
matching
pushes every local branch with a name that matches a branch on the remote. This was the default before Git 2.0. -
nothing
causes the push to fail if no target is set.
The push fails if it cannot be completed with a fast-forward merge. This is generally resolved by pulling and then pushing again.
push
supports these options, among others:
-
--all
- Pushes all branches.
-
--tags
- Pushes all tags, in addition to the specified branch.
-
--delete
- Removes branch from the remote.
-
--prune
- Removes every remote branch that does not have the same name as a local branch.
-
-u
-
--set-upstream
- Creates a remote-tracking branch after pushing branch to the remote, and sets the remote branch as the upstream of branch.
Miscellanea
File globs
Many Git commands allow files to be specified with glob patterns. Within a glob, certain character sequences are expanded to match multiple files:
Sequence | Effect |
? |
Match any one character. |
* |
Match any sequence of zero or more characters. |
[set] |
Match any one character in set. |
[start-end] |
Match any one character between start and end, inclusive. |
Globbing is performed first by the shell, and then by Git. Ordinarily, the shell's globbing leaves no wildcards to be expanded by Git, but a wildcard can be hidden from the shell by escaping it with a backslash:
git add \*.dat
The shell knows only about files in the file system, whereas Git knows those files plus the files in its index. Escaping a wildcard therefore allows different files to be targeted by the glob.
Sources
Git man pages
git-scm.com
Retrieved March 2018
Git Pocket Guide
Richard E. Silverman
2013, O'Reilly Media Inc.
Ry's Git Tutorial
Ryan Hodson
2014, RyPress
Pro Git
Scott Chacon and Ben Straub
2014, Apress Media LLC
Working with dates in Git
alexpeattie.com
Retrieved March 2018
Stack Overflow
git ignore exception not working as desired
Retrieved February 2020