Both sides previous revision
Previous revision
Next revision
|
Previous revision
|
software:git [2011/02/22 08:47] cyril git bisect |
software:git [2024/11/06 22:20] (current) cyril [Editing commits] |
changed = cyan bold | changed = cyan bold |
untracked = red bold | untracked = red bold |
| [alias] |
| d = diff -w --color-words |
</code> | </code> |
| * More aliases, in your shell configuration file (eg .zshenv):<code> |
| alias gitk='gitk --color-words' |
| </code> |
| |
| ==== General tips ==== |
| * ''<commit-hash>'' is the hash of a commit, but it can also be just the few first characters as long as it is not ambiguous. |
| |
| |
==== Local repository management ==== | ==== Local repository management ==== |
* % **''git add [-p] <files|dirs>''** (or just ''git add .'' for all files) : add new or modified files to the index (-p to select chunks to include, y/n/s = yes/no/split) | * % **''git add [-p] <files|dirs>''** (or just ''git add .'' for all files) : add new or modified files to the index (-p to select chunks to include, y/n/s = yes/no/split) |
* % **''git commit [-m <msg>]''** : commit the changes of the index to the repository | * % **''git commit [-m <msg>]''** : commit the changes of the index to the repository |
* % **''git commit -a''** : commit the changes of the working files to the repository | * % **''git commit -a''** : commit the changes of the working files to the repository (does a "git add" of all the working files before "git commit") |
* % **''git tag -a <tag-name> [-m <msg>]''** : add a tag | * % **''git tag -a <tag-name> [-m <msg>]''** : add a tag |
* % **''git reset --hard [<commit-hash>]''** : restore the working files to the latest commit, or given commit | * % **''git reset --hard [<commit-hash>]''** : restore the working files and index to the latest commit [or given commit] (everything after is lost) |
* % **''git revert <commit-hash>''** : revert the given commit (<commit> can be just the beginning of its hashcode) | * % **''git revert <commit-hash>''** : create a new commit that revertr the given commit |
* % **''git checkout <file>''** : restore a working file to the last commited version | * % **''git checkout <file>''** : restore a working file to the last commited version |
* % **''git checkout <commit>''** : switch working files to the commit version, use **''git checkout master''** to go back to head | * % **''git checkout <commit-hash>''** : switch all working files to the given commit version, use **''git checkout master''** to go back to head |
| |
==== Branches ==== | ==== Branches ==== |
* % **''git checkout <branch-name>''** : switch to the given branch | * % **''git checkout <branch-name>''** : switch to the given branch |
* % **''git branch [-a]''** : list available branches (''-a'' to list all branches, including distant branches) | * % **''git branch [-a]''** : list available branches (''-a'' to list all branches, including distant branches) |
* % **''git branch -D <branch-name>''** : delete the given branch | * % **''git branch -D <branch-name>''** : delete the given branch (force even if not fully merged, -d otherwise) |
* % **''git merge <branch-name>''** : merge current branch with the given branch | * % **''git merge <branch-name>''** : merge current branch with the given branch |
* % **''git cherry-pick <commit-hash>''** : apply the changes introduced by a given commit to the current branch | * % **''git rebase <branch-name>''** : rebase the current branch on top of the given branch (if you have to resolve conflicts, do "''git add .''" and "''git rebase --continue''" once you resolved conflicts for a commit) |
* % **''git rebase <branch-name>''** : rebase the branch on top of the given branch, in order to merge the branch commits that were done after the branch was started (if you have to resolve conflicts, do "''git add .''" and "''git rebase --continue''" once you resolved conflicts for a commit) | * % **''git cherry-pick <commit-hash>''** : apply the changes introduced by a given commit to the current branch (ie import the commit) |
| |
==== Collaborative repository management ==== | ==== Collaborative repository management ==== |
* % **''git clone <repo-addr>''** : copy the distant repository (<repo-addr> can be "http://<repo>" or "ssh://<user>@<repo>") | * % **''git clone <repo-addr>''** : copy the distant repository (<repo-addr> can be "http://<repo>" or "ssh://<user>@<repo>") |
* % **''git pull [<repo-addr>]''** : update from the distant repository (fetch and merge) | * % **''git pull [<repo-addr>]''** : update from the distant repository (fetch and merge) |
* % **''git pull --rebase [<repo-addr>]''** : instead of merging your pending commits with the new ones on master, rebase your pending commits on the top of master ; it creates a cleaner tree and avoids artificial "merged" commits. | * % **''git pull --rebase [<repo-addr>]''** : instead of merging your pending commits with the new ones on master, rebase your pending commits on the top of master (fetch and rebase) ; it creates a cleaner tree and avoids artificial "merged" commits. |
* % **''git stash ; git pull|merge|rebase ; git stash apply''**: to pull or merge or rebase when you have non-commited modifications ; store the modifs, pull or rebase, apply the modifs back | * % **''git stash ; git pull|merge|rebase ; git stash pop''**: to pull or merge or rebase when you have non-commited modifications ; store the modifs, pull or rebase, apply the modifs back. |
* % **''git push <repo-addr>''** : send to the distant repository (needs ssh clone and write permissions) | * % **''git push <repo-addr>''** : send to the distant repository (needs ssh clone and write permissions) |
* % **''git push origin <local-branch>[:<dist-branch>]''** : push a local branch into a new distant branch | * % **''git push origin <local-branch>[:<dist-branch>]''** : push a local branch into a new distant branch |
| * % **''git push origin <commit-hash>[:<dist-branch>]''** : push until this commit in the given branch |
* % **''git branch <local-branch> origin/<dist-branch>''** or **''git checkout -b <local-branch> -t origin/<dist-branch>''** : create a local branch to track a distant branch (so that you can pull/push with the distant branch) | * % **''git branch <local-branch> origin/<dist-branch>''** or **''git checkout -b <local-branch> -t origin/<dist-branch>''** : create a local branch to track a distant branch (so that you can pull/push with the distant branch) |
| * % **''git push -f origin <commit-hash>:<dist-branch>''** (after setting temporarily denyNonFastforwards to false in distant git config file) : cancel a previous push, if no one pulled meanwhile |
| |
==== Info ==== | ==== Info ==== |
* % **''git format-patch -M <first-commit-hash> [<last-commit-hash>]''** : create git patches between two arbitrary commits | * % **''git format-patch -M <first-commit-hash> [<last-commit-hash>]''** : create git patches between two arbitrary commits |
* % **''git am <patch>''** : apply a commit created with "git format-patch" | * % **''git am <patch>''** : apply a commit created with "git format-patch" |
| |
| Stats: |
| * ''.mailmap'' file: to unify same authors with different name spelling or email address. |
| * % **''git shortlog -s -n --no-merges''**: number of commits by author. |
| * [[http://gitstats.sourceforge.net/|gitstats project]]: generates stats in html. |
| * [[http://git-wt-commit.rubyforge.org/git-rank-contributors|git-rank-contributors script]]: number of lines of diff by author. You can add ''-w --pretty=format:"commit %H%nAuthor: %aN%nDate: %ad"'' options to the git log command, in order to ignore blank changes and use .mailmap file. |
| |
| ==== Undoing ==== |
| * ''git --reset'': ''git reset HEAD@{1}'' |
| |
===== Howtos ===== | ===== Howtos ===== |
cd <repo-location> | cd <repo-location> |
mkdir <repo-name> && cd <repo-name> | mkdir <repo-name> && cd <repo-name> |
| chgrp <group> . && chmod a+s . # optional, if you need to change the group |
git --bare init [--shared=false|group|all|0xxx] | git --bare init [--shared=false|group|all|0xxx] |
echo "Project-Title\nExtensive description" > description | echo "Project-Title\nExtensive description" > description |
</code> | </code> |
| |
Create the local repository, if not already existing (on your machine): | If you want to send emails after each commit, check [[git#setting_up_email_hooks|this section]]. |
<code> | |
cd <folder-to-versionize> | |
git init | |
git add . | |
git commit | |
</code> | |
| |
Associate repositories together and push (in local repository): | * First case, you already have a local repository, then you need to associate it to the remote repository and push (in local repository):<code> |
<code> | |
git remote add origin ssh://<username>@<server>/home/<username>/<repo-location>/<repo-name> | git remote add origin ssh://<username>@<server>/home/<username>/<repo-location>/<repo-name> |
git fetch origin | git fetch origin |
git config branch.master.remote origin | git config branch.master.remote origin |
git config branch.master.merge refs/heads/master | git config branch.master.merge refs/heads/master |
| git push origin master |
| </code> |
| |
| * Second case, if you don't have a local repository yet you just have to clone it:<code> |
| git clone ssh://<username>@<server>/home/<username>/<repo-location>/<repo-name> |
| ... |
git push origin master | git push origin master |
</code> | </code> |
<code> | <code> |
git rebase -i <latest-commit-to-keep-unchanged> | git rebase -i <latest-commit-to-keep-unchanged> |
# set "reword" if you want to change message | # set "r" (reword) if you want to change message |
# set "edit" if you want to amend the commit (git commit --amend; git rebase --continue) | # set "e" (edit) if you want to amend the commit (git commit --amend; git rebase --continue) |
# set "squash" if you want to merge with the previous commit | # set "s" (squash) if you want to merge with the previous commit and merging or editing the commit message |
| # set "f" (fixup) if you want to merge with the previous commit without interaction |
# you can even reorder the commits! | # you can even reorder the commits! |
</code> | </code> |
| Tips with ''rebase -i'': |
| * If you have a bunch of fixup commits, first move them one by one (i.e. move one, apply, rebase again, move another one, apply, etc), so that if you prefer to abort due to conflicts you don't lose the ones before, and then really mark them "f" (nothing can go wrong afterwards) |
| * If you are just moving and merging some fixup commits, you may want to check that the end result is identical, by making a copy and then performing a diff. |
| * If you move a fixup commit up and keep getting conflicts after its initial position, it means that you made a mistake in the conflict resolution |
| |
| Change author or date: use ''rebase -i'', chose "edit", and commit with: |
| <code> |
| git commit --amend --author "Name <email-address>" --date "$(date -R)" |
| </code> |
| |
| To split a commit: use ''rebase -i'', chose "edit", and reset the index to the commit before, and commit: |
| <code> |
| git reset --mixed @~ |
| git add -p . |
| git commit |
| </code> |
==== Archive generation ==== | ==== Archive generation ==== |
| |
<code> | <code> |
cd <repo-location> | cd <repo-location> |
wget http://crteknologies.free.fr/wiki/lib/exe/fetch.php/software:git:post-receive.txt -O hooks/post-receive | wget http://crteknologies.fr/wiki/lib/exe/fetch.php/software:git:post-receive.txt -O hooks/post-receive |
chmod a+x hooks/post-receive | chmod a+x hooks/post-receive |
git config --add hooks.mailinglist "<email1> [<email2>...]" | git config --add hooks.mailinglist "<email1> [<email2>...]" |
| |
[[http://www.dmo.ca/blog/20080307124544/]] | [[http://www.dmo.ca/blog/20080307124544/]] |
| |
| ==== Recovery ==== |
| |
| For finding a lost commit you can use "git reflog". |
| |
| For finding a lost stash (eg "git stash drop") or file (eg "git rm"), you can try "git fsck --full", and then use "git show" with the hash to see the content of the objects. |
| |
| [[https://github.com/blog/2019-how-to-undo-almost-anything-with-git]] |