Getting started with Git
Learn how to get started with Git with this easy tutorial
You liked this tutorial and want to go even further with Git? Here some some books we recommend you to read. They are great additions to what we covered in this tutorial.
New Git commands used in this tutorial
Get and set repository or global options.
git config [<file-option>] [type] [-z|--null] name [value [value_regex]] git config [<file-option>] [type] --add name value git config [<file-option>] [type] --replace-all name value [value_regex] git config [<file-option>] [type] [-z|--null] --get name [value_regex] git config [<file-option>] [type] [-z|--null] --get-all name [value_regex] git config [<file-option>] [type] [-z|--null] --get-regexp name_regex [value_regex] git config [<file-option>] [type] [-z|--null] --get-urlmatch name URL git config [<file-option>] --unset name [value_regex] git config [<file-option>] --unset-all name [value_regex] git config [<file-option>] --rename-section old_name new_name git config [<file-option>] --remove-section name git config [<file-option>] [-z|--null] -l | --list git config [<file-option>] --get-color name [default] git config [<file-option>] --get-colorbool name [stdout-is-tty] git config [<file-option>] -e | --edit
You can query/set/replace/unset options with this command. The name is actually the section and the
key separated by a dot, and the value will be escaped.
Multiple lines can be added to an option by using the --add option. If you want to update or unset an option which can occur on multiple lines, a POSIX regexp value_regex needs to be given. Only the existing values that match the regexp are updated or unset. If you want to handle the lines that do not match the regex, just prepend a single exclamation mark in front (see also the section called "EXAMPLES").
The type specifier can be either --int or --bool, to make git config ensure that the variable(s) are of the given type and convert the value to the canonical form (simple decimal number for int, a "true" or "false" string for bool), or --path, which does some path expansion (see --path below). If no type specifier is passed, no checks or transformations are performed on the value.
When reading, the values are read from the system, global and repository local configuration files by default, and options --system, --global, --local and --file <filename> can be used to tell the command to read from only that location (see the section called "FILES").
When writing, the new value is written to the repository local configuration file by default, and options --system, --global, --file <filename> can be used to tell the command to write to that location (you can say --local but that is the default).
This command will fail with non-zero status upon error. Some exit codes are:
- The config file is invalid (ret=3),
- can not write to the config file (ret=4),
- no section or name was provided (ret=2),
- the section or key is invalid (ret=1),
- you try to unset an option which does not exist (ret=5),
- you try to unset/set an option for which multiple lines match (ret=5), or
- you try to use an invalid regexp (ret=6).
--replace-all Default behavior is to replace at most one line. This replaces all lines matching the key (and optionally the value_regex). --add Adds a new line to the option without altering any existing values. This is the same as providing ^$ as the value_regex in --replace-all. --get Get the value for a given key (optionally filtered by a regex matching the value). Returns error code 1 if the key was not found and the last value if multiple key values were found. --get-all Like get, but does not fail if the number of values for the key is not exactly one. --get-regexp Like --get-all, but interprets the name as a regular expression and writes out the key names. Regular expression matching is currently case-sensitive and done against a canonicalized version of the key in which section and variable names are lowercased, but subsection names are not. --get-urlmatch name URL When given a two-part name section.key, the value for section.<url>.key whose <url> part matches the best to the given URL is returned (if no such key exists, the value for section.key is used as a fallback). When given just the section as name, do so for all the keys in the section and list them. --global For writing options: write to global ~/.gitconfig file rather than the repository .git/config, write to $XDG_CONFIG_HOME/git/config file if this file exists and the ~/.gitconfig file doesn't. For reading options: read only from global ~/.gitconfig and from $XDG_CONFIG_HOME/git/config rather than from all available files. See also the section called "FILES". --system For writing options: write to system-wide $(prefix)/etc/gitconfig rather than the repository .git/config. For reading options: read only from system-wide $(prefix)/etc/gitconfig rather than from all available files. See also the section called "FILES". --local For writing options: write to the repository .git/config file. This is the default behavior. For reading options: read only from the repository .git/config rather than from all available files. See also the section called "FILES". -f config-file, --file config-file Use the given config file instead of the one specified by GIT_CONFIG. --blob blob Similar to --file but use the given blob instead of a file. E.g. you can use master:.gitmodules to read values from the file .gitmodules in the master branch. See "SPECIFYING REVISIONS" section in gitrevisions(7) for a more complete list of ways to spell blob names. --remove-section Remove the given section from the configuration file. --rename-section Rename the given section to a new name. --unset Remove the line matching the key from config file. --unset-all Remove all lines matching the key from config file. -l, --list List all variables set in config file. --bool git config will ensure that the output is "true" or "false" --int git config will ensure that the output is a simple decimal number. An optional value suffix of k, m, or g in the config file will cause the value to be multiplied by 1024, 1048576, or 1073741824 prior to output. --bool-or-int git config will ensure that the output matches the format of either --bool or --int, as described above. --path git-config will expand leading ~ to the value of $HOME, and ~user to the home directory for the specified user. This option has no effect when setting the value (but you can use git config bla ~/ from the command line to let your shell do the expansion). -z, --null For all options that output values and/or keys, always end values with the null character (instead of a newline). Use newline instead as a delimiter between key and value. This allows for secure parsing of the output without getting confused e.g. by values that contain line breaks. --get-colorbool name [stdout-is-tty] Find the color setting for name (e.g. color.diff) and output "true" or "false". stdout-is-tty should be either "true" or "false", and is taken into account when configuration says "auto". If stdout-is-tty is missing, then checks the standard output of the command itself, and exits with status 0 if color is to be used, or exits with status 1 otherwise. When the color setting for name is undefined, the command uses color.ui as fallback. --get-color name [default] Find the color configured for name (e.g. color.diff.new) and output it as the ANSI color escape sequence to the standard output. The optional default parameter is used instead, if there is no color configured for name. -e, --edit Opens an editor to modify the specified config file; either --system, --global, or repository (default). --[no-]includes Respect include.* directives in config files when looking up values. Defaults to on.
Create an empty Git repository or reinitialize an existing one.
git init [-q | --quiet] [--bare] [--template=<template_directory>] [--separate-git-dir <git dir>] [--shared[=<permissions>]] [directory]
This command creates an empty Git repository - basically a .git directory with subdirectories
for objects, refs/heads, refs/tags, and template files. An initial HEAD file that references
the HEAD of the master branch is also created.
If the $GIT_DIR environment variable is set then it specifies a path to use instead of ./.git for the base of the repository.
If the object storage directory is specified via the $GIT_OBJECT_DIRECTORY environment variable then the sha1 directories are created underneath - otherwise the default $GIT_DIR/objects directory is used.
Running git init in an existing repository is safe. It will not overwrite things that are already there. The primary reason for rerunning git init is to pick up newly added templates (or to move the repository to another place if --separate-git-dir is given).
-q, --quiet Only print error and warning messages; all other output will be suppressed. --bare Create a bare repository. If GIT_DIR environment is not set, it is set to the current working directory. --template=<template_directory> Specify the directory from which templates will be used. (See the "TEMPLATE DIRECTORY" section below.) --separate-git-dir=<git dir> Instead of initializing the repository as a directory to either $GIT_DIR or ./.git/, create a text file there containing the path to the actual repository. This file acts as filesystem-agnostic Git symbolic link to the repository. If this is reinitialization, the repository will be moved to the specified path. --shared[=(false|true|umask|group|all|world|everybody|0xxx)] Specify that the Git repository is to be shared amongst several users. This allows users belonging to the same group to push into that repository. When specified, the config variable "core.sharedRepository" is set so that files and directories under $GIT_DIR are created with the requested permissions. When not specified, Git will use permissions reported by umask(2). The option can have the following values, defaulting to group if no value is given: umask (or false) Use permissions reported by umask(2). The default, when --shared is not specified. group (or true) Make the repository group-writable, (and g+sx, since the git group may be not the primary group of all users). This is used to loosen the permissions of an otherwise safe umask(2) value. Note that the umask still applies to the other permission bits (e.g. if umask is 0022, using group will not remove read privileges from other (non-group) users). See 0xxx for how to exactly specify the repository permissions. all (or world or everybody) Same as group, but make the repository readable by all users. 0xxx 0xxx is an octal number and each file will have mode 0xxx. 0xxx will override users' umask(2) value (and not only loosen permissions as group and all does). 0640 will create a repository which is group-readable, but not group-writable or accessible to others. 0660 will create a repo that is readable and writable to the current user and group, but inaccessible to others. By default, the configuration flag receive.denyNonFastForwards is enabled in shared repositories, so that you cannot force a non fast-forwarding push into it. If you provide a directory, the command is run inside it. If this directory does not exist, it will be created.
Show the working tree status.
git status [<options>...] [--] [<pathspec>...]
Displays paths that have differences between the index file and the current HEAD commit, paths that have differences between the working tree and the index file, and paths in the working tree that are not tracked by Git (and are not ignored by gitignore(5)). The first are what you would commit by running git commit; the second and third are what you could commit by running git add before running git commit.
-s, --short Give the output in the short-format. -b, --branch Show the branch and tracking info even in short-format. --porcelain Give the output in an easy-to-parse format for scripts. This is similar to the short output, but will remain stable across Git versions and regardless of user configuration. See below for details. --long Give the output in the long-format. This is the default. -u[<mode>], --untracked-files[=<mode>] Show untracked files. The mode parameter is optional (defaults to all), and is used to specify the handling of untracked files. The possible options are: o no - Show no untracked files. o normal - Shows untracked files and directories. o all - Also shows individual files in untracked directories. When -u option is not used, untracked files and directories are shown (i.e. the same as specifying normal), to help you avoid forgetting to add newly created files. Because it takes extra work to find untracked files in the filesystem, this mode may take some time in a large working tree. You can use no to have git status return more quickly without showing untracked files. The default can be changed using the status.showUntrackedFiles configuration variable documented in git- config(1). --ignore-submodules[=<when>] Ignore changes to submodules when looking for changes. <when> can be either "none", "untracked", "dirty" or "all", which is the default. Using "none" will consider the submodule modified when it either contains untracked or modified files or its HEAD differs from the commit recorded in the superproject and can be used to override any settings of the ignore option in git-config(1) or gitmodules(5). When "untracked" is used submodules are not considered dirty when they only contain untracked content (but they are still scanned for modified content). Using "dirty" ignores all changes to the work tree of submodules, only changes to the commits stored in the superproject are shown (this was the behavior before 1.7.0). Using "all" hides all changes to submodules (and suppresses the output of submodule summaries when the config option status.submodulesummary is set). --ignored Show ignored files as well. -z Terminate entries with NUL, instead of LF. This implies the --porcelain output format if no other format is given. --column[=<options>], --no-column Display untracked files in columns. See configuration variable column.status for option syntax.--column and --no-column without options are equivalent to always and never respectively.
Add file contents to the index.
git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--] [<pathspec>...]
This command updates the index using the current content found in the working tree, to prepare the content staged
for the next commit. It typically adds the current content of existing paths as a whole, but with some options it
can also be used to add content with only part of the changes made to the working tree files applied, or remove
paths that do not exist in the working tree anymore.
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 directory, and before running the commit command, you must use the add command to add any new or modified files to the index.
This command can be performed multiple times before a commit. It only adds the content of the specified file(s) at the time the add command is run; if you want subsequent changes included in the next commit, then you must run git add again to add the new content to the index.
The git status command can be used to obtain a summary of which files have changes that are staged for the next commit.
The git add command will not add ignored files by default. If any ignored files were explicitly specified on the command line, git add will fail with a list of ignored files. Ignored files reached by directory recursion or filename globbing performed by Git (quote your globs before the shell) will be silently ignored. The git add command can be used to add ignored files with the -f (force) option.
Please see git-commit(1) for alternative ways to add content to a commit.
<pathspec>... Files to add content from. Fileglobs (e.g. *.c) can be given to add all matching files. Also a leading directory name (e.g. dir to add dir/file1 and dir/file2) can be given to update the index to match the current state of the directory as a whole (e.g. specifying dir will record not just a file dir/file1 modified in the working tree, a file dir/file2 added to the working tree, but also a file dir/file3 removed from the working tree. Note that older versions of Git used to ignore removed files; use --no-all option if you want to add modified or new files but ignore removed ones. -n, --dry-run Don't actually add the file(s), just show if they exist and/or will be ignored. -v, --verbose Be verbose. -f, --force Allow adding otherwise ignored files. -i, --interactive Add modified contents in the working tree interactively to the index. Optional path arguments may be supplied to limit operation to a subset of the working tree. See "Interactive mode" for details. -p, --patch Interactively choose hunks of patch between the index and the work tree and add them to the index. This gives the user a chance to review the difference before adding modified contents to the index. This effectively runs add --interactive, but bypasses the initial command menu and directly jumps to the patch subcommand. See "Interactive mode" for details. -e, --edit Open the diff vs. the index in an editor and let the user edit it. After the editor was closed, adjust the hunk headers and apply the patch to the index. The intent of this option is to pick and choose lines of the patch to apply, or even to modify the contents of lines to be staged. This can be quicker and more flexible than using the interactive hunk selector. However, it is easy to confuse oneself and create a patch that does not apply to the index. See EDITING PATCHES below. -u, --update Update the index just where it already has an entry matching <pathspec>. This removes as well as modifies index entries to match the working tree, but adds no new files. If no <pathspec> is given when -u option is used, all tracked files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories). -A, --all, --no-ignore-removal Update the index not only where the working tree has a file matching <pathspec> but also where the index already has an entry. This adds, modifies, and removes index entries to match the working tree. If no <pathspec> is given when -A option is used, all files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories). --no-all, --ignore-removal Update the index by adding new files that are unknown to the index and files modified in the working tree, but ignore files that have been removed from the working tree. This option is a no-op when no <pathspec> is used. This option is primarily to help users who are used to older versions of Git, whose "git add <pathspec>..." was a synonym for "git add --no-all <pathspec>...", i.e. ignored removed files. -N, --intent-to-add Record only the fact that the path will be added later. An entry for the path is placed in the index with no content. This is useful for, among other things, showing the unstaged content of such files with git diff and committing them with git commit -a. --refresh Don't add the file(s), but only refresh their stat() information in the index. --ignore-errors If some files could not be added because of errors indexing them, do not abort the operation, but continue adding the others. The command shall still exit with non-zero status. The configuration variable add.ignoreErrors can be set to true to make this the default behaviour. --ignore-missing This option can only be used together with --dry-run. By using this option the user can check if any of the given files would be ignored, no matter if they are already present in the work tree or not. -- This option can be used to separate command-line options from the list of files, (useful when filenames might be mistaken for command-line options).
Record changes to the repository.
git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend] [--dry-run] [(-c | -C | --fixup | --squash) <commit>] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [-S[<key-id>]] [--] [<file>...]
Stores the current contents of the index in a new commit along with a log message from the user describing the
The content to be added can be specified in several ways:
- by using git add to incrementally "add" changes to the index before using the commit command (Note: even modified files must be "added");
- by using git rm to remove files from the working tree and the index, again before using the commit command;
- by listing files as arguments to the commit command, in which case the commit will ignore changes staged in the index, and instead record the current content of the listed files (which must already be known to Git);
- by using the -a switch with the commit command to automatically "add" changes from all known files (i.e. all files that are already listed in the index) and to automatically "rm" files in the index that have been removed from the working tree, and then perform the actual commit;
- by using the --interactive or --patch switches with the commit command to decide one by one which files or hunks should be part of the commit, before finalizing the operation. See the "Interactive Mode" section of git- add(1) to learn how to operate these modes.
The --dry-run option can be used to obtain a summary of what is included by any of the above for the next commit by giving the same set of parameters (options and paths).
If you make a commit and then find a mistake immediately after that, you can recover from it with git reset.
-a, --all Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected. -p, --patch Use the interactive patch selection interface to chose which changes to commit. See git-add(1) for details. -C <commit>, --reuse-message=<commit> Take an existing commit object, and reuse the log message and the authorship information (including the timestamp) when creating the commit. -c <commit>, --reedit-message=<commit> Like -C, but with -c the editor is invoked, so that the user can further edit the commit message. --fixup=<commit> Construct a commit message for use with rebase --autosquash. The commit message will be the subject line from the specified commit with a prefix of "fixup! ". See git-rebase(1) for details. --squash=<commit> Construct a commit message for use with rebase --autosquash. The commit message subject line is taken from the specified commit with a prefix of "squash! ". Can be used with additional commit message options (-m/-c/-C/-F). See git-rebase(1) for details. --reset-author When used with -C/-c/--amend options, or when committing after a a conflicting cherry-pick, declare that the authorship of the resulting commit now belongs of the committer. This also renews the author timestamp. --short When doing a dry-run, give the output in the short-format. See git-status(1) for details. Implies --dry-run. --branch Show the branch and tracking info even in short-format. --porcelain When doing a dry-run, give the output in a porcelain-ready format. See git-status(1) for details. Implies --dry-run. --long When doing a dry-run, give the output in a the long-format. Implies --dry-run. -z, --null When showing short or porcelain status output, terminate entries in the status output with NUL, instead of LF. If no format is given, implies the --porcelain output format. -F <file>, --file=<file> Take the commit message from the given file. Use - to read the message from the standard input. --author=<author> Override the commit author. Specify an explicit author using the standard A U Thor <[email protected]> format. Otherwise <author> is assumed to be a pattern and is used to search for an existing commit by that author (i.e. rev-list --all -i --author=<author>); the commit author is then copied from the first such commit found. --date=<date> Override the author date used in the commit. -m <msg>, --message=<msg> Use the given <msg> as the commit message. If multiple -m options are given, their values are concatenated as separate paragraphs. -t <file>, --template=<file> When editing the commit message, start the editor with the contents in the given file. The commit.template configuration variable is often used to give this option implicitly to the command. This mechanism can be used by projects that want to guide participants with some hints on what to write in the message in what order. If the user exits the editor without editing the message, the commit is aborted. This has no effect when a message is given by other means, e.g. with the -m or -F options. -s, --signoff Add Signed-off-by line by the committer at the end of the commit log message. -n, --no-verify This option bypasses the pre-commit and commit-msg hooks. See also githooks(5). --allow-empty Usually recording a commit that has the exact same tree as its sole parent commit is a mistake, and the command prevents you from making such a commit. This option bypasses the safety, and is primarily for use by foreign SCM interface scripts. --allow-empty-message Like --allow-empty this command is primarily for use by foreign SCM interface scripts. It allows you to create a commit with an empty commit message without using plumbing commands like git-commit-tree(1). --cleanup=<mode> This option determines how the supplied commit message should be cleaned up before committing. The <mode> can be strip, whitespace, verbatim, scissors or default. strip Strip leading and trailing empty lines, trailing whitespace, and #commentary and collapse consecutive empty lines. whitespace Same as strip except #commentary is not removed. verbatim Do not change the message at all. scissors Same as whitespace, except that everything from (and including) the line "# ------------------------ >8 ------------------------" is truncated if the message is to be edited. "#" can be customized with core.commentChar. default Same as strip if the message is to be edited. Otherwise whitespace. The default can be changed by the commit.cleanup configuration variable (see git-config(1)). -e, --edit The message taken from file with -F, command line with -m, and from commit object with -C are usually used as the commit log message unmodified. This option lets you further edit the message taken from these sources. --no-edit Use the selected commit message without launching an editor. For example, git commit --amend --no-edit amends a commit without changing its commit message. --amend Replace the tip of the current branch by creating a new commit. The recorded tree is prepared as usual (including the effect of the -i and -o options and explicit pathspec), and the message from the original commit is used as the starting point, instead of an empty message, when no other message is specified from the command line via options such as -m, -F, -c, etc. The new commit has the same parents and author as the current one (the --reset-author option can countermand this). It is a rough equivalent for: $ git reset --soft HEAD^ $ ... do something else to come up with the right tree ... $ git commit -c ORIG_HEAD but can be used to amend a merge commit. You should understand the implications of rewriting history if you amend a commit that has already been published. (See the "RECOVERING FROM UPSTREAM REBASE" section in git-rebase(1).) --no-post-rewrite Bypass the post-rewrite hook. -i, --include Before making a commit out of staged contents so far, stage the contents of paths given on the command line as well. This is usually not what you want unless you are concluding a conflicted merge. -o, --only Make a commit by taking the updated working tree contents of the paths specified on the command line, disregarding any contents that have been staged for other paths. This is the default mode of operation of git commit if any paths are given on the command line, in which case this option can be omitted. If this option is specified together with --amend, then no paths need to be specified, which can be used to amend the last commit without committing changes that have already been staged. -u[<mode>], --untracked-files[=<mode>] Show untracked files. The mode parameter is optional (defaults to all), and is used to specify the handling of untracked files; when -u is not used, the default is normal, i.e. show untracked files and directories. The possible options are: o no - Show no untracked files o normal - Shows untracked files and directories o all - Also shows individual files in untracked directories. The default can be changed using the status.showUntrackedFiles configuration variable documented in git- config(1). -v, --verbose Show unified diff between the HEAD commit and what would be committed at the bottom of the commit message template. Note that this diff output doesn't have its lines prefixed with #. -q, --quiet Suppress commit summary message. --dry-run Do not create a commit, but show a list of paths that are to be committed, paths with local changes that will be left uncommitted and paths that are untracked. --status Include the output of git-status(1) in the commit message template when using an editor to prepare the commit message. Defaults to on, but can be used to override configuration variable commit.status. --no-status Do not include the output of git-status(1) in the commit message template when using an editor to prepare the default commit message. -S[<keyid>], --gpg-sign[=<keyid>] GPG-sign commit. --no-gpg-sign Countermand commit.gpgsign configuration variable that is set to force each and every commit to be signed. -- Do not interpret any more arguments as options. <file>... When files are given on the command line, the command commits the contents of the named files, without recording the changes already staged. The contents of these files are also staged for the next commit on top of what have been staged before.
Manage set of tracked repositories.
git remote [-v | --verbose] git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=<fetch|push>] <name> <url> git remote rename <old> <new> git remote remove <name> git remote set-head <name> (-a | --auto | -d | --delete | <branch>) git remote set-branches [--add] <name> <branch>... git remote set-url [--push] <name> <newurl> [<oldurl>] git remote set-url --add [--push] <name> <newurl> git remote set-url --delete [--push] <name> <url> git remote [-v | --verbose] show [-n] <name>... git remote prune [-n | --dry-run] <name>... git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]
Manage the set of repositories ("remotes") whose branches you track.
-v, --verbose Be a little more verbose and show remote url after name. NOTE: This must be placed between remote and subcommand.
Update remote refs along with associated objects.
git push [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose] [-u | --set-upstream] [--signed] [--force-with-lease[=<refname>[:<expect>]]] [--no-verify] [<repository> [<refspec>...]]
Updates remote refs using local refs, while sending objects necessary to complete the given refs.
You can make interesting things happen to a repository every time you push into it, by setting up hooks there. See documentation for git-receive-pack(1).
When the command line does not specify where to push with the <repository> argument, branch.*.remote configuration for the current branch is consulted to determine where to push. If the configuration is missing, it defaults to origin.
When the command line does not specify what to push with <refspec>... arguments or --all, --mirror, --tags options, the command finds the default <refspec> by consulting remote.*.push configuration, and if it is not found, honors push.default configuration to decide what to push (See git-config(1) for the meaning of push.default).
<repository> The "remote" repository that is destination of a push operation. This parameter can be either a URL (see the section GIT URLS below) or the name of a remote (see the section REMOTES below). <refspec>... Specify what destination ref to update with what source object. The format of a <refspec> parameter is an optional plus +, followed by the source object <src>, followed by a colon :, followed by the destination ref <dst>. The <src> is often the name of the branch you would want to push, but it can be any arbitrary "SHA-1 expression", such as master~4 or HEAD (see gitrevisions(7)). The <dst> tells which ref on the remote side is updated with this push. Arbitrary expressions cannot be used here, an actual ref must be named. If git push [<repository>] without any <refspec> argument is set to update some ref at the destination with <src> with remote.<repository>.push configuration variable, :<dst> part can be omitted---such a push will update a ref that <src> normally updates without any <refspec> on the command line. Otherwise, missing :<dst> means to update the same ref as the <src>. The object referenced by <src> is used to update the <dst> reference on the remote side. By default this is only allowed if <dst> is not a tag (annotated or lightweight), and then only if it can fast-forward <dst>. By having the optional leading +, you can tell Git to update the <dst> ref even if it is not allowed by default (e.g., it is not a fast-forward.) This does not attempt to merge <src> into <dst>. See EXAMPLES below for details. tag <tag> means the same as refs/tags/<tag>:refs/tags/<tag>. Pushing an empty <src> allows you to delete the <dst> ref from the remote repository. The special refspec : (or +: to allow non-fast-forward updates) directs Git to push "matching" branches: for every branch that exists on the local side, the remote side is updated if a branch of the same name already exists on the remote side. --all Push all branches (i.e. refs under refs/heads/); cannot be used with other <refspec>. --prune Remove remote branches that don't have a local counterpart. For example a remote branch tmp will be removed if a local branch with the same name doesn't exist any more. This also respects refspecs, e.g. git push --prune remote refs/heads/*:refs/tmp/* would make sure that remote refs/tmp/foo will be removed if refs/heads/foo doesn't exist. --mirror Instead of naming each ref to push, specifies that all refs under refs/ (which includes but is not limited to refs/heads/, refs/remotes/, and refs/tags/) be mirrored to the remote repository. Newly created local refs will be pushed to the remote end, locally updated refs will be force updated on the remote end, and deleted refs will be removed from the remote end. This is the default if the configuration option remote.<remote>.mirror is set. -n, --dry-run Do everything except actually send the updates. --porcelain Produce machine-readable output. The output status line for each ref will be tab-separated and sent to stdout instead of stderr. The full symbolic names of the refs will be given. --delete All listed refs are deleted from the remote repository. This is the same as prefixing all refs with a colon. --tags All refs under refs/tags are pushed, in addition to refspecs explicitly listed on the command line. --follow-tags Push all the refs that would be pushed without this option, and also push annotated tags in refs/tags that are missing from the remote but are pointing at commit-ish that are reachable from the refs being pushed. --signed GPG-sign the push request to update refs on the receiving side, to allow it to be checked by the hooks and/or be logged. See git-receive-pack(1) for the details on the receiving end. --receive-pack=<git-receive-pack>, --exec=<git-receive-pack> Path to the git-receive-pack program on the remote end. Sometimes useful when pushing to a remote repository over ssh, and you do not have the program in a directory on the default $PATH. --[no-]force-with-lease, --force-with-lease=<refname>, --force-with-lease=<refname>:<expect> Usually, "git push" refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it. This option bypasses the check, but instead requires that the current value of the ref to be the expected value. "git push" fails otherwise. Imagine that you have to rebase what you have already published. You will have to bypass the "must fast-forward" rule in order to replace the history you originally published with the rebased history. If somebody else built on top of your original history while you are rebasing, the tip of the branch at the remote may advance with her commit, and blindly pushing with --force will lose her work. This option allows you to say that you expect the history you are updating is what you rebased and want to replace. If the remote ref still points at the commit you specified, you can be sure that no other people did anything to the ref (it is like taking a "lease" on the ref without explicitly locking it, and you update the ref while making sure that your earlier "lease" is still valid). --force-with-lease alone, without specifying the details, will protect all remote refs that are going to be updated by requiring their current value to be the same as the remote-tracking branch we have for them, unless specified with a --force-with-lease=<refname>:<expect> option that explicitly states what the expected value is. --force-with-lease=<refname>, without specifying the expected value, will protect the named ref (alone), if it is going to be updated, by requiring its current value to be the same as the remote-tracking branch we have for it. --force-with-lease=<refname>:<expect> will protect the named ref (alone), if it is going to be updated, by requiring its current value to be the same as the specified value <expect> (which is allowed to be different from the remote-tracking branch we have for the refname, or we do not even have to have such a remote-tracking branch when this form is used). Note that all forms other than --force-with-lease=<refname>:<expect> that specifies the expected current value of the ref explicitly are still experimental and their semantics may change as we gain experience with this feature. "--no-force-with-lease" will cancel all the previous --force-with-lease on the command line. -f, --force Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it. Also, when --force-with-lease option is used, the command refuses to update a remote ref whose current value does not match what is expected. This flag disables these checks, and can cause the remote repository to lose commits; use it with care. Note that --force applies to all the refs that are pushed, hence using it with push.default set to matching or with multiple push destinations configured with remote.*.push may overwrite refs other than the current branch (including local refs that are strictly behind their remote counterpart). To force a push to only one branch, use a + in front of the refspec to push (e.g git push origin +master to force a push to the master branch). See the <refspec>... section above for details. --repo=<repository> This option is only relevant if no <repository> argument is passed in the invocation. In this case, git push derives the remote name from the current branch: If it tracks a remote branch, then that remote repository is pushed to. Otherwise, the name "origin" is used. For this latter case, this option can be used to override the name "origin". In other words, the difference between these two commands git push public #1 git push --repo=public #2 is that #1 always pushes to "public" whereas #2 pushes to "public" only if the current branch does not track a remote branch. This is useful if you write an alias or script around git push. -u, --set-upstream For every branch that is up to date or successfully pushed, add upstream (tracking) reference, used by argument-less git-pull(1) and other commands. For more information, see branch.<name>.merge in git-config(1). --[no-]thin These options are passed to git-send-pack(1). A thin transfer significantly reduces the amount of sent data when the sender and receiver share many of the same objects in common. The default is --thin. -q, --quiet Suppress all output, including the listing of updated refs, unless an error occurs. Progress is not reported to the standard error stream. -v, --verbose Run verbosely. --progress Progress status is reported on the standard error stream by default when it is attached to a terminal, unless -q is specified. This flag forces progress status even if the standard error stream is not directed to a terminal. --recurse-submodules=check|on-demand Make sure all submodule commits used by the revisions to be pushed are available on a remote-tracking branch. If check is used Git will verify that all submodule commits that changed in the revisions to be pushed are available on at least one remote of the submodule. If any commits are missing the push will be aborted and exit with non-zero status. If on-demand is used all submodules that changed in the revisions to be pushed will be pushed. If on-demand was not able to push all necessary revisions it will also be aborted and exit with non-zero status. --[no-]verify Toggle the pre-push hook (see githooks(5)). The default is --verify, giving the hook a chance to prevent the push. With --no-verify, the hook is bypassed completely.