summaryrefslogtreecommitdiff
path: root/doc/topics/git/numerous_undo_possibilities_in_git/index.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/topics/git/numerous_undo_possibilities_in_git/index.md')
-rw-r--r--doc/topics/git/numerous_undo_possibilities_in_git/index.md218
1 files changed, 93 insertions, 125 deletions
diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/index.md b/doc/topics/git/numerous_undo_possibilities_in_git/index.md
index b151ddfff71..6de62897041 100644
--- a/doc/topics/git/numerous_undo_possibilities_in_git/index.md
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/index.md
@@ -36,7 +36,7 @@ You can undo changes at any point in this workflow:
- [When you're working locally](#undo-local-changes) and haven't yet pushed to a remote repository.
- When you have already pushed to a remote repository and you want to:
- [Keep the history intact](#undo-remote-changes-without-changing-history) (preferred).
- - [Change the history](#undo-remote-changes-with-modifying-history) (requires
+ - [Change the history](#undo-remote-changes-while-changing-history) (requires
coordination with team and force pushes).
## Undo local changes
@@ -139,6 +139,12 @@ If you want to change to another branch, you can use [`git stash`](https://www.g
1. Commit, push, and test.
1. Return to the branch where you want to resume your changes.
1. Use `git stash list` to list all previously stashed commits.
+
+ ```shell
+ stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation
+ stash@{1}: On master: 9cc0589... Add git-stash
+ ```
+
1. Run a version of `git stash`:
- Use `git stash pop` to redo previously stashed changes and remove them from stashed list.
@@ -146,7 +152,7 @@ If you want to change to another branch, you can use [`git stash`](https://www.g
## Undo committed local changes
-When you commit to your local repository (`git commit`), the version control system records
+When you commit to your local repository (`git commit`), Git records
your changes. Because you did not push to a remote repository yet, your changes are
not public (or shared with other developers). At this point, you can undo your changes.
@@ -212,64 +218,53 @@ which clashes with what other developers have locally.
### Undo staged local changes with history modification
-You can rewrite history in Git, but you should avoid it, because it can cause problems
-when multiple developers are contributing to the same codebase.
-
-There is one command for history modification and that is `git rebase`. Command
-provides interactive mode (`-i` flag) which enables you to:
+The following tasks rewrite Git history.
-- **reword** commit messages (there is also `git commit --amend` for editing
- last commit message).
-- **edit** the commit content (changes introduced by commit) and message.
-- **squash** multiple commits into a single one, and have a custom or aggregated
- commit message.
-- **drop** commits - delete them.
-- and few more options.
+#### Delete a specific commit
-Let us check few examples. Again there are commits `A-B-C-D` where you want to
-delete commit `B`.
+You can delete a specific commit. For example, if you have
+commits `A-B-C-D` and you want to delete commit `B`.
-- Rebase the range from current commit D to A:
+1. Rebase the range from current commit `D` to `B`:
- ```shell
- git rebase -i A
- ```
+ ```shell
+ git rebase -i A
+ ```
-- Command opens your favorite editor where you write `drop` in front of commit
- `B`, but you leave default `pick` with all other commits. Save and exit the
- editor to perform a rebase. Remember: if you want to cancel delete whole
- file content before saving and exiting the editor
+ A list of commits is displayed in your editor.
-In case you want to modify something introduced in commit `B`.
+1. In front of commit `B`, replace `pick` with `drop`.
+1. Leave the default, `pick`, for all other commits.
+1. Save and exit the editor.
-- Rebase the range from current commit D to A:
+#### Modify a specific commit
- ```shell
- git rebase -i A
- ```
+You can modify a specific commit. For example, if you have
+commits `A-B-C-D` and you want to modify something introduced in commit `B`.
-- Command opens your favorite text editor where you write `edit` in front of commit
- `B`, but leave default `pick` with all other commits. Save and exit the editor to
- perform a rebase.
+1. Rebase the range from current commit `D` to `B`:
-- Now do your edits and commit changes:
+ ```shell
+ git rebase -i A
+ ```
- ```shell
- git commit -a
- ```
+ A list of commits is displayed in your editor.
+
+1. In front of commit `B`, replace `pick` with `edit`.
+1. Leave the default, `pick`, for all other commits.
+1. Save and exit the editor.
+1. Open the file in your editor, make your edits, and commit the changes:
-You can find some more examples in the section explaining
-[how to modify history](#how-modifying-history-is-done).
+ ```shell
+ git commit -a
+ ```
### Redoing the undo
-Sometimes you realize that the changes you undid were useful and you want them
-back. Well because of first paragraph you are in luck. Command `git reflog`
-enables you to *recall* detached local commits by referencing or applying them
-via commit ID. Although, do not expect to see really old commits in reflog, because
-Git regularly [cleans the commits which are *unreachable* by branches or tags](https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery).
+You can recall previous local commits. However, not all previous commits are available, because
+Git regularly [cleans the commits that are unreachable by branches or tags](https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery).
-To view repository history and to track older commits you can use below command:
+To view repository history and track prior commits, run `git reflog show`. For example:
```shell
$ git reflog show
@@ -287,89 +282,64 @@ eb37e74 HEAD@{6}: rebase -i (pick): Commit C
6e43d59 HEAD@{16}: commit: Commit B
```
-Output of command shows repository history. In first column there is commit ID,
-in following column, number next to `HEAD` indicates how many commits ago something
-was made, after that indicator of action that was made (commit, rebase, merge, ...)
-and then on end description of that action.
+This output shows the repository history, including:
-## Undo remote changes without changing history
+- The commit SHA.
+- How many `HEAD`-changing actions ago the commit was made (`HEAD@{12}` was 12 `HEAD`-changing actions ago).
+- The action that was taken, for example: commit, rebase, merge.
+- A description of the action that changed `HEAD`.
-This topic is roughly same as modifying committed local changes without modifying
-history. **It should be the preferred way of undoing changes on any remote repository
-or public branch.** Keep in mind that branching is the best solution when you want
-to retain the history of faulty development, yet start anew from certain point.
+## Undo remote changes without changing history
-Branching
-enables you to include the existing changes in new development (by merging) and
-it also provides a clear timeline and development structure.
+To undo changes in the remote repository, you can create a new commit with the changes you
+want to undo. You should follow this process, which preserves the history and
+provides a clear timeline and development structure. However, you
+only need this procedure if your work was merged into a branch that
+other developers use as the base for their work.
![Use revert to keep branch flowing](img/revert.png)
-If you want to revert changes introduced in certain `commit-id`, you can
-revert that `commit-id` (swap additions and deletions) in newly created commit:
-You can do this with
+To revert changes introduced in a specific commit `B`:
```shell
-git revert commit-id
+git revert B
```
-or creating a new branch:
-
-```shell
-git checkout commit-id
-git checkout -b new-path-of-feature
-```
+## Undo remote changes while changing history
-## Undo remote changes with modifying history
+You can undo remote changes and change history.
-This is useful when you want to *hide* certain things - like secret keys,
-passwords, and SSH keys. It is and should not be used to hide mistakes, as
-it makes it harder to debug in case there are some other bugs. The main
-reason for this is that you loose the real development progress. Keep in
-mind that, even with modified history, commits are just detached and can still be
-accessed through commit ID - at least until all repositories perform
-the automated cleanup of detached commits.
+Even with an updated history, old commits can still be
+accessed by commit SHA. This is the case at least until all the automated cleanup
+of detached commits is performed, or a cleanup is run manually. Even the cleanup might not remove old commits if there are still refs pointing to them.
![Modifying history causes problems on remote branch](img/rebase_reset.png)
-### Where modifying history is generally acceptable
+### When changing history is acceptable
-Modified history breaks the development chain of other developers, as changed
-history does not have matching commit IDs. For that reason it should not be
-used on any public branch or on branch that might be used by other developers.
-When contributing to big open source repositories (for example, [GitLab](https://gitlab.com/gitlab-org/gitlab/blob/master/CONTRIBUTING.md#contribution-acceptance-criteria)
-itself), it is acceptable to squash commits into a single one, to present a
-nicer history of your contribution.
+You should not change the history when you're working in a public branch
+or a branch that might be used by other developers.
-Keep in mind that this also removes the comments attached to certain commits
-in merge requests, so if you need to retain traceability in GitLab, then
-modifying history is not acceptable.
+When you contribute to large open source repositories, like [GitLab](https://gitlab.com/gitlab-org/gitlab),
+you can squash your commits into a single one.
-A feature branch of a merge request is a public branch and might be used by
-other developers, but project process and rules might allow or require
-you to use `git rebase` (command that changes history) to reduce number of
-displayed commits on target branch after reviews are done (for example
-GitLab). There is a `git merge --squash` command which does exactly that
-(squashes commits on feature-branch to a single commit on target branch
-at merge).
+To squash commits on a feature branch to a single commit on a target branch
+at merge, use `git merge --squash`.
NOTE:
-Never modify the commit history of `master` or shared branch.
+Never modify the commit history of your [default branch](../../../user/project/repository/branches/default.md) or shared branch.
-### How modifying history is done
+### How to change history
-After you know what you want to modify (how far in history or how which range of
-old commits), use `git rebase -i commit-id`. This command displays all the commits from
-current version to chosen commit ID and allow modification, squashing, deletion
-of that commits.
+A feature branch of a merge request is a public branch and might be used by
+other developers. However, the project rules might require
+you to use `git rebase` to reduce the number of
+displayed commits on target branch after reviews are done.
-```shell
-$ git rebase -i commit1-id..commit3-id
-pick <commit1-id> <commit1-commit-message>
-pick <commit2-id> <commit2-commit-message>
-pick <commit3-id> <commit3-commit-message>
+You can modify history by using `git rebase -i`. Use this command to modify, squash,
+and delete commits.
-# Rebase commit1-id..commit3-id onto <commit4-id> (3 command(s))
+```shell
#
# Commands:
# p, pick = use commit
@@ -382,50 +352,48 @@ pick <commit3-id> <commit3-commit-message>
#
# These lines can be re-ordered; they are executed from top to bottom.
#
-# If you remove a line here THAT COMMIT WILL BE LOST.
+# If you remove a line THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
-# Note that empty commits are commented out
+# Empty commits are commented out
```
NOTE:
-The comment from the output clearly states that, if
-you decide to abort, don't just close your editor (as that
-modifies history), but remove all uncommented lines and save.
+If you decide to stop a rebase, do not close your editor.
+Instead, remove all uncommented lines and save.
-Use `git rebase` carefully on
-shared and remote branches, but rest assured: nothing is broken until
-you push back to the remote repository (so you can freely explore the
-different outcomes locally).
+Use `git rebase` carefully on shared and remote branches.
+Experiment locally before you push to the remote repository.
```shell
# Modify history from commit-id to HEAD (current commit)
git rebase -i commit-id
```
-### Deleting sensitive information from commits
+### Delete sensitive information from commits
+
+You can use Git to delete sensitive information from your past commits. However,
+history is modified in the process.
+
+To rewrite history with
+[certain filters](https://git-scm.com/docs/git-filter-branch#_options),
+run `git filter-branch`.
-Git also enables you to delete sensitive information from your past commits and
-it does modify history in the progress. That is why we have included it in this
-section and not as a standalone topic. To do so, you should run the
-`git filter-branch`, which enables you to rewrite history with
-[certain filters](https://git-scm.com/docs/git-filter-branch#_options).
-This command uses rebase to modify history and if you want to remove certain
-file from history altogether use:
+To remove a file from the history altogether use:
```shell
git filter-branch --tree-filter 'rm filename' HEAD
```
-Because `git filter-branch` command might be slow on big repositories, there are
-tools that can use some of Git specifics to enable faster execution of common
-tasks (which is exactly what removing sensitive information file is about).
+The `git filter-branch` command might be slow on large repositories.
+Tools are available to execute Git commands more quickly.
An alternative is the open source community-maintained tool [BFG](https://rtyley.github.io/bfg-repo-cleaner/).
-Keep in mind that these tools are faster because they do not provide the same
+These tools are faster because they do not provide the same
feature set as `git filter-branch` does, but focus on specific use cases.
-Refer [Reduce repository size](../../../user/project/repository/reducing_the_repo_size_using_git.md) page to know more about purging files from repository history & GitLab storage.
+Refer to [Reduce repository size](../../../user/project/repository/reducing_the_repo_size_using_git.md) to
+learn more about purging files from repository history and GitLab storage.
<!-- ## Troubleshooting