Git

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.

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

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.

  • gitg GNOME GUI client to view git repositories.
https://wiki.gnome.org/Apps/Gitg || gitg
    • gitk Tcl/Tk based Git repository browser.
    https://git-scm.com/docs/gitk || git + tk
    • Tig ncurses-based text-mode interface for git.
    https://jonas.github.io/tig/ || tig

      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 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
      , see
      • Clone an existing repository
      , see git-clone(1) (also explains the Git URLs)

      Recording changes

      Git projects have a staging area, which is an 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 command then stores the current index in a new commit.

      Staging changes

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

      You can tell Git to ignore certain untracked files using files, see .

      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 command records the staged changes to the repository, see .

      • – 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)
      • – redo the last commit, amending the commit message or the committed files

      Revision selection

      Git offers multiple ways to specify revisions, see 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 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, refers to one commit before and refers to five commits before .

      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

      • - to restore working tree files, see git-checkout(1)
      • - reset current HEAD to the specified state, see
      • - revert some existing commits, see

      These, along with few others, are further explained at undoing-changes.

      For more complex modifications of history, such as git commit --amend and see, for example, rewriting-history. It is highly advised not to use such rewrites for commits that were collaborated with other users. Or, at the very least, highly coordinate it in advance.

      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 . 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 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 .

      So what typically is done is this:

      $ git push origin master

      If the -u () option is used, the location is recorded so the next time just a 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 command (e.g. or ).

      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 and 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 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 () back to, but excluding, commit checksum. Or to use a number notation, use for example , 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:

      • — Apply this commit as is (the default).
      • — Edit files and/or commit message.
      • — Edit commit message.
      • — Merge/fold into previous commit.
      • — 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 command.

      Tips and tricks

      Using git-config

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

      • /etc/gitconfig for system-wide defaults
      • and (since 1.7.12) for user-specific configuration
      • 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 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.

      Using git-credential-libsecret as credential-helper

      Git may fetch your credentials from a org.freedesktop.secrets compatible keyring like GNOME/Keyring or KeePassXC. Therefore set up one compatible keyring and check if a keyring is registered to dbus using:

      dbus-send --session --print-reply --dest=org.freedesktop.DBus / \
          org.freedesktop.DBus.GetConnectionUnixProcessID \
          string:org.freedesktop.secrets

      then run

      git config --global credential.helper /usr/lib/git-core/git-credential-libsecret

      to set up git.

      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 configuration will set Git over SSH for any repository hosted on the AUR.

      Bash completion

      In order to enable Bash completion, source in a Bash startup file. Alternatively, install .

      Git prompt

      The Git package comes with a prompt script. To enable it, source the and set a custom prompt with the %s parameter:

      Note that the command substitution must be escaped, see Bash/Prompt customization#Embedding commands for details. See Command-line shell#Configuration files for persistent configuration.

      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 by setting the corresponding environment variable:

      Shell variableInformation
      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_STATESEPARATORseparator between branch name and state symbols
      GIT_PS1_DESCRIBE_STYLEshow commit relative to tag or branch, when detached HEAD
      GIT_PS1_SHOWCOLORHINTSdisplay in color

      The full documentation for the environment variables is available in the comments of the script.

      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 or .

      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

      Alternatively, edit with the new location.

      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 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.

      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 or . 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: and .

      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 and git-send-email.io):

      $ git add filename
      $ git commit -s
      $ git send-email --to=pacman-contrib@lists.archlinux.org --confirm=always -M -1

      Working with a large git repository

      When working with a large remote repository, a significant amount of data has to be fetched. The following examples use the Linux kernel to illustrate how to work with such codebases.

      Fetching the entire repository

      The easiest solution is to get the entire repository:

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

      You can update your repository by git pull.

      Partially fetching the repository

      To limit your local repository to a smaller subset of the origin, say after v4.14 to bisect a bug, use a shallow clone:

      $ git clone --shallow-exclude v4.13 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

      You will get v4.14 and later, but not v4.13 and older.

      If you only want the latest snapshot, ignoring all history. (If a tarball is available and it suffices, choose that. Downloading from a git repository needs more bandwidth.) You can get it with:

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

      You can later obtain older commits, as the two following examples show:

      $ git fetch --tags --shallow-exclude v4.1
      $ git fetch --tags --shallow-since 2016-01-01

      Getting other branches

      Your local repository 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 wanted. (To know the name of the branch you want, there is no general rule. You can guess one by seeing the "ref" link in the gitweb interface.)

      For the snapshot of linux-4.17.y, do

      $ git checkout -b linux-4.17.y

      Or to extract it in another directory,

      $ mkdir /path/to/src-4.17; cd /path/to /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.

      Possible alternative

      Virtual File System for Git (VFS for Git), allows to access git repositories without a local one. (See this Microsoft blog or the Wikipedia article.)

      It already has a successor : Scalar, which is available in , Microsoft's fork of git including gvfs and scalar.

      Filtering confidential information

      Occasionally, software may keep plain-text passwords in configuration files, as opposed to hooking into a keyring. In these cases, git clean-filters may be handy to avoid accidentally commiting confidential information. E. g., the following file assigns a filter to the file “some-dotfile”:

      Whenever the file “some-dotfile” is checked into git, git will invoke the filter “remove-pass” on the file before checking it in. The filter must be defined in the git-configuration file, e. g.:

      HTML help files

      The documentation is also available in HTML form by installing git-htmldocsAUR. After installing, the HTML docs can be accessed by passing the flag. For example:

      $ git help -w merge

      The HTML documentation can be loaded by default by setting a option:

      $ git config --global help.format html

      Extensions

      • git-extras some utilities for git (repo summary, repl,changelog population, author commit percentages, etc.)
      https://github.com/tj/git-extras || git-extrasAUR - If you're using oh-my-zsh, you may also enable git-extras plugin
      gollark: Back. OOM killer ate my browser.
      gollark: Well, this is... executing.
      gollark: μhahahaha.
      gollark: Wow, I made python segfault*!* via blatant ctypes abuse
      gollark: This is why mutability is isomorphic to a single bee per second.

      See also

      This article is issued from Archlinux. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.