Git: Difference between revisions
mNo edit summary |
|||
(81 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== | {| class="wikitable" style="float:right; margin-left: 10px;" width="400px" | ||
| Quick Cheat Sheet | |||
|- | |||
| | |||
<pre class="bash"> | |||
git config credential.helper store | |||
git config user.email "email@example.com" | |||
git config user.name "username" | |||
git log --graph --oneline | |||
</pre> | |||
|} | |||
= Command Overview = | |||
<pre class="bash"> | |||
git init # standard | |||
git init --bare # bare (server) repo without working directory | |||
git clone https://gerrit.wikimedia.org/r/p/mediawiki/core.git | |||
git clone ssh://user@server/srv/git/git-repo.git | |||
git pull # (= git fetch && git merge) | |||
git fetch # get updates from remote, safe operation | |||
git fetch --all # | |||
git fetch upstream | |||
git merge # merges those updates into working dir | |||
git status # show changed files (working dir & staging area) | |||
git diff # show changes in working dir | |||
git diff --cached # show changes in staging area | |||
git log | |||
git add . | |||
git add -A # all | |||
git commit -m "Commit message" | |||
git commit -a # includes add (modified and deleted files, but not new files) | |||
git commit -am "msg" | |||
git commit --amend -m "Fixed" # only do, if not pushed. Amend commit over last wrong commit | |||
git reset --soft | |||
git reset (--mixed) | |||
git reset --hard | |||
git reset --hard origin/master | |||
git clean -df | |||
git push | |||
git push origin master | |||
git push origin --delete <branch> # delete branch from origin | |||
git push -f origin # force push | |||
git push -u origin <branch> # push new local branch to origin | |||
git checkout master | |||
git checkout file.txt | |||
git log | |||
git log --all --decorate --oneline --graph | |||
git branch # list branches | |||
git branch -a # list local & remote branches | |||
git branch --merged # list branches that have been merged | |||
git branch <branch> # create new branch | |||
git branch -d <branch> # delete | |||
git merge <branch> # to be executed on the branch that stays (usually master) | |||
git merge <branch> --no-ff # no fast forward, always keep branch in history | |||
git merge upstream/master # merge upstream master into own fork | |||
git merge --abort | |||
git rebase master # to be executed on the branch that is to be rebased (e.g. feature) | |||
git rebase --continue | |||
git rebase --abort | |||
git rebase -i # interactive | |||
git rebase -i HEAD~3 # interactive mode for 3 most recent commits | |||
git revert <hash> # revert commit (changes from <hash> will be removed) | |||
git config --list # show current git config | |||
git remote -v # show remote urls | |||
git remote set-url origin https.. # set origin url | |||
git remote add upstream https://.. # add upstream remote url | |||
</pre> | |||
<pre class="bash"> | |||
# Merge | |||
A---B---C topic A---B---C topic | |||
/ / \ | |||
D---E---F---G master D---E---F---G---H master | |||
# Rebase | |||
A---B---C topic A'--B'--C' topic | |||
/ / | |||
D---E---F---G master D---E---F---G master | |||
</pre> | |||
= Basics = | |||
<blockquote> | <blockquote> | ||
<pre> | == Create repository == | ||
git init | <pre class="bash"> | ||
git init # standard | |||
git init --bare # bare (server) repo without working directory | |||
</pre> | |||
== Initial checkout of remote repository == | |||
<pre class="bash"> | |||
git clone https://gerrit.wikimedia.org/r/p/mediawiki/core.git | |||
git clone ssh://user@server/srv/git/git-repo.git | |||
</pre> | |||
== Get latest updates from server == | |||
<pre class="bash"> | |||
git pull # (= git fetch && git merge) | |||
git fetch # get updates from remote, safe operation | |||
git merge # merges those updates into working dir | |||
</pre> | </pre> | ||
== Change files and commit == | |||
* show changed files | * show changed files | ||
< | <pre class="bash"> | ||
git status # show changed files (working dir & staging area) | |||
git diff # show changes in working dir | |||
git diff --cached # show changes in staging area | |||
git diff --cached --name-only | git diff --cached --name-only | ||
git diff --name-status | git diff --name-status | ||
</pre> | </pre> | ||
* add files | * add files | ||
< | <pre class="bash"> | ||
git add . | |||
git add | git add -A # all | ||
</pre> | </pre> | ||
* commit changes | * commit changes | ||
<pre class="bash"> | |||
<pre> | git commit -m "Commit message" | ||
git commit -m "Commit | |||
git commit -a # includes add | git commit -a # includes add | ||
git commit -am. | |||
</pre> | </pre> | ||
* send changes to server | * send changes to server | ||
<pre class="bash"> | |||
<pre> | |||
git push | git push | ||
</pre> | |||
== .gitignore files == | |||
<pre class="bash"> | |||
*.log | |||
filename.txt | |||
subfolder/* | |||
</pre> | </pre> | ||
</blockquote> | </blockquote> | ||
= Staging = | |||
<pre> <------------------------ checkout --------------------- | |||
Working Directory -stage-> Staging Area -commit-> Repository</pre> | |||
<pre class="bash"> | |||
git add . # add all files to staging area | |||
git status # show staged & unstaged(untracked) files | |||
git reset # unstage all files | |||
</pre> | |||
= Branches = | |||
<pre class="bash"> | |||
git branch # list local branches | |||
git branch -a # list local & remote branches | |||
git branch --merged # list branches that have been merged | |||
git branch <new-branch-name> # create new branch (from the current commit) | |||
</pre> | |||
=== hard reset to specific branch === | |||
<pre class="bash"> | |||
git fetch --all | |||
git reset --hard origin/branchname | |||
</pre> | |||
=== switch to branch === | |||
<pre class="bash"> | |||
git switch <new-branch-name> | |||
git commit ... some-stuff | |||
git switch master | |||
</pre> | |||
=== merge feature branch into master === | |||
<pre class="bash"> | |||
git checkout master | |||
git merge <new-branch-name> (--no-ff) # no fast forward: create merge commit | |||
git diff | |||
git commit -a | |||
</pre> | |||
=== rebase branch onto latest master === | |||
<pre class="bash"> | |||
git checkout master # go to master | |||
git pull # check if new updates in origin | |||
# ...master has proceeded... | |||
git checkout <branch> # go to <branch> | |||
git rebase master # Rebase pulls the "old" branch up to the latest master position | |||
# now proceed with merge or rebase to get the code onto master | |||
</pre> | |||
=== delete branch === | |||
<pre class="bash"> | |||
git branch -d <branch-name> # local | |||
git push origin --delete <branch-name> # remote | |||
</pre> | |||
https://stackoverflow.com/questions/9069061/what-is-the-difference-between-git-merge-and-git-merge-no-ff | |||
= Repositories = | |||
=== move repo to new server === | |||
<pre class="bash"> | |||
git remote -v # show remote location | |||
git remote set-url origin <URL to my NEW repo location> # change remote url | |||
git push -f origin # push to remote url | |||
git remote -v | |||
</pre> | |||
=== sparse clone (only specific folder) === | |||
<pre class="bash"> | |||
mkdir <repo> | |||
cd <repo> | |||
git init | |||
git remote add -f origin <url> | |||
git config core.sparseCheckout true | |||
echo "some/dir/" >> .git/info/sparse-checkout | |||
git pull origin master | |||
</pre> | |||
= Forks = | |||
=== Syncing fork === | |||
<pre class="bash"> | |||
git clone https://your-fork.git | |||
git remote -v # should show your fork | |||
git remote add upstream https # adding upstream repo | |||
git remote -v # should show your fork as origin and upstream | |||
git fetch upstream # get changes from upstream | |||
git checkout master (or fork-branch) | |||
git merge upstream/master | |||
git add . | |||
git commit -m "sync with upstream" | |||
git push origin master | |||
</pre> | |||
= Undo mistakes = | |||
=== replace file with commited version === | |||
<pre class="bash"> | |||
git checkout file.txt # file gets replaced by repo version | |||
</pre> | |||
=== fix commit message or files === | |||
<pre class="bash"> | |||
git commit -m "Wrong message" | |||
git commit --amend -m "Fixed message" # only do this if you never pushed the wrong commit | |||
</pre> | |||
=== move commit from master to branch === | |||
<pre class="bash"> | |||
git log # get hash from commit you want to cherry pick | |||
git checkout <branch> | |||
git cherry-pick <hash-of-commit> # add commit to branch | |||
git checkout master # if not pushed to remote, | |||
git log # get hash of previous commit | |||
git reset --soft <hash> # resets commit to previous hash, but will keep changes in staging area | |||
git reset (--mixed) <hash> # resets commit to previous hash, will keep changes only in working dir | |||
git reset --hard <hash> # resets commit to previous hash, will delete changes (untracked files will stay) | |||
git clean -df # deletes untracked files from working dir | |||
</pre> | |||
=== undo commit after push === | |||
<pre class="bash"> | |||
git log # get hash of bad commit | |||
git revert <hash> # adds a revert-commit | |||
</pre> | |||
= Configuration = | |||
=== Show config === | |||
<pre class="bash">git config --list</pre> | |||
=== Store credentials === | |||
<pre class="bash">git config credential.helper store</pre> | |||
=== Set username and email === | |||
<pre class="bash"> | |||
git config --global user.email "you@example.com" | |||
git config --global user.name "Your Name" | |||
</pre> | |||
=== Windows - remove old credentials === | |||
<pre class="bash">rundll32.exe keymgr.dll,KRShowKeyMgr</pre> | |||
* | === post-receive hook === | ||
* execute script on main git server, after receiving push: hooks/post-receive | |||
<blockquote> | |||
<pre> | |||
#!/bin/bash | |||
# unset GIT_INDEX_FILE # not needed for post-receive? | |||
git --work-tree=/srv/targetfolder --git-dir=/home/demo/proj/.git checkout -f | |||
</pre> | |||
</blockquote> | |||
::or | |||
<blockquote> | <blockquote> | ||
<pre> | <pre> | ||
git | #!/bin/bash | ||
while read oldrev newrev ref | |||
do | |||
if [[ $ref =~ .*/master$ ]]; | |||
then | |||
echo "Master ref received. Deploying master branch to production..." | |||
git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f | |||
else | |||
echo "Ref $ref successfully received. Doing nothing: only the master branch may be deployed on this server." | |||
fi | |||
done | |||
</pre> | </pre> | ||
</blockquote> | </blockquote> | ||
:* make executable | |||
* | |||
<blockquote> | <blockquote> | ||
<pre> | <pre> | ||
chmod +x post-receive | |||
</pre> | </pre> | ||
</blockquote> | </blockquote> | ||
= Speed-up = | |||
<pre class="bash"> | |||
# alias 'acp' = add+commit+push | |||
git config --global alias.acp '!f() { git add . && git commit -m "$@" && git push; }; f' | |||
git acp "this is my commit comment" | |||
</pre> | |||
= Links = | |||
* https://ohmygit.org/ | |||
* https://nvie.com/posts/a-successful-git-branching-model/ | |||
* https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps | |||
* https://gist.github.com/noelboss/3fe13927025b89757f8fb12e9066f2fa | |||
* https://gist.github.com/thomasfr/9691385 | |||
== | = Other = | ||
== Special features == | == Special features == | ||
* auto-commit when file changes | * auto-commit when file changes | ||
Line 78: | Line 360: | ||
</blockquote> | </blockquote> | ||
::or | ::or | ||
:* etckeeper or [https://github.com/gitwatch/gitwatch gitwatch] | |||
etckeeper | |||
[[Category: | [[Category:Programming]] |
Latest revision as of 15:13, 28 September 2024
Quick Cheat Sheet |
git config credential.helper store git config user.email "email@example.com" git config user.name "username" git log --graph --oneline |
Command Overview
git init # standard git init --bare # bare (server) repo without working directory git clone https://gerrit.wikimedia.org/r/p/mediawiki/core.git git clone ssh://user@server/srv/git/git-repo.git git pull # (= git fetch && git merge) git fetch # get updates from remote, safe operation git fetch --all # git fetch upstream git merge # merges those updates into working dir git status # show changed files (working dir & staging area) git diff # show changes in working dir git diff --cached # show changes in staging area git log git add . git add -A # all git commit -m "Commit message" git commit -a # includes add (modified and deleted files, but not new files) git commit -am "msg" git commit --amend -m "Fixed" # only do, if not pushed. Amend commit over last wrong commit git reset --soft git reset (--mixed) git reset --hard git reset --hard origin/master git clean -df git push git push origin master git push origin --delete <branch> # delete branch from origin git push -f origin # force push git push -u origin <branch> # push new local branch to origin git checkout master git checkout file.txt git log git log --all --decorate --oneline --graph git branch # list branches git branch -a # list local & remote branches git branch --merged # list branches that have been merged git branch <branch> # create new branch git branch -d <branch> # delete git merge <branch> # to be executed on the branch that stays (usually master) git merge <branch> --no-ff # no fast forward, always keep branch in history git merge upstream/master # merge upstream master into own fork git merge --abort git rebase master # to be executed on the branch that is to be rebased (e.g. feature) git rebase --continue git rebase --abort git rebase -i # interactive git rebase -i HEAD~3 # interactive mode for 3 most recent commits git revert <hash> # revert commit (changes from <hash> will be removed) git config --list # show current git config git remote -v # show remote urls git remote set-url origin https.. # set origin url git remote add upstream https://.. # add upstream remote url
# Merge A---B---C topic A---B---C topic / / \ D---E---F---G master D---E---F---G---H master # Rebase A---B---C topic A'--B'--C' topic / / D---E---F---G master D---E---F---G master
Basics
Create repository
git init # standard git init --bare # bare (server) repo without working directoryInitial checkout of remote repository
git clone https://gerrit.wikimedia.org/r/p/mediawiki/core.git git clone ssh://user@server/srv/git/git-repo.gitGet latest updates from server
git pull # (= git fetch && git merge) git fetch # get updates from remote, safe operation git merge # merges those updates into working dirChange files and commit
- show changed files
git status # show changed files (working dir & staging area) git diff # show changes in working dir git diff --cached # show changes in staging area git diff --cached --name-only git diff --name-status
- add files
git add . git add -A # all
- commit changes
git commit -m "Commit message" git commit -a # includes add git commit -am.
- send changes to server
git push.gitignore files
*.log filename.txt subfolder/*
Staging
<------------------------ checkout --------------------- Working Directory -stage-> Staging Area -commit-> Repository
git add . # add all files to staging area git status # show staged & unstaged(untracked) files git reset # unstage all files
Branches
git branch # list local branches git branch -a # list local & remote branches git branch --merged # list branches that have been merged git branch <new-branch-name> # create new branch (from the current commit)
hard reset to specific branch
git fetch --all git reset --hard origin/branchname
switch to branch
git switch <new-branch-name> git commit ... some-stuff git switch master
merge feature branch into master
git checkout master git merge <new-branch-name> (--no-ff) # no fast forward: create merge commit git diff git commit -a
rebase branch onto latest master
git checkout master # go to master git pull # check if new updates in origin # ...master has proceeded... git checkout <branch> # go to <branch> git rebase master # Rebase pulls the "old" branch up to the latest master position # now proceed with merge or rebase to get the code onto master
delete branch
git branch -d <branch-name> # local git push origin --delete <branch-name> # remote
Repositories
move repo to new server
git remote -v # show remote location git remote set-url origin <URL to my NEW repo location> # change remote url git push -f origin # push to remote url git remote -v
sparse clone (only specific folder)
mkdir <repo> cd <repo> git init git remote add -f origin <url> git config core.sparseCheckout true echo "some/dir/" >> .git/info/sparse-checkout git pull origin master
Forks
Syncing fork
git clone https://your-fork.git git remote -v # should show your fork git remote add upstream https # adding upstream repo git remote -v # should show your fork as origin and upstream git fetch upstream # get changes from upstream git checkout master (or fork-branch) git merge upstream/master git add . git commit -m "sync with upstream" git push origin master
Undo mistakes
replace file with commited version
git checkout file.txt # file gets replaced by repo version
fix commit message or files
git commit -m "Wrong message" git commit --amend -m "Fixed message" # only do this if you never pushed the wrong commit
move commit from master to branch
git log # get hash from commit you want to cherry pick git checkout <branch> git cherry-pick <hash-of-commit> # add commit to branch git checkout master # if not pushed to remote, git log # get hash of previous commit git reset --soft <hash> # resets commit to previous hash, but will keep changes in staging area git reset (--mixed) <hash> # resets commit to previous hash, will keep changes only in working dir git reset --hard <hash> # resets commit to previous hash, will delete changes (untracked files will stay) git clean -df # deletes untracked files from working dir
undo commit after push
git log # get hash of bad commit git revert <hash> # adds a revert-commit
Configuration
Show config
git config --list
Store credentials
git config credential.helper store
Set username and email
git config --global user.email "you@example.com" git config --global user.name "Your Name"
Windows - remove old credentials
rundll32.exe keymgr.dll,KRShowKeyMgr
post-receive hook
- execute script on main git server, after receiving push: hooks/post-receive
#!/bin/bash # unset GIT_INDEX_FILE # not needed for post-receive? git --work-tree=/srv/targetfolder --git-dir=/home/demo/proj/.git checkout -f
- or
#!/bin/bash while read oldrev newrev ref do if [[ $ref =~ .*/master$ ]]; then echo "Master ref received. Deploying master branch to production..." git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f else echo "Ref $ref successfully received. Doing nothing: only the master branch may be deployed on this server." fi done
- make executable
chmod +x post-receive
Speed-up
# alias 'acp' = add+commit+push git config --global alias.acp '!f() { git add . && git commit -m "$@" && git push; }; f' git acp "this is my commit comment"
Links
- https://ohmygit.org/
- https://nvie.com/posts/a-successful-git-branching-model/
- https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps
- https://gist.github.com/noelboss/3fe13927025b89757f8fb12e9066f2fa
- https://gist.github.com/thomasfr/9691385
Other
Special features
- auto-commit when file changes
inotifywait -q -m -e CLOSE_WRITE --format="git commit -a -m 'autocommit on change' %w" file.txt | sh
- or
while true; do inotifywait -qq -e CLOSE_WRITE ~/.calendar/calendar cd ~/.calendar; git commit -a -m 'autocommit on change' done # inotify "-r" for recursive
- or
- etckeeper or gitwatch