X-Git-Url: https://git.phdru.name/?a=blobdiff_plain;f=pep-git.txt;h=51701c9935fcb673cade2b5a89fc8ecfa0548fd4;hb=bb91e98e10aabd0b8ae3972e10333c68e5ca803d;hp=402dac8907b5731166e4ae04ba822737a5d08808;hpb=d97d98eb25a34050380fa73f58752c2e2af5c207;p=git-wiki.git diff --git a/pep-git.txt b/pep-git.txt index 402dac8..51701c9 100644 --- a/pep-git.txt +++ b/pep-git.txt @@ -326,6 +326,11 @@ from it) you do that in two steps using two repositories: you push from the workstation to a bare repo on the remote host, ssh to the remote host and pull from the bare repo to a non-bare deployment repo. +That changed in git 2.3, but see `the blog post +`_ +for caveats; in 2.4 the push-to-deploy feature was `further improved +`_. + Tags '''' @@ -440,16 +445,81 @@ about unstaging and other undo tricks. git reflog: reference log ------------------------- +Removing commits with ``git reset`` or moving the head of a branch +sounds dangerous and it is. But there is a way to undo: another +reset back to the original commit. Git doesn't remove commits +immediately; unreferenced commits (in git terminology they are called +"dangling commits") stay in the database for some time (default is two +weeks) so you can reset back to it or create a new branch pointing to +the original commit. + +For every move of a branch's head - with ``git commit``, ``git +checkout``, ``git fetch``, ``git pull``, ``git rebase``, ``git reset`` +and so on - git stores a reference log (reflog for short). For every +move git stores where the head was. Command ``git reflog`` can be used +to view (and manipulate) the log. + +In addition to the moves of the head of every branch git stores the +moves of the HEAD - a symbolic reference that (usually) names the +current branch. HEAD is changed with ``git checkout $BRANCH``. + +By default ``git reflog`` shows the moves of the HEAD, i.e. the +command is equivalent to ``git reflog HEAD``. To show the moves of the +head of a branch use the command ``git reflog $BRANCH``. + +So to undo a ``git reset`` lookup the original commit in ``git +reflog``, verify it with ``git show`` or ``git log`` and run ``git +reset $COMMIT_ID``. Git stores the move of the branch's head in +reflog, so you can undo that undo later again. + +In a more complex situation you'd want to move some commits along with +resetting the head of the branch. Cherry-pick them to the new branch. +For example, if you want to reset the branch ``v2`` back to the +original commit but preserve two commits created in the current branch +do something like:: + + $ git branch save-v2 # create a new branch saving v2 + $ git reflog # find the original place of v2 + $ git reset $COMMIT_ID + $ git cherry-pick save-v2~ save-v2 + $ git branch -D save-v2 # remove temporary branch + git revert: revert a commit --------------------------- -How to undo a merge -https://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.html +``git revert`` reverts a commit or commits, that is, it creates a new +commit or commits that reverts the effects of the given commits. It's +the only way to undo published commits (``git commit --amend``, ``git +rebase`` and ``git reset`` change the branch in non-fast-forwardable +ways so they should only be used for non-pushed commits.) + +There is a problem with reverting a merge commit. ``git revert`` can +undo the code created by the merge commit but it cannot undo the fact +of merge. See the discussion `How to revert a faulty merge +`_. One thing that cannot be undone ------------------------------- -"Commit early, commit often". +Whatever you undo, there is one thing that cannot be undone - +overwritten uncommitted changes. Uncommitted changes don't belong to +git so git cannot help preserving them. + +Most of the time git warns you when you're going to execute a command +that overwrites uncommitted changes. Git warns you when you try to +switch branches with ``git checkout``. It warns you when you're going +to rebase with non-clean working tree. It refuses to pull new commits +over non-committed files. + +But there are commands that do exactly that - overwrite files in the +working tree. Commands like ``git checkout $PATHs`` or ``git reset +--hard`` silently overwrite files including your uncommitted changes. + +With that in mind you can understand the stance "commit early, commit +often". Commit as often as possible. Commit on every save in your +editor or IDE. You can edit your commits before pushing - change, +reorder, combine, remove. But save your changes in git database, +either commit changes or at least stash them with ``git stash``. Merge or rebase? @@ -520,10 +590,15 @@ Git has a builtin merge strategy for what Python core developers call $ git merge -s ours v1 # null-merge v1 into v2 -ReReRe -====== +Advanced configuration +====================== -https://git-scm.com/book/en/Git-Tools-Rerere +Line endings +------------ + +Git has builtin mechanisms to handle line endings. + +TODO: describe crlf configuration and .gitattributes. Advanced topics @@ -540,15 +615,10 @@ Staging area aka index is a distinguishing feature of git. See Wiki. -Advanced configuration -====================== - -Line endings ------------- - -Git has builtin mechanisms to handle line endings. +ReReRe +====== -TODO: describe crlf configuration and .gitattributes. +https://git-scm.com/book/en/Git-Tools-Rerere Database maintenance