Difference between revisions of "Git"

From ArchWiki
Jump to: navigation, search
m (Need to use double quote)
(Update list of config file locations)
 
(101 intermediate revisions by 12 users not shown)
Line 1: Line 1:
 
[[Category:Version Control System]]
 
[[Category:Version Control System]]
 +
[[es:Git]]
 
[[ja:Git]]
 
[[ja:Git]]
 
[[zh-hans:Git]]
 
[[zh-hans:Git]]
Line 9: Line 10:
 
{{Related|Concurrent Versions System}}
 
{{Related|Concurrent Versions System}}
 
{{Related articles end}}
 
{{Related articles end}}
{{Quote|I've met people who thought that git is a front-end to GitHub. They were wrong, git is a front-end to the AUR.|Linus Torvalds}}
+
{{Quote|I've met people who thought that git is a front-end to GitHub. They were wrong, git is a front-end to the AUR.|[https://public-inbox.org/git/#didyoureallythinklinuswouldsaythat Linus T.]}}
  
 
[[wikipedia:Git (software)|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain [[AUR]] packages, as well as many other projects, including sources for the Linux kernel.  
 
[[wikipedia:Git (software)|Git]] is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain [[AUR]] packages, as well as many other projects, including sources for the Linux kernel.  
Line 17: Line 18:
 
[[Install]] the {{Pkg|git}} package. For the development version, install the {{AUR|git-git}} package. Check the optional dependencies when using tools such as ''git svn'', ''git gui'' and ''gitk''.
 
[[Install]] the {{Pkg|git}} package. For the development version, install the {{AUR|git-git}} package. Check the optional dependencies when using tools such as ''git svn'', ''git gui'' and ''gitk''.
  
{{Note|To enable spell checking in ''git-gui'', {{Pkg|aspell}} is required, along with the dictionary corresponding to the {{ic|LC_MESSAGES}} [[environment variable]]. See {{Bug|28181}} and the [[aspell]] article.}}
+
=== Graphical front-ends ===
 +
 
 +
See also [https://git-scm.com/download/gui/linux git GUI Clients].
 +
 
 +
* {{App|Giggle|GTK+ frontend for git.|https://wiki.gnome.org/Apps/giggle/|{{Pkg|giggle}}}}
 +
* {{App|Git Cola|Sleek and powerful graphical user interface for Git written in Python.|https://git-cola.github.io/|{{AUR|git-cola}}}}
 +
* {{App|Git Extensions|Graphical user interface for Git that allows you to control Git without using the commandline.|https://gitextensions.github.io/|{{AUR|gitextensions}}}}
 +
* {{App|gitg|GNOME GUI client to view git repositories.|https://wiki.gnome.org/Apps/Gitg|{{Pkg|gitg}}}}
 +
* {{App|git-gui|Tcl/Tk based portable graphical interface to Git.|https://git-scm.com/docs/git-gui|{{Pkg|git}} + {{Pkg|tk}}}}
 +
:{{Note|To enable spell checking in ''git-gui'', {{Pkg|aspell}} is required, along with the dictionary corresponding to the {{ic|LC_MESSAGES}} [[environment variable]]. See {{Bug|28181}} and the [[aspell]] article.}}
 +
* {{App|gitk|Tcl/Tk based Git repository browser.|https://git-scm.com/docs/gitk|{{Pkg|git}} + {{Pkg|tk}}}}
 +
* {{App|QGit|Git GUI viewer to browse revisions history, view patch content and changed files, graphically following different development branches.|https://github.com/tibirna/qgit|{{Pkg|qgit}}}}
 +
* {{App|[[Wikipedia:RabbitVCS|RabbitVCS]]|Set of graphical tools written to provide simple and straightforward access to the version control systems you use.|http://rabbitvcs.org/|{{AUR|rabbitvcs}}}}
 +
* {{App|Tig|ncurses-based text-mode interface for git.|https://jonas.github.io/tig/|{{Pkg|tig}}}}
 +
* {{App|ungit|Brings user friendliness to git without sacrificing the versatility of git.|https://github.com/FredrikNoren/ungit|{{AUR|nodejs-ungit}}}}
  
 
== Configuration ==
 
== Configuration ==
Line 24: Line 39:
  
 
  $ git config --global user.name  "''John Doe''"
 
  $ git config --global user.name  "''John Doe''"
  $ git config --global user.email "''johndoe@foobar.com''"
+
  $ git config --global user.email "''johndoe@example.com''"
 +
 
 +
See [https://git-scm.com/book/en/Getting-Started-First-Time-Git-Setup Getting Started - First-Time Git Setup].
  
 
See [[#Tips and tricks]] for more settings.
 
See [[#Tips and tricks]] for more settings.
Line 30: Line 47:
 
== Usage ==
 
== Usage ==
  
This tutorial teaches how to use Git for basic distributed revision control of a project.
+
A Git repository is contained in a {{ic|.git}} directory, which holds the revision history and other metadata. The directory tracked by the repository, by default the parent directory, is called the working directory. Changes in the working tree need to be staged before they can be recorded (committed) to the repository. Git also lets you restore, previously committed, working tree files.
 
 
Git is a distributed version control system, which means that the entire history of changes to a repository is stored locally, in a directory called {{ic|./.git}} in the project directory. The project files which are visible to the user constitute the ''working tree''. These files can be updated to match revisions stored in {{ic|./.git}} using {{ic|git}} commands (e.g. {{ic|git checkout}}), and new revisions can be created in turn by editing these files and running the appropriate {{ic|git}} commands (e.g. {{ic|git commit}}).
 
 
 
See {{man|7|gitglossary}} for more complete definitions of the terms used in this tutorial.
 
 
 
A typical Git work-flow is:
 
 
 
# Create a new project or clone a remote one.
 
# Create a branch to make changes; then commit those changes.
 
# Consolidate commits for better organization/understanding.
 
# Merge commits back into the main branch.
 
# (Optional) Push changes to a remote server.
 
 
 
=== Local repository ===
 
 
 
==== Staging operations ====
 
 
 
'''Initialize''' a new repository. This creates and initializes {{ic|./.git}}:
 
 
 
$ cd (your project)/
 
$ git init
 
 
 
To record the changes to the repository, they must first be added to the ''index'', or ''staging area'', with an operation often also referred to as ''staging''. When you commit changes using {{ic|git commit}}, it is the contents of the index which are committed to the current branch, not the contents of the working tree.
 
 
 
{{Note|The index is actually a binary file {{ic|.git/index}}, which can be queried with {{ic|git ls-files --stage}}.}}
 
 
 
To '''add files''' to the index from the working tree:
 
 
 
$ git add ''file1'' ''file2''
 
 
 
This records the current state of the files. If the files are subsequently modified, you can run {{ic|git add}} again to "add" the new versions to the index.
 
  
'''Add all''' files:
+
See [https://git-scm.com/book/en/Getting-Started-Git-Basics Getting Started - Git Basics].
  
$ git add .
+
=== Getting a Git repository ===
  
{{Tip|To '''ignore''' some files from, e.g. {{ic|git add .}}, create a {{ic|.gitignore}} file (or files):
+
* Initialize a repository
 +
:{{ic|git init}}, see {{man|1|git-init}}
 +
* Clone an existing repository
 +
:{{ic|git clone ''repository''}}, see {{man|1|git-clone}}
  
{{hc|.gitignore|
+
=== Recording changes ===
# File I'll likely delete
 
test-script
 
  
# Ignore all .html files, except 'important.html'
+
Git projects have a staging area, which is an {{ic|index}} file in your Git directory, that stores the changes that will go into your next commit. To record a modified file you therefore firstly need to add it to the index (stage it). The {{ic|git commit}} command then stores the current index in a new commit.
*.html
 
!important.html
 
  
# Ignore all files recursively in 'DoNotInclude'
+
==== Staging changes ====
DoNotInclude/**
 
}}
 
  
See [http://git-scm.com/docs/gitignore gitignore(5)] for details.
+
* Add working tree changes to the index
}}
+
:{{ic|git add ''pathspec''}}, see {{man|1|git-add}}
 +
* Remove changes from the index
 +
:{{ic|git reset ''pathspec''}}, see {{man|1|git-reset}}
 +
* Show changes to be committed, unstaged changes and untracked files
 +
:{{ic|git status}}, see {{man|1|git-status}}
  
'''Remove''' a file from staging ({{ic|--cached}} preserves the actual file(s)):
+
You can tell Git to ignore certain untracked files using {{ic|.gitignore}} files, see {{man|5|gitignore}}.
  
$ git rm ''(--cached)'' ''file''
+
Git does not track file movement. Move detection during merges is based only on content similarity. The {{ic|git mv}} command is just there for convenience and is equivalent to:
  
'''Remove all''' files:
+
$ mv -i foo bar
 +
$ git reset -- foo
 +
$ git add bar
  
$ git rm --cached -r .
+
==== Committing changes ====
  
Or:
+
The {{ic|git commit}} command records the staged changes to the repository, see {{man|1|git-commit}}.
  
$ git reset HEAD -- .
+
* {{ic|-m}} – supply the commit message as an argument, instead of composing it in your default text editor
 +
* {{ic|-a}} – automatically stage files that have been modified or deleted (does not add untracked files)
 +
* {{ic|--amend}} – redo the last commit, amending the commit message or the committed files
  
Here, {{ic|HEAD}} is a "symbolic reference" to the current revision.
+
{{Tip|Always commit small changes frequently and with meaningful messages.}}
  
'''Rename''' a file:
+
==== Revision selection ====
  
$ git mv ''file1'' ''file2''
+
Git offers multiple ways to specify revisions, see {{man|7|gitrevisions}} and [https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection Revision Selection].
  
{{Note|{{ic|git mv}} is a convenience command, roughly equivalent to {{ic|mv file1 file2}} followed by {{ic|git rm file1}} and {{ic|git add file2}}. Rename detection during merges is based only on content similarity, and ignores the actual commands used to rename files. The broader rationale for this approach, which distinguishes Git from patch-based systems like [[Darcs]], can be found [http://permalink.gmane.org/gmane.comp.version-control.git/217 here].}}
+
Many Git commands take revisions as arguments. A commit can be identified by any of the following:
  
'''List''' files:
+
* SHA-1 hash of the commit (the first 7 digits are usually sufficient to identify it uniquely)
 
 
$ git ls-files
 
 
 
By default this shows files in the staging area ({{ic|--cached}} files).
 
 
 
==== Commit changes ====
 
 
 
Once the content to be recorded is ''staged'', '''commit''' them with:
 
 
 
$ git commit -m "''First commit.''"
 
 
 
The {{ic|-m (''--message)}}'' option is for a short message: if omitted, the preset editor will be spawned to allow entering a longer message.
 
 
 
{{Tip|
 
* Always commit small changes frequently and with meaningful messages.
 
* To '''add''' all the modified files to the index, '''and commit''' them in a single command ({{ic|-a}} stands for {{ic|--all}}):
 
 
 
$ git commit -am "''First commit.''"
 
}}
 
 
 
'''Edit''' the commit message for the last commit. This also amends the commit with any files which have been newly staged:
 
 
 
$ git commit --amend -m "''Message.''"
 
 
 
Many of the commands in this article take commits as arguments. A commit can be identified by any of the following:
 
 
 
* Its 40-digit SHA-1 hash (the first 7 digits are usually sufficient to identify it uniquely)
 
 
* Any commit label such as a branch or tag name
 
* Any commit label such as a branch or tag name
 
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used ''git checkout'' to jump back in history to an old commit)
 
* The label {{ic|HEAD}} always refers to the currently checked-out commit (usually the head of the branch, unless you used ''git checkout'' to jump back in history to an old commit)
 
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.
 
* Any of the above plus {{ic|~}} to refer to previous commits. For example, {{ic|HEAD~}} refers to one commit before {{ic|HEAD}} and {{ic|HEAD~5}} refers to five commits before {{ic|HEAD}}.
  
==== View changes ====
+
==== Viewing changes ====
  
'''Show differences''' between commits:
+
Show differences between commits:
  
 
  $ git diff HEAD HEAD~3
 
  $ git diff HEAD HEAD~3
Line 146: Line 110:
 
  $ git diff
 
  $ git diff
  
'''Get''' a general '''overview''' of the changes:
+
View history of changes (where "''-N''" is the number of latest commits):
 +
 
 +
$ git log -p ''(-N)''
  
$ git status
+
=== Undoing things ===
  
'''View history''' of changes (where "''-N''" is the number of latest commits):
+
* {{ic|git reset}} - reset current HEAD to the specified state, see {{man|1|git-reset}}
  
$ git log -p ''(-N)''
+
* {{ic|git checkout}} - to restore working tree files, see {{man|1|git-checkout}}
  
==== Branch a repository ====
+
=== Branching ===
  
 
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch.
 
Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch.
  
'''Create''' a branch, whose name accurately reflects its purpose:
+
Create a branch, whose name accurately reflects its purpose:
  
 
  $ git branch ''help-section-addition''
 
  $ git branch ''help-section-addition''
  
'''List''' branches:
+
List branches:
  
 
  $ git branch
 
  $ git branch
  
'''Switch''' branches:
+
Switch branches:
  
 
  $ git checkout ''branch''
 
  $ git checkout ''branch''
  
'''Create and switch''':
+
Create and switch:
  
 
  $ git checkout -b ''branch''
 
  $ git checkout -b ''branch''
  
'''Merge''' a branch back to the master branch:
+
Merge a branch back to the master branch:
  
 
  $ git checkout master
 
  $ git checkout master
Line 181: Line 147:
 
The changes will be merged if they do not conflict. Otherwise, Git will print an error message, and annotate files in the working tree to record the conflicts. The annotations can be displayed with {{ic|git diff}}. Conflicts are resolved by editing the files to remove the annotations, and committing the final version. See [[#Dealing with merges]] below.
 
The changes will be merged if they do not conflict. Otherwise, Git will print an error message, and annotate files in the working tree to record the conflicts. The annotations can be displayed with {{ic|git diff}}. Conflicts are resolved by editing the files to remove the annotations, and committing the final version. See [[#Dealing with merges]] below.
  
When done with a branch, '''delete''' it with:
+
When done with a branch, delete it with:
  
 
  $ git branch -d ''branch''
 
  $ git branch -d ''branch''
Line 187: Line 153:
 
=== Collaboration ===
 
=== Collaboration ===
  
==== Adopting a good etiquette ====
+
A typical Git work-flow is:
  
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.
+
# Create a new repository or clone a remote one.
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.
+
# Create a branch to make changes; then commit those changes.
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.
+
# Consolidate commits for better organization/understanding.
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.
+
# Merge commits back into the main branch.
 
+
# (Optional) Push changes to a remote server.
==== Clone a repository ====
 
 
 
To begin contributing to a project, '''clone''' its repository:
 
 
 
$ git clone ''location'' ''folder''
 
 
 
{{ic|''location''}} can be either a path or network address. Also, when cloning is done, the location is recorded so just a {{ic|git pull}} will be needed later.
 
  
 
==== Pull requests ====
 
==== Pull requests ====
Line 206: Line 165:
 
After making and committing some changes, the contributor can ask the original author to merge them. This is called a ''pull request''.
 
After making and committing some changes, the contributor can ask the original author to merge them. This is called a ''pull request''.
  
To '''pull''':
+
To pull:
  
 
  $ git pull ''location'' master
 
  $ git pull ''location'' master
Line 212: Line 171:
 
The ''pull'' command combines both ''fetching'' and ''merging''. If there are conflicts (e.g. the original author made changes in the same time span), then it will be necessary to manually fix them.
 
The ''pull'' command combines both ''fetching'' and ''merging''. If there are conflicts (e.g. the original author made changes in the same time span), then it will be necessary to manually fix them.
  
Alternatively, the original author can '''pick''' the '''changes''' wanting to be incorporated. Using the ''fetch'' option (and ''log'' option with a special {{ic|FETCH_HEAD}} symbol), the contents of the pull request can be viewed before deciding what to do:
+
Alternatively, the original author can pick the changes wanting to be incorporated. Using the ''fetch'' option (and ''log'' option with a special {{ic|FETCH_HEAD}} symbol), the contents of the pull request can be viewed before deciding what to do:
  
 
  $ git fetch ''location'' master
 
  $ git fetch ''location'' master
Line 222: Line 181:
 
Remotes are aliases for tracked remote repositories. A ''label'' is created defining a location. These labels are used to identify frequently accessed repositories.
 
Remotes are aliases for tracked remote repositories. A ''label'' is created defining a location. These labels are used to identify frequently accessed repositories.
  
'''Create''' a remote:
+
Create a remote:
  
 
  $ git remote add ''label'' ''location''
 
  $ git remote add ''label'' ''location''
  
'''Fetch''' a remote:
+
Fetch a remote:
  
 
  $ git fetch ''label''
 
  $ git fetch ''label''
  
'''Show differences''' between master and a remote master:
+
Show differences between master and a remote master:
  
 
  $ git log -p master..''label''/master
 
  $ git log -p master..''label''/master
  
'''View''' remotes for the current repository:
+
View remotes for the current repository:
  
 
  $ git remote -v
 
  $ git remote -v
Line 242: Line 201:
 
==== Push to a repository ====
 
==== Push to a repository ====
  
After being given rights from the original authors, '''push''' changes with:
+
After being given rights from the original authors, push changes with:
  
 
  $ git push ''location'' ''branch''
 
  $ git push ''location'' ''branch''
Line 248: Line 207:
 
When ''git clone'' is performed, it records the original location and gives it a remote name of {{ic|origin}}.
 
When ''git clone'' is performed, it records the original location and gives it a remote name of {{ic|origin}}.
  
So what '''typically''' is done is this:
+
So what ''typically'' is done is this:
  
 
  $ git push origin master
 
  $ git push origin master
Line 257: Line 216:
  
 
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).
 
See [http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts Basic Merge Conflicts] in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the {{ic|--abort}} command (e.g. {{ic|git merge --abort}} or {{ic|git pull --abort}}).
 
==== Send patch to mailing list ====
 
 
If you want to send patches directly to a mailing list, you have to install the following packages: {{Pkg|perl-authen-sasl}}, {{Pkg|perl-net-smtp-ssl}} and {{Pkg|perl-mime-tools}}.
 
 
Make sure you have configured your username and e-mail address, see [[#Configuration]].
 
 
'''Configure''' your '''e-mail''' settings:
 
 
$ git config --global sendemail.smtpserver ''smtp.gmail.com''
 
$ git config --global sendemail.smtpserverport ''587''
 
$ git config --global sendemail.smtpencryption ''tls''
 
$ git config --global sendemail.smtpuser ''foobar@gmail.com''
 
 
Now you should be able to '''send''' the '''patch''' to the mailing list (see also [http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):
 
 
$ git add ''filename''
 
$ git commit -s
 
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1
 
  
 
=== History and versioning ===
 
=== History and versioning ===
Line 283: Line 223:
 
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. The ''checksum'' is the "object name" of a commit object, typically a 40-character SHA-1 hash.
 
{{ic|git log}} will give the history with a commit checksum, author, date, and the short message. The ''checksum'' is the "object name" of a commit object, typically a 40-character SHA-1 hash.
  
For '''history''' with a '''long message''' (where the "''checksum''" can be truncated, as long as it is unique):
+
For history with a long message (where the "''checksum''" can be truncated, as long as it is unique):
  
 
  $ git show (''checksum'')
 
  $ git show (''checksum'')
  
'''Search''' for ''pattern'' in tracked files:
+
Search for ''pattern'' in tracked files:
  
 
  $ git grep ''pattern''
 
  $ git grep ''pattern''
  
'''Search''' in '''{{ic|.c}}''' and '''{{ic|.h}}''' files:
+
Search in {{ic|.c}} and {{ic|.h}} files:
  
 
  $ git grep ''pattern'' -- '*.[ch]'
 
  $ git grep ''pattern'' -- '*.[ch]'
  
==== Versioning for release ====
+
==== Tagging ====
  
'''Tag''' commits for versioning:
+
Tag commits for versioning:
  
 
  $ git tag 2.14 ''checksum''
 
  $ git tag 2.14 ''checksum''
Line 303: Line 243:
 
''Tagging'' is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used, because they get added to the Git database.
 
''Tagging'' is generally done for [https://www.drupal.org/node/1066342 releasing/versioning] but it can be any string. Generally annotated tags are used, because they get added to the Git database.
  
'''Tag''' the '''current''' commit with:
+
Tag the current commit with:
  
 
  $ git tag -a 2.14 -m "Version 2.14"
 
  $ git tag -a 2.14 -m "Version 2.14"
  
'''List''' tags:
+
List tags:
  
 
  $ git tag -l
 
  $ git tag -l
  
'''Delete''' a tag:
+
Delete a tag:
  
 
  $ git tag -d 2.08
 
  $ git tag -d 2.08
  
'''Update remote''' tags:
+
Update remote tags:
  
 
  $ git push --tags
 
  $ git push --tags
Line 321: Line 261:
 
==== Organizing commits ====
 
==== Organizing commits ====
  
Before submitting a pull request it may be desirable to '''consolidate/organize''' the commits. This is done with the ''git rebase'' {{ic|--interactive}} option:
+
Before submitting a pull request it may be desirable to consolidate/organize the commits. This is done with the ''git rebase'' {{ic|--interactive}} option:
  
 
  $ git rebase -i ''checksum''
 
  $ git rebase -i ''checksum''
Line 347: Line 287:
 
=== Using git-config ===
 
=== Using git-config ===
  
Git reads its configuration from a few INI-type configuration files:
+
Git reads its configuration from four INI-type configuration files:
  
* Each repository contains a {{ic|.git/config}} file for specific configuration.
+
* {{ic|/etc/gitconfig}} for system-wide defaults
* Each user has a {{ic|$HOME/.gitconfig}} file for fallback values.
+
* {{ic|~/.gitconfig}} and {{ic|~/.config/git/config}} (since 1.7.12) for user-specific configuration
* {{ic|/etc/gitconfig}} is used for system-wide defaults.
+
* {{ic|.git/config}} for repository-specific configuration
  
 
These files can be edited directly, but the usual method is to use ''git config'', as shown in the examples below.
 
These files can be edited directly, but the usual method is to use ''git config'', as shown in the examples below.
Line 371: Line 311:
 
  $ git config --global diff.tool vimdiff
 
  $ git config --global diff.tool vimdiff
  
See [https://www.kernel.org/pub/software/scm/git/docs/git-config.html git-config(1)] and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.
+
See {{man|1|git-config}} and [http://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration] for more information.
 +
 
 +
=== Adopting a good etiquette ===
 +
 
 +
* When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.
 +
* Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the [[#History and versioning|log]] of the repository.
 +
* When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.
 +
* If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.
  
 
=== Speeding up authentication ===
 
=== Speeding up authentication ===
Line 397: Line 344:
 
=== Git prompt ===
 
=== Git prompt ===
  
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} script in a [[Autostarting#Shells|shell startup file]], then set a custom prompt with the {{ic|%s}} parameter:
+
The Git package comes with a prompt script. To enable it, source the {{ic|/usr/share/git/completion/git-prompt.sh}} and set a custom prompt with the {{ic|%s}} parameter:
  
 
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}
 
* For [[Bash]]: {{ic|1=PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '}}
* For [[zsh]]: {{ic|1=PS1="[%n@%m %c$(__git_ps1 " (%s)")]\$ "}}
+
* For [[zsh]]: {{ic|1=setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '}}
 +
 
 +
To automate this see [[Command-line shell#Configuration files]].
  
 
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:
 
When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:
Line 446: Line 395:
  
 
  $ git remote set-url origin git@''address'':''user''/''repo''.git
 
  $ git remote set-url origin git@''address'':''user''/''repo''.git
 
{{Note|To use pinentry curses for gpg signing make sure to {{ic|1=export GPG_TTY=$(tty)}} (alternatively use pinentry-tty) otherwise the signing step will fail if gpg is currently in a locked state (since it can't prompt for pin)}}
 
  
 
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):
 
Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):
  
  $ git commit -s
+
$ git commit -s
  
 
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):
 
Signed-off-by automatically append to patches (when using {{ic|git format-patch ''commit''}}):
Line 460: Line 407:
  
 
  $ git add -p
 
  $ git add -p
 +
 +
=== Signing commits ===
 +
 +
Git allows commits and tags to be signed using [[GnuPG]], see [https://git-scm.com/book/en/Git-Tools-Signing-Your-Work Signing Your Work].
 +
 +
{{Note|To use {{Pkg|pinentry}} curses for GPG signing make sure to {{ic|1=export GPG_TTY=$(tty)}} (alternatively use pinentry-tty) otherwise the signing step will fail if GPG is currently in a locked state (since it cannot prompt for pin).}}
 +
 +
To configure Git to automatically sign commits:
 +
 +
$ git config --global commit.gpgSign true
  
 
=== Working with a non-master branch ===
 
=== Working with a non-master branch ===
Line 473: Line 430:
 
  $ git pull --all
 
  $ git pull --all
 
  $ git push --all
 
  $ git push --all
 +
 +
=== Directly sending patches to a mailing list ===
 +
 +
If you want to send patches directly to a mailing list, you have to install the following packages: {{Pkg|perl-authen-sasl}}, {{Pkg|perl-net-smtp-ssl}} and {{Pkg|perl-mime-tools}}.
 +
 +
Make sure you have configured your username and e-mail address, see [[#Configuration]].
 +
 +
Configure your e-mail settings:
 +
 +
$ git config --global sendemail.smtpserver ''smtp.example.com''
 +
$ git config --global sendemail.smtpserverport ''587''
 +
$ git config --global sendemail.smtpencryption ''tls''
 +
$ git config --global sendemail.smtpuser ''foobar@example.com''
 +
 +
Now you should be able to send the patch to the mailing list (see also [http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded#Sending_patches OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches]):
 +
 +
$ git add ''filename''
 +
$ git commit -s
 +
$ git send-email --to=''openembedded-core@lists.openembedded.org'' --confirm=always -M -1
 +
 +
=== When the remote repo is huge ===
 +
 +
{{Style|Uses informal language, contractions, HTML tags instead of code templates and does not use interwiki links.}}
 +
 +
When the remote repo is huge, what can you do? See this section. The examples are taken from the linux kernel.
 +
 +
==== Simplest way: fetch the entire repo ====
 +
You can get the entire repository by
 +
 +
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
 +
 +
This download takes long - "git clone" can not be resumed once it's stopped, as of Aug 2018 - and it'll cost some HDD space.
 +
 +
You can update your repo by
 +
$ git pull
 +
==== Partial fetch ====
 +
Probably you want to limit your local repository smaller, say after v4.14 to bisect a bug. Then do:
 +
 +
$ git clone --shallow-exclude v4.13  git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git # You'll get v4.14 and later, but not v4.13 and older.
 +
 +
Or maybe you only want the latest snapshot, ignoring all history. (If a tarball is available and it suffices, choose that. Getting a git repo costs more.) You can do it by:
 +
 +
$ git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
 +
 +
You can later obtain older commits, by e.g.
 +
 +
$ git fetch --tags --shallow-exclude v4.1 # Get the commits after v4.1.
 +
$ git fetch --tags --shallow-since 2016-01-01
 +
 +
Without <code>--tags</code>, tags won't be fetched.
 +
 +
==== Get other branches ====
 +
Your local repo tracks, in the above example, only the mainline kernel, i.e. in which the ''latest development is done''. Suppose you want the latest ''LTS'', for example the up-to-date 4.14 branch. You can get it by:
 +
 +
$ git remote set-branches --add origin linux-4.17.y
 +
$ git fetch
 +
$ git branch --track linux-4.17.y origin/linux-4.17.y
 +
 +
The last line is not mandatory, but probably you want it.
 +
(To know the name of the branch you want, sorry, there's no general rule. You can guess one by seeing the "ref" link in the gitweb interface.)
 +
 +
If you want the snapshot of linux-4.17.y, do
 +
 +
$ git checkout -b linux-4.17.y
 +
 +
Or to extract it in another directory,
 +
 +
$ mkdir /foo/bar/src-4.17; cd /foo/bar/src-4.17
 +
$ git clone --no-local --depth 1 -b linux-4.17.y  ../linux-stable
 +
 +
As usual, do <code>git pull</code> to update your snapshot.
 +
 +
==== Possilbe Future alternative ====
 +
Git Virtual Filesystem (GVFS), developed by Microsoft, allows you to access git repositories without a local one. (See [https://blogs.msdn.microsoft.com/bharry/2017/05/24/the-largest-git-repo-on-the-planet/ this Microsoft blog] or the [[wikipedia:Git_Virtual_File_System|Wikipedia artcile]].) It's not available in Linux yet.
 +
 +
Anyway it is not for the above examples of the Linux kernel, though.
  
 
== Git server ==
 
== Git server ==
Line 498: Line 531:
 
     url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git
 
     url = ssh://''user''@''foobar''.com:443/~''my_repository''/repo.git
 
}}
 
}}
 +
 +
You are able to secure the SSH user account even more allowing only push and pull commands on this user account. This is done by replacing the default login shell by git-shell. Described in [https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server Setting Up the Server].
  
 
=== Smart HTTP ===
 
=== Smart HTTP ===
Line 522: Line 557:
  
 
For more detailed documentation, visit the following links:
 
For more detailed documentation, visit the following links:
* http://progit.org/2010/03/04/smart-http.html
+
* https://git-scm.com/book/en/v2/Git-on-the-Server-Smart-HTTP
* https://www.kernel.org/pub/software/scm/git/docs/v1.7.10.1/git-http-backend.html
+
* https://git-scm.com/docs/git-http-backend
  
 
=== Git ===
 
=== Git ===
Line 541: Line 576:
 
=== Setting access rights ===
 
=== Setting access rights ===
  
To restrict read and/or write access, use standard Unix permissions. Refer to http://sitaramc.github.com/gitolite/doc/overkill.html{{Dead link|2013|11|06}} ([https://web.archive.org/web/20111004134500/http://sitaramc.github.com/gitolite/doc/overkill.html archive.org mirror]) for more information.
+
To restrict read and/or write access, use standard Unix permissions. Refer to
 +
[https://github.com/sitaramc/gitolite/blob/d74e58b5de8c78bddd29b009ba2d606f7fcb4f2d/doc/overkill.mkd when gitolite is overkill] for more information.
  
 
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].
 
For fine-grained access management, refer to [[gitolite]] and [[gitosis]].
Line 547: Line 583:
 
== See also ==
 
== See also ==
  
* Miscallaneous man pages available in the {{Pkg|git}} package: {{ic|gittutorial(7)}}, {{ic|giteveryday(7)}}, {{ic|gitworkflows(7)}}
+
* Git man pages, see {{man|1|git}}
* [http://git-scm.com/book Pro Git book]
+
* [https://git-scm.com/book/en/ Pro Git book]
* [http://gitref.org/ Git Reference]
+
* [https://git.github.io/git-reference/ Git Reference] by GitHub
* https://www.kernel.org/pub/software/scm/git/docs/
+
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git workflow: Forks, remotes, and pull requests]
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request Git overall]
+
* [https://wiki.videolan.org/Git VideoLAN wiki article]
* [http://nathanhoad.net/git-workflow-forks-remotes-and-pull-requests Git overall2]
+
* [https://gist.github.com/grawity/4392747 A comparison of protocols GitHubGist]
* https://wiki.videolan.org/Git
+
* [https://gun.io/blog/how-to-github-fork-branch-and-pull-request How to GitHub]
* [https://gist.github.com/grawity/4392747 A comparison of protocols offered by GitHub]
 

Latest revision as of 07:39, 14 August 2018

I've met people who thought that git is a front-end to GitHub. They were wrong, git is a front-end to the AUR.

Git is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the Linux kernel. Git is now used to maintain AUR packages, as well as many other projects, including sources for the Linux kernel.

Installation

Install the git package. For the development version, install the git-gitAUR package. Check the optional dependencies when using tools such as git svn, git gui and gitk.

Graphical front-ends

See also git GUI Clients.

  • Giggle — GTK+ frontend for git.
https://wiki.gnome.org/Apps/giggle/ || giggle
  • Git Cola — Sleek and powerful graphical user interface for Git written in Python.
https://git-cola.github.io/ || git-colaAUR
  • Git Extensions — Graphical user interface for Git that allows you to control Git without using the commandline.
https://gitextensions.github.io/ || gitextensionsAUR
  • gitg — GNOME GUI client to view git repositories.
https://wiki.gnome.org/Apps/Gitg || gitg
  • git-gui — Tcl/Tk based portable graphical interface to Git.
https://git-scm.com/docs/git-gui || git + tk
Note: To enable spell checking in git-gui, aspell is required, along with the dictionary corresponding to the LC_MESSAGES environment variable. See FS#28181 and the aspell article.
  • gitk — Tcl/Tk based Git repository browser.
https://git-scm.com/docs/gitk || git + tk
  • QGit — Git GUI viewer to browse revisions history, view patch content and changed files, graphically following different development branches.
https://github.com/tibirna/qgit || qgit
  • RabbitVCS — Set of graphical tools written to provide simple and straightforward access to the version control systems you use.
http://rabbitvcs.org/ || rabbitvcsAUR
  • Tig — ncurses-based text-mode interface for git.
https://jonas.github.io/tig/ || tig
  • ungit — Brings user friendliness to git without sacrificing the versatility of git.
https://github.com/FredrikNoren/ungit || nodejs-ungitAUR

Configuration

In order to use Git you need to set at least a name and email:

$ git config --global user.name  "John Doe"
$ git config --global user.email "johndoe@example.com"

See Getting Started - First-Time Git Setup.

See #Tips and tricks for more settings.

Usage

A Git repository is contained in a .git directory, which holds the revision history and other metadata. The directory tracked by the repository, by default the parent directory, is called the working directory. Changes in the working tree need to be staged before they can be recorded (committed) to the repository. Git also lets you restore, previously committed, working tree files.

See Getting Started - Git Basics.

Getting a Git repository

  • Initialize a repository
git init, see git-init(1)
  • Clone an existing repository
git clone repository, see git-clone(1)

Recording changes

Git projects have a staging area, which is an index file in your Git directory, that stores the changes that will go into your next commit. To record a modified file you therefore firstly need to add it to the index (stage it). The git commit command then stores the current index in a new commit.

Staging changes

  • Add working tree changes to the index
git add pathspec, see git-add(1)
  • Remove changes from the index
git reset pathspec, see git-reset(1)
  • Show changes to be committed, unstaged changes and untracked files
git status, see git-status(1)

You can tell Git to ignore certain untracked files using .gitignore files, see gitignore(5).

Git does not track file movement. Move detection during merges is based only on content similarity. The git mv command is just there for convenience and is equivalent to:

$ mv -i foo bar
$ git reset -- foo
$ git add bar

Committing changes

The git commit command records the staged changes to the repository, see git-commit(1).

  • -m – supply the commit message as an argument, instead of composing it in your default text editor
  • -a – automatically stage files that have been modified or deleted (does not add untracked files)
  • --amend – redo the last commit, amending the commit message or the committed files
Tip: Always commit small changes frequently and with meaningful messages.

Revision selection

Git offers multiple ways to specify revisions, see gitrevisions(7) and Revision Selection.

Many Git commands take revisions as arguments. A commit can be identified by any of the following:

  • SHA-1 hash of the commit (the first 7 digits are usually sufficient to identify it uniquely)
  • Any commit label such as a branch or tag name
  • The label HEAD always refers to the currently checked-out commit (usually the head of the branch, unless you used git checkout to jump back in history to an old commit)
  • Any of the above plus ~ to refer to previous commits. For example, HEAD~ refers to one commit before HEAD and HEAD~5 refers to five commits before HEAD.

Viewing changes

Show differences between commits:

$ git diff HEAD HEAD~3

or between staging area and working tree:

$ git diff

View history of changes (where "-N" is the number of latest commits):

$ git log -p (-N)

Undoing things

  • git reset - reset current HEAD to the specified state, see git-reset(1)

Branching

Fixes and new features are usually tested in branches. When changes are satisfactory they can merged back into the default (master) branch.

Create a branch, whose name accurately reflects its purpose:

$ git branch help-section-addition

List branches:

$ git branch

Switch branches:

$ git checkout branch

Create and switch:

$ git checkout -b branch

Merge a branch back to the master branch:

$ git checkout master
$ git merge branch

The changes will be merged if they do not conflict. Otherwise, Git will print an error message, and annotate files in the working tree to record the conflicts. The annotations can be displayed with git diff. Conflicts are resolved by editing the files to remove the annotations, and committing the final version. See #Dealing with merges below.

When done with a branch, delete it with:

$ git branch -d branch

Collaboration

A typical Git work-flow is:

  1. Create a new repository or clone a remote one.
  2. Create a branch to make changes; then commit those changes.
  3. Consolidate commits for better organization/understanding.
  4. Merge commits back into the main branch.
  5. (Optional) Push changes to a remote server.

Pull requests

After making and committing some changes, the contributor can ask the original author to merge them. This is called a pull request.

To pull:

$ git pull location master

The pull command combines both fetching and merging. If there are conflicts (e.g. the original author made changes in the same time span), then it will be necessary to manually fix them.

Alternatively, the original author can pick the changes wanting to be incorporated. Using the fetch option (and log option with a special FETCH_HEAD symbol), the contents of the pull request can be viewed before deciding what to do:

$ git fetch location master
$ git log -p HEAD..FETCH_HEAD
$ git merge location master

Using remotes

Remotes are aliases for tracked remote repositories. A label is created defining a location. These labels are used to identify frequently accessed repositories.

Create a remote:

$ git remote add label location

Fetch a remote:

$ git fetch label

Show differences between master and a remote master:

$ git log -p master..label/master

View remotes for the current repository:

$ git remote -v

When defining a remote that is a parent of the fork (the project lead), it is defined as upstream.

Push to a repository

After being given rights from the original authors, push changes with:

$ git push location branch

When git clone is performed, it records the original location and gives it a remote name of origin.

So what typically is done is this:

$ git push origin master

If the -u (--set-upstream-to) option is used, the location is recorded so the next time just a git push is necessary.

Dealing with merges

See Basic Merge Conflicts in the Git Book for a detailed explanation on how to resolve merge conflicts. Merges are generally reversible. If wanting to back out of a merge one can usually use the --abort command (e.g. git merge --abort or git pull --abort).

History and versioning

Searching the history

git log will give the history with a commit checksum, author, date, and the short message. The checksum is the "object name" of a commit object, typically a 40-character SHA-1 hash.

For history with a long message (where the "checksum" can be truncated, as long as it is unique):

$ git show (checksum)

Search for pattern in tracked files:

$ git grep pattern

Search in .c and .h files:

$ git grep pattern -- '*.[ch]'

Tagging

Tag commits for versioning:

$ git tag 2.14 checksum

Tagging is generally done for releasing/versioning but it can be any string. Generally annotated tags are used, because they get added to the Git database.

Tag the current commit with:

$ git tag -a 2.14 -m "Version 2.14"

List tags:

$ git tag -l

Delete a tag:

$ git tag -d 2.08

Update remote tags:

$ git push --tags

Organizing commits

Before submitting a pull request it may be desirable to consolidate/organize the commits. This is done with the git rebase --interactive option:

$ git rebase -i checksum

This will open the editor with a summary of all the commits in the range specified; in this case including the newest (HEAD) back to, but excluding, commit checksum. Or to use a number notation, use for example HEAD~3, which will rebase the last three commits:

pick d146cc7 Mountpoint test.
pick 4f47712 Explain -o option in readme.
pick 8a4d479 Rename documentation.

Editing the action in the first column will dictate how the rebase will be done. The options are:

  • pick — Apply this commit as is (the default).
  • edit — Edit files and/or commit message.
  • reword — Edit commit message.
  • squash — Merge/fold into previous commit.
  • fixup — Merge/fold into previous commit discarding its message.

The commits can be re-ordered or erased from the history (but be very careful with these). After editing the file, Git will perform the specified actions; if prompted to resolve merge problems, fix them and continue with git rebase --continue or back out with the git rebase --abort command.

Note: Squashing commits is only used for local commits, it will cause troubles on a repository that is shared by other people.

Tips and tricks

Using git-config

Git reads its configuration from four INI-type configuration files:

  • /etc/gitconfig for system-wide defaults
  • ~/.gitconfig and ~/.config/git/config (since 1.7.12) for user-specific configuration
  • .git/config for repository-specific configuration

These files can be edited directly, but the usual method is to use git config, as shown in the examples below.

List the currently set variables:

$ git config {--local,--global,--system} --list

Set the default editor from vim to nano:

$ git config --global core.editor "nano -w"

Set the default push action:

$ git config --global push.default simple

Set a different tool for git difftool (meld by default):

$ git config --global diff.tool vimdiff

See git-config(1) and Git Configuration for more information.

Adopting a good etiquette

  • When considering contributing to an existing project, read and understand its license, as it may excessively limit your ability to change the code. Some licenses can generate disputes over the ownership of the code.
  • Think about the project's community and how well you can fit into it. To get a feeling of the direction of the project, read any documentation and even the log of the repository.
  • When requesting to pull a commit, or submit a patch, keep it small and well documented; this will help the maintainers understand your changes and decide whether to merge them or ask you to make some amendments.
  • If a contribution is rejected, do not get discouraged, it is their project after all. If it is important, discuss the reasoning for the contribution as clearly and as patiently as possible: with such an approach a resolution may eventually be possible.

Speeding up authentication

You may wish to avoid the hassle of authenticating interactively at every push to the Git server.

Protocol Defaults

If you are running a multiplexed SSH connection as shown above, Git over SSH might be faster than HTTPS. Also, some servers (like the AUR) only allow pushing via SSH. For example, the following config will set Git over SSH for any repository hosted on the AUR.

~/.gitconfig
[url "ssh://aur@aur.archlinux.org/"]
	insteadOf = https://aur.archlinux.org/
	insteadOf = http://aur.archlinux.org/
	insteadOf = git://aur.archlinux.org/

Bash completion

In order to enable Bash completion, source /usr/share/git/completion/git-completion.bash in a Bash startup file. Alternatively, install bash-completion.

Git prompt

The Git package comes with a prompt script. To enable it, source the /usr/share/git/completion/git-prompt.sh and set a custom prompt with the %s parameter:

  • For Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
  • For zsh: setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '

To automate this see Command-line shell#Configuration files.

When changing to a directory of a Git repository, the prompt will change to show the branch name. Extra details can be set to be shown by the prompt:

Shell variable Information
GIT_PS1_SHOWDIRTYSTATE + for staged, * if unstaged.
GIT_PS1_SHOWSTASHSTATE $ if something is stashed.
GIT_PS1_SHOWUNTRACKEDFILES % if there are untracked files.
GIT_PS1_SHOWUPSTREAM <,>,<> behind, ahead, or diverged from upstream.

GIT_PS1_SHOWUPSTREAM will need to be set to auto for changes to take effect.

Note: If you experience that $(__git_ps1) returns ((unknown)), then there is a .git folder in your current directory which does not contain any repository, and therefore Git does not recognize it. This can, for example, happen if you mistake Git's configuration file to be ~/.git/config instead of ~/.gitconfig.

Alternatively, you can use one of git shell prompt customization packages from AUR such as bash-git-promptAUR or gittifyAUR.

Visual representation

To get an idea of the amount of work done:

$ git diff --stat

git log with forking representation:

$ git log --graph --oneline --decorate

git log graph alias (i.e. git graph will show a decorated version):

$ git config --global alias.graph 'log --graph --oneline --decorate'

Commit tips

Reset to previous commit (very dangerous, erases everything to specified commit):

$ git reset --hard HEAD^

If a repository address gets changed, its remote location will need to be updated:

$ git remote set-url origin git@address:user/repo.git

Signed-off-by line append (a name-email signature is added to the commit which is required by some projects):

$ git commit -s

Signed-off-by automatically append to patches (when using git format-patch commit):

$ git config --local format.signoff true

Commit specific parts of files that have changed. This is useful if there are a large number of changes made that would be best split into several commits:

$ git add -p

Signing commits

Git allows commits and tags to be signed using GnuPG, see Signing Your Work.

Note: To use pinentry curses for GPG signing make sure to export GPG_TTY=$(tty) (alternatively use pinentry-tty) otherwise the signing step will fail if GPG is currently in a locked state (since it cannot prompt for pin).

To configure Git to automatically sign commits:

$ git config --global commit.gpgSign true

Working with a non-master branch

Occasionally a maintainer will ask that work be done on a branch. These branches are often called devel or testing. Begin by cloning the repository.

To enter another branch beside master (git clone only shows master branch but others still exist, git branch -a to show):

$ git checkout -b branch origin/branch

Now edit normally; however to keep the repository tree in sync be sure to use both:

$ git pull --all
$ git push --all

Directly sending patches to a mailing list

If you want to send patches directly to a mailing list, you have to install the following packages: perl-authen-sasl, perl-net-smtp-ssl and perl-mime-tools.

Make sure you have configured your username and e-mail address, see #Configuration.

Configure your e-mail settings:

$ git config --global sendemail.smtpserver smtp.example.com
$ git config --global sendemail.smtpserverport 587
$ git config --global sendemail.smtpencryption tls
$ git config --global sendemail.smtpuser foobar@example.com

Now you should be able to send the patch to the mailing list (see also OpenEmbedded:How to submit a patch to OpenEmbedded#Sending patches):

$ git add filename
$ git commit -s
$ git send-email --to=openembedded-core@lists.openembedded.org --confirm=always -M -1

When the remote repo is huge

Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements. See Help:Style for reference.Tango-edit-clear.png

Reason: Uses informal language, contractions, HTML tags instead of code templates and does not use interwiki links. (Discuss in Talk:Git#)

When the remote repo is huge, what can you do? See this section. The examples are taken from the linux kernel.

Simplest way: fetch the entire repo

You can get the entire repository by

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

This download takes long - "git clone" can not be resumed once it's stopped, as of Aug 2018 - and it'll cost some HDD space.

You can update your repo by

$ git pull

Partial fetch

Probably you want to limit your local repository smaller, say after v4.14 to bisect a bug. Then do:

$ git clone --shallow-exclude v4.13   git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git # You'll get v4.14 and later, but not v4.13 and older.

Or maybe you only want the latest snapshot, ignoring all history. (If a tarball is available and it suffices, choose that. Getting a git repo costs more.) You can do it by:

$ git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

You can later obtain older commits, by e.g.

$ git fetch --tags --shallow-exclude v4.1 # Get the commits after v4.1.
$ git fetch --tags --shallow-since 2016-01-01

Without --tags, tags won't be fetched.

Get other branches

Your local repo tracks, in the above example, only the mainline kernel, i.e. in which the latest development is done. Suppose you want the latest LTS, for example the up-to-date 4.14 branch. You can get it by:

$ git remote set-branches --add origin linux-4.17.y
$ git fetch
$ git branch --track linux-4.17.y origin/linux-4.17.y

The last line is not mandatory, but probably you want it. (To know the name of the branch you want, sorry, there's no general rule. You can guess one by seeing the "ref" link in the gitweb interface.)

If you want the snapshot of linux-4.17.y, do

$ git checkout -b linux-4.17.y

Or to extract it in another directory,

$ mkdir /foo/bar/src-4.17; cd /foo/bar/src-4.17
$ git clone --no-local --depth 1 -b linux-4.17.y  ../linux-stable

As usual, do git pull to update your snapshot.

Possilbe Future alternative

Git Virtual Filesystem (GVFS), developed by Microsoft, allows you to access git repositories without a local one. (See this Microsoft blog or the Wikipedia artcile.) It's not available in Linux yet.

Anyway it is not for the above examples of the Linux kernel, though.

Git server

How to set up connecting to repositories using varying protocols.

SSH

To use the SSH protocol, first set up a public SSH key; for that follow the guide at SSH keys. To set up a SSH server, follow the SSH guide.

With SSH working and a key generated, paste the contents of ~/.ssh/id_rsa.pub to ~/.ssh/authorized_keys (be sure it is all on one line). Now the Git repository can be accessed with SSH by doing:

$ git clone user@foobar.com:my_repository.git

You should now get an SSH yes/no question, if you have the SSH client setting StrictHostKeyChecking set to ask (the default). Type yes followed by Enter. Then you should have your repository checked out. Because this is with SSH, you also have commit rights now.

To modify an existing repository to use SSH, the remote location will need to be redefined:

$ git remote set-url origin git@localhost:my_repository.git

Connecting on a port other than 22 can be configured on a per-host basis in /etc/ssh/ssh_config or ~/.ssh/config. To set up ports for a repository (here 443 as example):

.git/config
[remote "origin"]
    url = ssh://user@foobar.com:443/~my_repository/repo.git

You are able to secure the SSH user account even more allowing only push and pull commands on this user account. This is done by replacing the default login shell by git-shell. Described in Setting Up the Server.

Smart HTTP

Git is able to use the HTTP(S) protocol as efficiently as the SSH or Git protocols, by utilizing the git-http-backend. Furthermore it is not only possible to clone or pull from repositories, but also to push into repositories over HTTP(S).

The setup for this is rather simple as all you need to have installed is the Apache web server (apache, with mod_cgi, mod_alias, and mod_env enabled) and of course, git.

Once you have your basic setup running, add the following to your Apache configuration file, which is usually located at:

/etc/httpd/conf/httpd.conf
<Directory "/usr/lib/git-core*">
    Require all granted
</Directory>
 
SetEnv GIT_PROJECT_ROOT /srv/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

This assumes your Git repositories are located at /srv/git and that you want to access them via something like: http(s)://your_address.tld/git/your_repo.git.

Note: Make sure that Apache can read and write to your repositories.

For more detailed documentation, visit the following links:

Git

Note: The Git protocol is not encrypted or authenticated, and only allows read access.

Start and enable git-daemon.socket.

The daemon is started with the following options:

ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git

Repositories placed in /srv/git/ will be recognized by the daemon. Clients can connect with something similar to:

$ git clone git://location/repository.git

Setting access rights

To restrict read and/or write access, use standard Unix permissions. Refer to when gitolite is overkill for more information.

For fine-grained access management, refer to gitolite and gitosis.

See also