Low Orbit Flux Logo 2 F

untracked - not tracked ( not in last snapshot ) unmodified - not changed modified - changed but not committed staged - marked for next commit committed - added to DB

index - staging area



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

MacOS Install: install Xcode Command Line Tools - run git from cli for the first time

or directly download binaries



git --version



[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



git help xxxxx
git xxxx --help
git help config


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



git status           # check status

clean - tracked files are unmodified, no untracked 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



git status -s       # short status

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

left char - staging area status right char - working tree status



 .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



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



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



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



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 like this:



git mv README.md README

Or this:



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

git will figure out what was renamed.



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"

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 --pretty=format:"%h %s" --graph        # branch and merge history

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



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

–all-match # and instead of or

- 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



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 ? )



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

origin - default name for server that repo was cloned from local master is setup to track orgin master ( or default branch ) when cloning remote repo



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

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 )



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

git push origin master
git push


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

Tags



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

lightweight tags - just a pointer to a commit annotated tags - full objects with a bunch of info ( recommended )



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

HEAD - pointer to current branch



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



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


merging - fast forward if there is a direct chain, just moves pointer forward
        - recursive strategy - three way merge - 1 common ansestor and 2 branch tips, results in new commit
          ( merge commit - has more than one parent )

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

=======

>>>>>>> iss53:index.html



git add index.html    # add each file that was manually edited
git mergetool        # fire up a gui tool,  can probably edit and add
git commit          # finish the merge

Cancel a merge in progress:



git merge --abort

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

Fast-forward merge - just move pointer forward Recursive merge - 3 way merge: 1 common ancestor, 2 branch tips Octopus merge - multiple branches all merged at once



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: master - stable / prod dev - unstable /dev

topic branches short lived branches

ex: topic/silly_bug_fix

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 
git remote show 

</code></pre>


Remote-tracking branches - RO pointers to remote branches so you can track them

/.




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



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



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

tracking branch tracks an upstream branch


git push origin --delete serverfix                  # delete remote branch

## 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: * save all changes that were made to current branch ( diffs between HEAD and common ancestor ) * move HEAD back to common ancestor commit * add all changes from other branch * add changes for current branch back in * afterwards, can merge with fast forward for a linear history make sure your commits apply cleanly on a remote branch ( good if someone else maintains it ) Example: * Take client branch changes since it diverged from server branch * Replay those on top of the current master branch * The point the client branch to point to the tip of that * Then merge ( fast forward ) master to this


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

* Rebase server onto master without having to check it out * Then merge ( fast forward ) that too


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: * Someone else pulls your branch before you rebase * You rebase and force push * They push it back up after you rebase * It will include your old changes and your rebased version of those changes ( duplicate commits ). * Keeps getting more messed up from there. 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 Rebase - cleaner, not a "first draft", more coherent story Merge - preserve history, how it actually happened ## 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 * need web server, and some other steps Smart HTTP # pre 1.6.6 username/password authentication anonymous or with encryption and auth Dumb HTTP # 1.6.6 and later ### SSH * requires key setup ( probably ) * requires ssh access to host ( might not want this for public stuff but fine on home or corporate networks ) * comes with encryption and auth Clone over SSH:


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

### Git Protocol * no security * no encryption * no auth * port 9418 * git daemon can serve this * usually no push access but can be enabled * supposed to be fast, same transfer mechanism as SSH but no auth or encryption git-daemon-export-ok - file must exist in repo for daemon to serve the repo


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