--- obj: application wiki: https://en.wikipedia.org/wiki/Git repo: https://github.com/git/git website: https://git-scm.com rev: 2024-12-04 --- # Git Git is the version control system (VCS) designed and developed by Linus Torvalds, the creator of the [Linux](../linux/Linux.md) kernel. Git is now used to maintain AUR packages, as well as many other projects, including sources for the [Linux](../linux/Linux.md) kernel. There is a commit naming scheme called [gitmoji](gitmoji.md) To control a git repo graphically [GitHub Desktop](../applications/development/GitHub%20Desktop.md) can be used. ## Configuration Git can be configured with a `.gitconfig` file or via the command line. In order to use Git you need to set at least a name and [email](../internet/eMail.md): ```shell git config --global user.name "John Doe" git config --global user.email "johndoe@example.com" ``` ## 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. ### Git repository Initialize a repository ```shell git init git init --bare git init -b main ``` Clone an existing repository ```shell git clone repository git clone repository folder git clone --recursive repository git clone --bare repository git clone --sparse repository git clone -b master repository ``` See status of tracked and untracked files: ```shell git status ``` Rename a file or folder: ```shell git mv old new ``` See Commits: ```shell git log git log --graph --oneline --decorate # Graph of all branches git log --graph --all # Extended graph git log --graph ``` ### Commits Git allows commits and tags to be signed using [GnuPG](../cryptography/GPG.md). ```shell git config --global commit.gpgSign true` ``` See how a file come together over commits and authors: ```shell git blame file # Ignore code movements git blame -C -C -C file ``` Add files to version control: ```shell git add file # Add everything git add -A ``` Commit changes: ```shell git commit -m "message" # Signed commit git commit -s -m "message" # Fix last commit with new changes git commit --amend ``` See commit changes: ```shell git show commit # See only changed filenames or status git show --name-only commit git show --name-status commit # Show commit statistics git show --stat commit # Show patch of commit git show -p commit git show --patch commit ``` Revert changes: ```shell git revert # Signed revert commit git revert -s # Revert to the fourth last commit from HEAD git revert HEAD~3 ``` Bring back old revisions of files: ```shell git restore file # Restore state before two commits from master git restore --source master~2 Makefile ``` ## 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: ```shell git branch help-section-addition ``` List branches: ```shell git branch git branch --all git branch --remotes ``` Switch branches: ```shell git checkout # Switch to ref and create new branch git checkout -B ``` Merge a branch back to the master branch: ```shell 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. Any conflicts will look something like this: ``` Here are lines that are either unchanged from the common ancestor, or cleanly resolved because only one side changed, or cleanly resolved because both sides changed the same way. <<<<<<< yours:sample.txt Conflict resolution is hard; let's go shopping. ======= Git makes conflict resolution easy. >>>>>>> theirs:sample.txt And here is another line that is cleanly resolved or unmodified. ``` Continue the merge after resolving merge conflicts: ```shell git merge --continue ``` When done with a branch, delete it with: ```shell git branch -d branch # Also delete on remote git push -d ``` ## Remotes Working with remotes: ```shell git remote [-v | --verbose] git remote add [-t ] [-m ] [-f] git remote rename git remote remove git remote set-head (-a | --auto | -d | --delete | ) git remote set-branches [--add] ... git remote get-url [--push] [--all] git remote set-url [--push] [] git remote set-url --add [--push] git remote set-url --delete [--push] git remote [-v | --verbose] show [-n] ... git remote prune [-n | --dry-run] ... git remote [-v | --verbose] update [-p | --prune] [( | )...] ``` Pull from a reposity: ```shell git pull # Rebase instead of merge (append your commit if remote is newer) git pull --rebase ``` Push to a repository: ```shell git push git push --force git push remote branch ``` ## Tagging Tag commits for versioning: ```shell git tag 2.14 # Signed Tag git tag -s 2.14 # Tag with message git tag -a 2.14 -m "Version 2.14" ``` List tags: ```shell git tag -l ``` Delete a tag: ```shell git tag -d 2.08 ``` Update remote tags: ```shell git push --tags ``` ## Patches & Diffs Show differences: ```shell # Show uncommited changes git diff # Output a summary of file creations, renames and mode changes since a given commit: git diff --summary commit # Output a difference by word instead of line git diff --word-diff # Output a statistic of changes git diff --stat commit # Compare a single file between two branches or commits: git diff branch_1..branch_2 [--] path/to/file # Compare changes between commits git range-diff ``` Generate a patch file: ```shell git format-patch ``` Apply patch files to repository: ```shell git apply patch # Revert patch git apply --reverse patch # Another way to apply patches git am < patch git am --signoff < patch git am --continue < patch git am --abort < patch ``` ## .gitignore A `.gitignore` file specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected. This file contains pattern on each line which exclude files from git versioning. ## Git Hooks Git hooks are custom scripts that run automatically in response to certain Git events or actions. These hooks are useful for automating tasks like code quality checks, running tests, enforcing commit message conventions, and more. Git hooks can be executed at different points in the Git workflow, such as before or after a commit, push, or merge. Git hooks are stored in the `.git/hooks` directory of your repository. By default, this directory contains example scripts with the `.sample` extension. You can customize these scripts by removing the `.sample` extension and editing them as needed. Hooks only apply to your local repository. If a hook script fails it prevents the associated action as well. ### Common Git Hooks - pre-commit - prepare-commit-msg - commit-msg - post-commit - post-checkout - pre-rebase