All - GradedJestRisk/git-training GitHub Wiki

Table of Contents

Manual

git <CMD> --help

Training

List:

  • show changes
    • since last commit git diff
    • between current and a branch ?
    • between 2 branches git diff <BRANCH_1> <BRANCH_2>
  • file
    • with no branch switch: git show REF:FILENAME
  • commit
    • per hunks git add --patch
    • without test (disable pre-commit hook) git commit --no-verify
    • change last commit git commit --amend
  • push
    • without test (disable pre-push hook) git push --no-verify
    • after rebase git push --force--with-lease (preventing someone else'change to be overwritten)

Common

create repo

.gitattributes

doc

attributes

4 operations:

  • set with no value : * text
  • unset: * -text
  • set with specific value: * text=auto
  • unspecified: * !text

header

Header (that apply to ALL files) starts by * , eg: * text=auto Normalization: when a text file is normalized, its line endings are converted to LF in the repository.

text

Control when normalization is triggered. Values:

  • set : do not check if file contains text, normalize anyway
  • unset: do not check for text, never normalize (check-in and check-out)
  • auto : check for text on check-in; if this is text, normalize (when the file has been committed with CRLF, no conversion is done ??)
  • unspecified : use user-specific settings instead (core.autocrlf)
eol

Control how normalization is applied. Values:

  • CRLF:
    • on check-in: force normalization (convert to LF)
    • on check-out: convert LE to CRLF
  • LF:
    • on check-in: force normalization (convert to LF)
    • on check-out: prevent conversion to CRLF (preserve LF)
  • unspecified (!eol): look at the core.eol config
More on that

clone

Clone in specific folder
git clone [email protected]:whatever FOLDER_NAME

branch

checkout

branch

Because of branch name restriction, see here, better avoid:

  • slash /, antislash \
  • dot .
  • space
  • tilde ~
  • caret ^
  • colon :
  • question-mark ?
  • asterisk *
  • open bracket []
  • parenthese ()
  • arobase @
Anyway, you can:
  • use dash -, if you don't use it as first character
  • use parenthese (), if you double-quote the branch name git branch "my()branch", but be careful especially when using zsh (see here why
To sum up, you can use:
  • a-z, A-Z, 1-9
  • - wiwthin

tag

git checkout version <TAG_NAME> -b <BRANCH_NAME>
git checkout tags/version <TAG_NAME> -b <BRANCH_NAME>

stash

Manage uncommited changes when switching branches.

Handful:

  • push changes to stash git stash push
  • list stashed changes git stash list
  • pop changes from stash git stash pop
  • show stash in status: git config --global status.showStash true
Specifics
  • restore specific stashed changes git stash apply <STASH_ID>
  • clear the stash git stash clear
Stash file section (aka hunks, parts of patches):
  • git stash push --patch (-p)

diff

Discard end-of-line difference (use it only on Windows)
git config --global core.whitespace cr-at-eol

add

Handful:

  • add modified,deleted git add --all
  • add all (new, modified,deleted) git add --all
  • handle hunks separately git add --patch
More on --patch

commit

List:

  • Write a comment
  • you forgot something
    • and not pushed
      • just a line: git commit --amend
      • changed many things, change the commit message git commit --amend --no-edit
    • and already pushed : git push --force origin <BRANCH>

pull

Options

  • rebase : --rebase=merges
  • preserve uncommited changes (use stash) : --autostash
Matching configuration
[pull]
   rebase = merges
[rebase]
   autoStash = true

compare

View all modifications on a single file git log --follow -- <FILE_NAME>

View all modifications made by a commit git show <COMMIT_SHA1>

Compare 2 branches, ignoring spaces git diff --ignore-space-change <BRANCH_1> <BRANCH_2>

cleanup

Remove remote branches
git fetch -p

Remove local branches not on remote
git remote prune origin

Exclude files

For files you don't want to be handled in git:

  • binary files;
  • temporary files;
  • IDE files.

shared (.gitignore)

Create a .gitignore file, at root of the repo, and commit it.

Example for all java compiled classes *.class

*.class

In you want to exclude some file under a specific folder, that may be anywhere in your repo, prefix this folder with a **/

**/.idea/workspace.xml

However, if .gitignore has been modified after files appeared in untracked changed, these files won't disappear.
Execute this to remove them form untracked changes.

git rm -r --cached .
git add .
git commit -m "fixed untracked files"

local

To deal with specific issues (ie: some use Windows, some others Linux)

this repository (exclude) =

Update the repo-based local file exclude: it will filter objects before the shared .gitignore applies.
It is stored in .git/info/exclude

all repositories (~/.gitignore)

Setup

touch ~/.gitignore
git config --global core.excludesfile '~/.gitignore'

Remove git config --global --unset core.excludesfile

Encoding and other funny things

End of line

=> to check... Git store everything in repository by default using Unix EOL characters : LF. (??) core.autocrlf parameter controls this:

  • true: Checkout Windows-style, commit Unix-style;
  • input: Checkout as-is, commit Unix-style (when working in Unix, if by incident a bad file is introduced, it will be normalized);
  • false: Checkout as-is, commit as-is.
For single platforms projects, set false. (If platform is Windows, Git will store CRLF in repository).

For cross-platforms projects, use LF in repository, so set:

  • Unix: input (or false if you're lucky);
  • Windows: true.
true: ensure that
  • normalize text files when added
  • files that are already normalized in the repository stay normalized.
If not set, default value is applied: false.

Config

List

Handful:

  • get existing settings file: git config --list --show-origin
  • show all config values : git config --list --show-origin
  • show all repository-specific values: git config --local --list
  • show specific config value : git config --get <PROPERTY>

Set

Set config on repository (not global) Command-line

git config user.name “Joe Bloggs”
git config user.email “[email protected]
Config file (.git/config)
[user]
        name  = "Joe Bloggs”
        email = “[email protected]

Remove

git config --global --unset <PROPERTY>

Misc

List:

  • locate local repo : find ~ -name ".git" 2>/dev/null

Compare repos

Steps:

  • add target git remote add -f b path/to/repo_b.git
  • update target git remote update
  • get diff git diff master remotes/b/master
  • remove target git remote rm b

Update

Windows : git update-git-for-windows

Get remote: .git/config

(..)
[remote "origin"]
	url = https://github.com/g0t4/jenkins2-course-spring-boot.git
	fetch = +refs/heads/*:refs/remotes/origin/*
(..)

Get all repositories (= find all .git folders):

  • Linux: find / -name ".git"
  • Windows (PowerShell) : Get-ChildItem . -Attributes Directory,Directory+Hidden -ErrorAction SilentlyContinue -Include ".git" -Recurse
Show git location in git-bash where git.exe

Commit template

You can use a template for

  • all repositories
  • a specific repository (store that template in the repo)
Add template
echo "Feature - Symptom - Cause " > .gitCommitTemplate
git config --global commit.template .gitCommitTemplate

Save last commit (?)

vi .git/hooks/post-commit

#!/bin/sh
printf "`git log -1 --pretty=%s`" > .gitmessage.txt

chmod +x .git/hooks/post-commit

Prepare commit message & enforce rules

Modify pushed commit

Remove an already-pushed commit (warn people that checked it out locally)

git reset --hard HEAD^
git push --force-with-lease

Remove from history implies remove all history

File operation

Include OS command and git staging:

  • git-rm
  • git-mv

Bulk commit change

List:

  • from a commit up to HEAD rebase --execute
  • on commit rantge: rev-list
⚠️ **GitHub.com Fallback** ⚠️