Low Orbit Flux Logo 2 F

States:

Install

Linux:



sudo dnf install git-all
sudo apt install git-all

MacOS Install:

Alternate install

Check version:



git --version

Configure



[path]//etc/gitconfig
~/.gitconfig or ~/.config/git/config
.git/config


git config --list                        # check settings
git config --list --show-origin   # view all settings and where they are from

--global # set for all projects

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

git config --global core.editor emacs

git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"


git config --global init.defaultBranch main       # change default branch name instead of master

git config user.name
git config core.editor
git config --show-origin user.name

Get Help



git help xxxxx
git xxxx --help
git help config

Basic Commands


cd /home/user/my_project
git init

git add *.c
git add LICENSE                         # version at time you ran this command
git commit -m 'Initial project version'

git clone https://github.com/libgit2/libgit2
git clone https://github.com/libgit2/libgit2 mylibgit

Adding files:



git add xxxx
    # version at time you ran this command, changing again will result in stated/unstaged status
    # begin tracking, stage, mark merge-conflicted files as resolved

Status



git status           # check status



git status -s       # short status

 M       modified, not staged   ( note the leading space )
M        modified, staged
MM       modified, staged, modified
A        new, staged
??       untracked

Git Ignore

.gitignore
*.[oa] *~ /!doc.txt # negate, do track this one *.txt # glob /*.txt # leading slash for non recursive build/ # slash to match dir a/**/z # match nested dirs, multiple levels doc/*.txt # not recursive doc/**/*.pdf # recursive

Diff / Compare

Standard diff:



git diff            # compare working dir to staged
git diff --staged   # compare staged to last commit
git diff --cached   # compare staged to last commit

Tools:



git difftool --tool-help
git difftool --tool=araxis
git difftool --tool=kompare

Commit



git commit        # commit, open editor with output of 'git status' commented out, comments stripped after saving
git commit -v     # same but with 'git diff'
git commit -m "my update 1 - some changes"   # specify commit message
git commit -a -m 'Add new benchmarks'        # add all tracked files and commit

Remove / Delete



git rm test1.java      # remove from staging and working dir ( removes from git )
git rm -f test1.java   # force if it was already added to staging


git rm --cached output.log  # remove from staging ( and from git ) but keep in working dir
                            # good for accidentally included files that should be ignored


git rm log/\*.log        # !!! escape * so we can use git expansion and not shell expansion

Rename

Rename like this:



git mv README.md README

Or this, git will figure out what was renamed:



mv README.md README
git rm README.md
git add README

Log / History



git log    # show commit history
git log -p -2   # show diff / patch output,  limit to 2 entries
git log --stat   # short stats for each commit
git log --pretty=oneline   # one line output

git log --pretty=format:"%h - %an, %ar : %s"
git log --pretty=format:"%H - %an, %cd : %s"

git log --pretty=format:"%h %s" --graph        # branch and merge history

git log --since=2.weeks
git log --since=2024-01-01
git log --pretty=oneline --since=2024-01-01

git log -S function_name      # Git’s “pickaxe” option - commits that changed occurrences of string

git log --_includes/common_header1.md                              # commits that changed this file
git log --pretty=oneline -- _includes/common_header1.md            # same but one line

Git log formatting specifiers:

Specifier Description of Output
%H Commit hash
%h Abbreviated commit hash
%T Tree hash
%t Abbreviated tree hash
%P Parent hashes
%p Abbreviated parent hashes
%an Author name
%ae Author email
%ad Author date (format respects the –date=option)
%ar Author date, relative
%cn Committer name
%ce Committer email
%cd Committer date
%cr Committer date, relative
%s Subject

Git log options:

Option Description
-p Show the patch introduced with each commit.
–stat Show statistics for files modified in each commit.
–shortstat Display only the changed/insertions/deletions line from the –stat command.
–name-only Show the list of files modified after the commit information.
–name-status Show the list of files affected with added/modified/deleted information as well.
–abbrev-commit Show only the first few characters of the SHA-1 checksum instead of all 40.
–relative-date Display the date in a relative format (for example, “2 weeks ago”) instead ofusing the full date format.
–graph Display an ASCII graph of the branch and merge history beside the log output.
–pretty Show commits in an alternate format. Option values include oneline, short,full, fuller, and format (where you specify your own format).
–oneline Shorthand for –pretty=oneline –abbrev-commit used together.
–all-match and instead of or
-<n> Show only the last n commits.
–since, –after Limit the commits to those made after the specified date.
–until, –before Limit the commits to those made before the specified date.
–author Only show commits in which the author entry matches the specified string.
–committer Only show commits in which the committer entry matches the specified string.
–grep Only show commits with a commit message containing the string.
-S Only show commits adding or removing code matching the string.
–no-merges don’t show merge commits

Amend

Change existing commit:



git add .               # add forgotton files / missing changes
git commit --amend      # ammend to commit ( completly replaces that commit )

Use amend before pushing. Using amend and then force pushing can cause issues for others. ( ? probably fine in a forked setup ? )

Undoing Changes



git reset HEAD CONTRIBUTING.md         # unstage a file
git restore --staged CONTRIBUTING.md   # unstage a file   (new command in 2.23.0 )
git checkout -- CONTRIBUTING.md        # replace file in working dir with last staged or committed version
git restore CONTRIBUTING.md            # replace file in working dir with last staged or committed version

Remotes



git remote      # show remote servers ( short names )
git remote -v   # also show URLs

git remote add pb https://github.com/paulboone/ticgit   # shortname, URL


git remote show origin     # inspect remote, shows which branches are tracked and how they map out

git remote rename pb paul  # rename a remote

git remote remove paul     # remove a remote
git remote rm paul         # remove a remote

Fetch and Pull



git fetch        # get all info, you can then use other branches that you didn't have
git fetch pb     # get all info from this remote
git fetch origin # get all info from this remote

git pull         # fetch and merge into current branch ( usually from origin master )

Push



git push origin master
git push

Rebase Config



git config --global pull.rebase "false"
    * default behavior of Git (fast-forward if possible, else create a merge commit)
    * 2.27 might give warnings about pull.rebase not being set on git pull

Tags



git tag                # list tags
git tag -l "v1.8.5*"   # list matching tags



git tag -a v1.4 -m "my version 1.4"   # create annoteted tag, -m to specify message
git show v1.4                         # show it


git tag v1.4-lw   # create lightweight tag
git show v1.4-lw  # show it


git tag -a v1.2 9fceb02          # tag existing commit


git push origin v1.5             # push a tag to remote
git push origin --tags           # push all tags
git push origin --follow-tags    # only annoteted tags

git tag -d v1.4-lw                     # delete local tag
git push origin :refs/tags/v1.4-lw     # delete remote tag ( overwrite with null value )
git push origin --delete v1.4-lw       # delete remote tag

git checkout v2.0.0                    # checkout a tag ( but results in detached HEAD )
git checkout -b version2 v2.0.0        # create a branch based on a tag

Aliases



git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'             # ! for external command

Brancing



git branch      # list branches
git branch -v   # list branches with last commit
git branch --merged   # show branches that are already merged into current branch
git branch --no-merged  # not merged yet
git branch --no-merged master   # what isn't merged into master


git branch testing      # create new branch pointing to current commit,  DOESN'T switch to it
git checkout testing    # switch to existing branch
git checkout master     # switch back
git checkout -b test2  # create and switch to new branch

git switch testing      # switch to existing branch  ( v2.23 and up )
git switch -c test2     # create and switch to branch
git switch -            # switch to previous checked out branch

More branch info



git log --oneline --decorate                  # show where branch pointers are pointing
git log --oneline --decorate --graph --all    # show graph of all branches

git log testing   # show history for this branch
git log --all     # show history for all branches

Merging



git checkout master
git merge hotfix          # hotfix merged into master, both will point to same commit

git branch -d hotfix      # remove branch
git branch -D hotfix      # remove branch that hasn't been merged

Merge Conflict



git status         # show which files are unmerged ( Unmerged paths: )

Manually edit each section in each file that looks like this:



<<<<<<< HEAD:index.html

size = 10

=======

size = 5

>>>>>>> hotfix:index.html

Next:



git add index.html    # add each file that was manually edited
git commit            # finish the merge

Optionally, to edit and add:



git mergetool        # fire up a gui tool,  can probably edit and add

Cancel a merge in progress:



git merge --abort

Always commit or stash before merging, aborting a merge could result in lossing uncommitted files.



git branch --move bad-branch-name corrected-branch-name  # rename branch locally
git push --set-upstream origin corrected-branch-name     # push renamed branch to remote
git push origin --delete bad-branch-name                 # remove old branch name from remote

git branch --all   # show all branches


git branch --move master main              # rename master to main, can break things
git push --set-upstream origin main
git push origin --delete master

Branching Workflows

Long-Running Branches

ex:

Topic branches ( short lived branches )

ex:

Commit History

Commit history is still branched after removing branch:



$git log --oneline --decorate --graph --all
*   9e54cb2 (HEAD -> master) Merge branch 'topic/abc123'
|\
| * 59cfb94 (topic/abc123) update
* | 595b1af update
|/
* 25e7897 update
* a3a00e1 update
* a7d16a5 update
$git branch -d topic/abc123
Deleted branch topic/abc123 (was 59cfb94).
$git log --oneline --decorate --graph --all
*   9e54cb2 (HEAD -> master) Merge branch 'topic/abc123'
|\
| * 59cfb94 update
* | 595b1af update
|/
* 25e7897 update
* a3a00e1 update
* a7d16a5 update
$

Git show remote references:



git ls-remote repo-name
git remote show remote-name

Remote Branches

Remote branches:



git push origin serverfix                 # push a branch to remote
git push origin serverfix:awesomebranch   # use different branch name on remote


git merge origin/serverfix                    # merge remot branch with current local
git checkout -b serverfix origin/serverfix    # create local branch from remote branch and tracks it
git checkout --track origin/serverfix         # same
git checkout -b sf origin/serverfix           # use different local name

git branch -u origin/serverfix  # track specific remote branch on current local  ( or change the tracked branch )
git merge @{u}                  # shortcut for remote branch

git branch -vv                  # show what each branch is tracking ( since last fetch )
git fetch --all;
git branch -vv
git pull                        # fetch and merge current local branch with current remote

git push origin --delete serverfix                  # delete remote branch

Credential Helpers:



git config --global credential.helper cache                               # temp 15 min cache
git config --global credential.helper 'store --file ~/.my-credentials'    # clear text in file

Rebasing



git checkout experiment
git rebase master        # pull in all changes from master and apply them before any changes in experiment
git checkout master      # back to master
git merge experiment     # can now do a fast forward merge

rebase:

Make sure your commits apply cleanly on a remote branch ( good if someone else maintains it ).

Example



git rebase --onto master server client
git checkout master
git merge client



git rebase master server
git checkout master
git merge server

Remove the topic branches:



git branch -d client
git branch -d server

Cancel Rebase



git rebase --abort   # cancel rebase
git rebase --quit    # if cancelling didn't work

The Perils of Rebasing

“Do not rebase commits that exist outside your repository and that people may have based work on.”

Scenario:

I’ve you have someone elses rebased work, you can rebase again and git should figure out which commits are duplicates and which need to be added ( rebase on top of force pushed rebase ).



git fetch
git rebase  teamone/master

OR



git pull --rebase

Rebase vs Merge

Git Revert



git revert 25e7897d1ce4ca817555d71ac158d8e7112bded5   # revert a commit ( just changes from this commit ), creates new commit for this
git revert HEAD                                       # revert last commit in current branch

git reset 25e7897d1ce4ca817555d71ac158d8e7112bded5    # revert to this point and any other commit after it ( HEAD goes back to this commit )

Squashing

Squashing with merge:



git merge --squash

Squash local commits:



git rebase -i

Squash to whatever is in origin/master:



git rebase -i origin/master
git push -f

If there are conflicts:



git add .
git rebase --continue

Cherry Pick



git cherry-pick e43a6   # pull a specific commit from any other branch into your HEAD branch

git cherry-pick af02e0b --no-commit   # only add to current copy

Git Stash

“Stash the changes in a dirty working directory away”



git stash          # stash uncommitted changes ( staged and unstaged, not untracked )
git stash -u       # include untracked files
git stash list     # Show stashes
git stash show     # show operations performed on the stash

git stash save "message"  # message for this stash (deprecated)
git stash push "message"  # message for this stash
git pop                   # remove changes from stash, restore to working dir and index
git apply                 # keep in stash but also restore to working dir and index

git stash branch newbranch            # create new branch based on stash and the commit it was based on, latest stash
git stash branch newbranch stash@{0}  # same but specify the stash

git stash drop stash@{1}         # remove a stash
git stash clear                  # remove all stashes

Git Server

bare repository — git repo with no working directory

Protocols: Local, HTTP, Secure Shell (SSH) and Git

local

local - local file system ( or NAS )



git clone /srv/git/project.git            # tries to use hard links and file copying
git clone file:///srv/git/project.git     # transfers using network

git remote add local_proj /srv/git/project.git   # add local repo to existing project as a remote

HTTP

Smart HTTP # pre 1.6.6 username/password authentication anonymous or with encryption and auth Dumb HTTP # 1.6.6 and later

SSH

Clone over SSH:



git clone ssh://[user@]server/project.git
git clone [user@]server:project.git

Git Protocol

git-daemon-export-ok - file must exist in repo for daemon to serve the repo



git clone git://example.com/project.git

References

Most things on this page are based on this book: