diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-19 15:44:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-19 15:44:42 +0000 |
commit | 4555e1b21c365ed8303ffb7a3325d773c9b8bf31 (patch) | |
tree | 5423a1c7516cffe36384133ade12572cf709398d /doc/topics/git | |
parent | e570267f2f6b326480d284e0164a6464ba4081bc (diff) | |
download | gitlab-ce-4555e1b21c365ed8303ffb7a3325d773c9b8bf31.tar.gz |
Add latest changes from gitlab-org/gitlab@13-12-stable-eev13.12.0-rc42
Diffstat (limited to 'doc/topics/git')
-rw-r--r-- | doc/topics/git/bisect.md | 76 | ||||
-rw-r--r-- | doc/topics/git/feature_branching.md | 31 | ||||
-rw-r--r-- | doc/topics/git/getting_started.md | 86 | ||||
-rw-r--r-- | doc/topics/git/git_add.md | 40 | ||||
-rw-r--r-- | doc/topics/git/git_log.md | 60 | ||||
-rw-r--r-- | doc/topics/git/git_rebase.md | 2 | ||||
-rw-r--r-- | doc/topics/git/index.md | 22 | ||||
-rw-r--r-- | doc/topics/git/lfs/img/git-annex-branches.png | bin | 32164 -> 0 bytes | |||
-rw-r--r-- | doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md | 248 | ||||
-rw-r--r-- | doc/topics/git/lfs/migrate_to_git_lfs.md | 1 | ||||
-rw-r--r-- | doc/topics/git/merge_conflicts.md | 69 | ||||
-rw-r--r-- | doc/topics/git/merge_requests.md | 8 | ||||
-rw-r--r-- | doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png | bin | 12744 -> 0 bytes | |||
-rw-r--r-- | doc/topics/git/numerous_undo_possibilities_in_git/index.md | 366 | ||||
-rw-r--r-- | doc/topics/git/rollback_commits.md | 81 | ||||
-rw-r--r-- | doc/topics/git/stash.md | 82 | ||||
-rw-r--r-- | doc/topics/git/subtree.md | 52 | ||||
-rw-r--r-- | doc/topics/git/unstage.md | 33 |
18 files changed, 783 insertions, 474 deletions
diff --git a/doc/topics/git/bisect.md b/doc/topics/git/bisect.md new file mode 100644 index 00000000000..8af77031c93 --- /dev/null +++ b/doc/topics/git/bisect.md @@ -0,0 +1,76 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Bisect + +- Find a commit that introduced a bug +- Works through a process of elimination +- Specify a known good and bad revision to begin + +## Bisect sample workflow + +1. Start the bisect process +1. Enter the bad revision (usually latest commit) +1. Enter a known good revision (commit/branch) +1. Run code to see if bug still exists +1. Tell bisect the result +1. Repeat the previous 2 items until you find the offending commit + +## Setup + +```shell + mkdir bisect-ex + cd bisect-ex + touch index.html + git add -A + git commit -m "starting out" + vi index.html + # Add all good + git add -A + git commit -m "second commit" + vi index.html + # Add all good 2 + git add -A + git commit -m "third commit" + vi index.html +``` + +```shell + # Add all good 3 + git add -A + git commit -m "fourth commit" + vi index.html + # This looks bad + git add -A + git commit -m "fifth commit" + vi index.html + # Really bad + git add -A + git commit -m "sixth commit" + vi index.html + # again just bad + git add -A + git commit -m "seventh commit" +``` + +## Commands + +```shell + git bisect start + # Test your code + git bisect bad + git bisect next + # Say yes to the warning + # Test + git bisect good + # Test + git bisect bad + # Test + git bisect good + # done + git bisect reset +``` diff --git a/doc/topics/git/feature_branching.md b/doc/topics/git/feature_branching.md new file mode 100644 index 00000000000..f6233bddb18 --- /dev/null +++ b/doc/topics/git/feature_branching.md @@ -0,0 +1,31 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Feature branching + +- Efficient parallel workflow for teams +- Develop each feature in a branch +- Keeps changes isolated +- Consider a 1-to-1 link to issues +- Push branches to the server frequently + - Hint: This is a cheap backup for your work-in-progress code + +## Feature branching sample workflow + +1. Create a new feature branch called 'squash_some_bugs' +1. Edit '`bugs.rb`' and remove all the bugs. +1. Commit +1. Push + +```shell +git checkout -b squash_some_bugs +# Edit `bugs.rb` +git status +git add bugs.rb +git commit -m 'Fix some buggy code' +git push origin squash_some_bugs +``` diff --git a/doc/topics/git/getting_started.md b/doc/topics/git/getting_started.md new file mode 100644 index 00000000000..2c3d5fe15de --- /dev/null +++ b/doc/topics/git/getting_started.md @@ -0,0 +1,86 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Getting Started + +## Instantiating Repositories + +- Create a new repository by instantiating it through: + + ```shell + git init + ``` + +- Copy an existing project by cloning the repository through: + + ```shell + git clone <url> + ``` + +## Central Repositories + +- To instantiate a central repository a `--bare` flag is required. +- Bare repositories don't allow file editing or committing changes. +- Create a bare repository with: + + ```shell + git init --bare project-name.git + ``` + +## Instantiate workflow with clone + +1. Create a project in your user namespace. + - Choose to import from **Any Repository by URL** and use <https://gitlab.com/gitlab-org/training-examples.git>. +1. Create a '`Workspace`' directory in your home directory. +1. Clone the '`training-examples`' project. + +```shell +mkdir ~/workspace +cd ~/workspace + +git clone git@gitlab.example.com:<username>/training-examples.git +cd training-examples +``` + +## Git concepts + +**Untracked files** + +New files that Git has not been told to track previously. + +**Working area** + +Files that have been modified but are not committed. + +**Staging area** + +Modified files that have been marked to go in the next commit. + +## Committing Workflow + +1. Edit '`edit_this_file.rb`' in '`training-examples`' +1. See it listed as a changed file (working area) +1. View the differences +1. Stage the file +1. Commit +1. Push the commit to the remote +1. View the Git log + +```shell +# Edit `edit_this_file.rb` +git status +git diff +git add <file> +git commit -m 'My change' +git push origin master +git log +``` + +## Note + +- `git fetch` vs `git pull` +- Pull is `git fetch` + `git merge` diff --git a/doc/topics/git/git_add.md b/doc/topics/git/git_add.md new file mode 100644 index 00000000000..d136b9151bc --- /dev/null +++ b/doc/topics/git/git_add.md @@ -0,0 +1,40 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Git Add + +Adds content to the index or staging area. + +- Adds a list of file: + + ```shell + git add <files> + ``` + +- Adds all files including deleted ones: + + ```shell + git add -A + ``` + +- Add all text files in current dir: + + ```shell + git add *.txt + ``` + +- Add all text file in the project: + + ```shell + git add "*.txt*" + ``` + +- Adds all files in directory: + + ```shell + git add views/layouts/ + ``` diff --git a/doc/topics/git/git_log.md b/doc/topics/git/git_log.md new file mode 100644 index 00000000000..ae4ae69ce76 --- /dev/null +++ b/doc/topics/git/git_log.md @@ -0,0 +1,60 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Git Log + +Git log lists commit history. It allows searching and filtering. + +- Initiate log: + + ```shell + git log + ``` + +- Retrieve set number of records: + + ```shell + git log -n 2 + ``` + +- Search commits by author. Allows user name or a regular expression. + + ```shell + git log --author="user_name" + ``` + +- Search by comment message: + + ```shell + git log --grep="<pattern>" + ``` + +- Search by date: + + ```shell + git log --since=1.month.ago --until=3.weeks.ago + ``` + +## Git Log Workflow + +1. Change to workspace directory +1. Clone the multi runner projects +1. Change to project dir +1. Search by author +1. Search by date +1. Combine + +## Commands + +```shell +cd ~/workspace +git clone git@gitlab.com:gitlab-org/gitlab-runner.git +cd gitlab-runner +git log --author="Travis" +git log --since=1.month.ago --until=3.weeks.ago +git log --since=1.month.ago --until=1.day.ago --author="Travis" +``` diff --git a/doc/topics/git/git_rebase.md b/doc/topics/git/git_rebase.md index bf77ba3272c..78303d24a20 100644 --- a/doc/topics/git/git_rebase.md +++ b/doc/topics/git/git_rebase.md @@ -175,7 +175,7 @@ a macOS's `ZSH` shell, and you want to **squash** all the three commits Note that the steps for editing through the command line can be slightly different depending on your operating system and the shell you're using. -See [Numerous undo possibilities in Git](numerous_undo_possibilities_in_git/index.md#with-history-modification) +See [Numerous undo possibilities in Git](numerous_undo_possibilities_in_git/index.md#undo-staged-local-changes-without-modifying-history) for a deeper look into interactive rebase. ## Force-push diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md index 2c28bdcb0ed..21775044301 100644 --- a/doc/topics/git/index.md +++ b/doc/topics/git/index.md @@ -39,7 +39,7 @@ The following resources can help you get started with Git: - [Squashing commits](../gitlab_flow.md#squashing-commits-with-rebase) - [Squash-and-merge](../../user/project/merge_requests/squash_and_merge.md) - [Signing commits](../../user/project/repository/gpg_signed_commits/index.md) -- [Git stash](../../university/training/topics/stash.md) +- [Git stash](stash.md) - [Git file blame](../../user/project/repository/git_blame.md) - [Git file history](../../user/project/repository/git_history.md) - [Git tags](tags.md) @@ -48,12 +48,27 @@ The following resources can help you get started with Git: The following are resources on version control concepts: -- [Git concepts](../../university/training/user_training.md#git-concepts) - [Why Git is Worth the Learning Curve](https://about.gitlab.com/blog/2017/05/17/learning-curve-is-the-biggest-challenge-developers-face-with-git/) - [The future of SaaS hosted Git repository pricing](https://about.gitlab.com/blog/2016/05/11/git-repository-pricing/) - [Git website on version control](https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control) - [GitLab University presentation about Version Control](https://docs.google.com/presentation/d/16sX7hUrCZyOFbpvnrAFrg6tVO5_yT98IgdAqOmXwBho/edit?usp=sharing) +### Work with Git on the command line + +You can do many Git tasks from the command line: + +- [Bisect](bisect.md). +- [Cherry pick](cherry_picking.md). +- [Feature branching](feature_branching.md). +- [Getting started with Git](getting_started.md). +- [Git add](git_add.md). +- [Git log](git_log.md). +- [Git stash](stash.md). +- [Merge conflicts](merge_conflicts.md). +- [Rollback commits](rollback_commits.md). +- [Subtree](subtree.md). +- [Unstage](unstage.md). + ## Git tips The following resources may help you become more efficient at using Git: @@ -100,6 +115,5 @@ The following relate to Git Large File Storage: - [Migrate an existing Git repository with Git LFS](lfs/migrate_to_git_lfs.md) - [Removing objects from LFS](lfs/index.md#removing-objects-from-lfs) - [GitLab Git LFS user documentation](lfs/index.md) -- [GitLab Git LFS admin documentation](../../administration/lfs/index.md) -- [Git Annex to Git LFS migration guide](lfs/migrate_from_git_annex_to_git_lfs.md) +- [GitLab Git LFS administrator documentation](../../administration/lfs/index.md) - [Towards a production quality open source Git LFS server](https://about.gitlab.com/blog/2015/08/13/towards-a-production-quality-open-source-git-lfs-server/) diff --git a/doc/topics/git/lfs/img/git-annex-branches.png b/doc/topics/git/lfs/img/git-annex-branches.png Binary files differdeleted file mode 100644 index 3d614f68177..00000000000 --- a/doc/topics/git/lfs/img/git-annex-branches.png +++ /dev/null diff --git a/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md b/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md index 3b3f1c0b46f..741b2a78b85 100644 --- a/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md +++ b/doc/topics/git/lfs/migrate_from_git_annex_to_git_lfs.md @@ -1,248 +1,8 @@ --- -stage: Create -group: Source Code -info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments" -type: reference, howto +redirect_to: 'index.md' --- -# Migration guide from Git Annex to Git LFS **(FREE)** +This document was moved to [another location](index.md). -WARNING: -Git Annex support [has been removed](https://gitlab.com/gitlab-org/gitlab/-/issues/1648) in GitLab Enterprise -Edition 9.0 (2017/03/22). - -Both [Git Annex](http://git-annex.branchable.com/) and [Git LFS](https://git-lfs.github.com/) are tools to manage large files in Git. - -## History - -Git Annex [was introduced in GitLab Enterprise Edition 7.8](https://about.gitlab.com/blog/2015/02/17/gitlab-annex-solves-the-problem-of-versioning-large-binaries-with-git/), at a time -where Git LFS didn't yet exist. A few months later, GitLab brought support for -Git LFS in [GitLab 8.2](https://about.gitlab.com/blog/2015/11/23/announcing-git-lfs-support-in-gitlab/) and is available for both Community and -Enterprise editions. - -## Differences between Git Annex and Git LFS - -Some items below are general differences between the two protocols and some are -ones that GitLab developed. - -- Git Annex works only through SSH, whereas Git LFS works both with SSH and HTTPS - (SSH support was added in GitLab 8.12). -- Annex files are stored in a sub-directory of the normal repositories, whereas - LFS files are stored outside of the repositories in a place you can define. -- Git Annex requires a more complex setup, but has much more options than Git - LFS. You can compare the commands each one offers by running `man git-annex` - and `man git-lfs`. -- Annex files cannot be browsed directly in the GitLab interface, whereas LFS - files can. - -## Migration steps - -Git Annex files are stored in a sub-directory of the normal repositories -(`.git/annex/objects`) and LFS files are stored outside of the repositories. -The two aren't compatible as they are using a different scheme. Therefore, the -migration has to be done manually per repository. - -There are basically two steps you need to take in order to migrate from Git -Annex to Git LFS. - -### TL; DR - -If you know what you are doing and want to skip the reading, this is what you -need to do (we assume you have [git-annex enabled](../../../administration/git_annex.md#using-gitlab-git-annex) in your -repository and that you have made backups in case something goes wrong). -Fire up a terminal, navigate to your Git repository and: - -1. Disable `git-annex`: - - ```shell - git annex sync --content - git annex direct - git annex uninit - git annex indirect - ``` - -1. Enable `git-lfs`: - - ```shell - git lfs install - git lfs track <files> - git add . - git commit -m "commit message" - git push - ``` - -### Disabling Git Annex in your repository - -Before changing anything, make sure you have a backup of your repository first. -There are a couple of ways to do that, but you can clone it to another -local path and maybe push it to GitLab if you want a remote backup as well. -A guide on -[how to back up a **git-annex** repository to an external hard drive](https://www.thomas-krenn.com/en/wiki/Git-annex_Repository_on_an_External_Hard_Drive) is also available. - -Because Annex files are stored as objects with symlinks and cannot be directly -modified, we need to first remove those symlinks. - -NOTE: -Make sure the you read about the [`direct` mode](https://git-annex.branchable.com/direct_mode/) as it contains -information that may fit in your use case. The `annex direct` command is -deprecated in Git Annex version 6, so you may need to upgrade your repository -if the server also has Git Annex 6 installed. Read more in the -[Git Annex troubleshooting tips](../../../administration/git_annex.md#troubleshooting-tips) section. - -1. Backup your repository - - ```shell - cd repository - git annex sync --content - cd .. - git clone repository repository-backup - cd repository-backup - git annex get - cd .. - ``` - -1. Use `annex direct`: - - ```shell - cd repository - git annex direct - ``` - - The output should be similar to this: - - ```shell - commit - On branch master - Your branch is up-to-date with 'origin/master'. - nothing to commit, working tree clean - ok - direct debian.iso ok - direct ok - ``` - -1. Disable Git Annex with [`annex uninit`](https://git-annex.branchable.com/git-annex-uninit/): - - ```shell - git annex uninit - ``` - - The output should be similar to this: - - ```shell - unannex debian.iso ok - Deleted branch git-annex (was 2534d2c). - ``` - - This command runs `unannex` on every file in the repository, leaving the original files. - -1. Switch back to `indirect` mode: - - ```shell - git annex indirect - ``` - - The output should be similar to this: - - ```shell - (merging origin/git-annex into git-annex...) - (recording state in git...) - commit (recording state in git...) - - ok - (recording state in git...) - [master fac3194] commit before switching to indirect mode - 1 file changed, 1 deletion(-) - delete mode 120000 alpine-virt-3.4.4-x86_64.iso - ok - indirect ok - ok - ``` - ---- - -At this point, you have two options. Either add, commit and push the files -directly back to GitLab or switch to Git LFS. The LFS switch is described in -the next section. - -### Enabling Git LFS in your repository - -Git LFS is enabled by default on all GitLab products (GitLab CE, GitLab EE, -GitLab.com), therefore, you don't need to do anything server-side. - -1. First, make sure you have `git-lfs` installed locally: - - ```shell - git lfs help - ``` - - If the terminal doesn't prompt you with a full response on `git-lfs` commands, - [install the Git LFS client](https://git-lfs.github.com/) first. - -1. Inside the repository, run the following command to initiate LFS: - - ```shell - git lfs install - ``` - -1. Enable `git-lfs` for the group of files you want to track. You - can track specific files, all files containing the same extension, or an - entire directory: - - ```shell - git lfs track images/01.png # per file - git lfs track **/*.png # per extension - git lfs track images/ # per directory - ``` - - After this, run `git status` to see the `.gitattributes` added - to your repository. It collects all file patterns that you chose to track via - `git-lfs`. - -1. Add the files, commit and push them to GitLab: - - ```shell - git add . - git commit -m "commit message" - git push - ``` - - If your remote is set up with HTTP, you are asked to enter your login - credentials. If you have [2FA enabled](../../../user/profile/account/two_factor_authentication.md), make sure to use a - [personal access token](../../../user/profile/account/two_factor_authentication.md#personal-access-tokens) - instead of your password. - -## Removing the Git Annex branches - -After the migration finishes successfully, you can remove all `git-annex` -related branches from your repository. - -On GitLab, navigate to your project's **Repository > Branches** and delete all -branches created by Git Annex: `git-annex`, and all under `synced/`. - -![repository branches](img/git-annex-branches.png) - -You can also do this on the command line with: - -```shell -git branch -d synced/master -git branch -d synced/git-annex -git push origin :synced/master -git push origin :synced/git-annex -git push origin :git-annex -git remote prune origin -``` - -If there are still some Annex objects inside your repository (`.git/annex/`) -or references inside `.git/config`, run `annex uninit` again: - -```shell -git annex uninit -``` - -## Further Reading - -- (Blog Post) [Getting Started with Git FLS](https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/) -- (Blog Post) [Announcing LFS Support in GitLab](https://about.gitlab.com/blog/2015/11/23/announcing-git-lfs-support-in-gitlab/) -- (Blog Post) [GitLab Annex Solves the Problem of Versioning Large Binaries with Git](https://about.gitlab.com/blog/2015/02/17/gitlab-annex-solves-the-problem-of-versioning-large-binaries-with-git/) -- [Git Annex](../../../administration/git_annex.md) -- [Git LFS](index.md) +<!-- This redirect file can be deleted after <2021-07-22>. --> +<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page --> diff --git a/doc/topics/git/lfs/migrate_to_git_lfs.md b/doc/topics/git/lfs/migrate_to_git_lfs.md index 98c7e59154e..3f8e0575add 100644 --- a/doc/topics/git/lfs/migrate_to_git_lfs.md +++ b/doc/topics/git/lfs/migrate_to_git_lfs.md @@ -174,7 +174,6 @@ but commented out to help encourage others to add to it in the future. --> ## References - [Getting Started with Git LFS](https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/) -- [Migrate from Git Annex to Git LFS](migrate_from_git_annex_to_git_lfs.md) - [GitLab Git LFS user documentation](index.md) - [GitLab Git LFS administrator documentation](../../../administration/lfs/index.md) - Alternative method to [migrate an existing repository to Git LFS](https://github.com/git-lfs/git-lfs/wiki/Tutorial#migrating-existing-repository-data-to-lfs) diff --git a/doc/topics/git/merge_conflicts.md b/doc/topics/git/merge_conflicts.md new file mode 100644 index 00000000000..66771559298 --- /dev/null +++ b/doc/topics/git/merge_conflicts.md @@ -0,0 +1,69 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Merge conflicts + +- Happen often +- Learning to fix conflicts is hard +- Practice makes perfect +- Force push after fixing conflicts. Be careful! + +## Merge conflicts sample workflow + +1. Checkout a new branch and edit `conflicts.rb`. Add 'Line4' and 'Line5'. +1. Commit and push. +1. Checkout master and edit `conflicts.rb`. Add 'Line6' and 'Line7' below 'Line3'. +1. Commit and push to master. +1. Create a merge request and watch it fail. +1. Rebase our new branch with master. +1. Fix conflicts on the `conflicts.rb` file. +1. Stage the file and continue rebasing. +1. Force push the changes. +1. Finally continue with the Merge Request. + +```shell +git checkout -b conflicts_branch + +# vi conflicts.rb +# Add 'Line4' and 'Line5' + +git commit -am "add line4 and line5" +git push origin conflicts_branch + +git checkout master + +# vi conflicts.rb +# Add 'Line6' and 'Line7' +git commit -am "add line6 and line7" +git push origin master +``` + +Create a merge request on the GitLab web UI, and a conflict warning displays. + +```shell +git checkout conflicts_branch +git fetch +git rebase master + +# Fix conflicts by editing the files. + +git add conflicts.rb +# No need to commit this file + +git rebase --continue + +# Remember that we have rewritten our commit history so we +# need to force push so that our remote branch is restructured +git push origin conflicts_branch -f +``` + +## Note + +- When to use `git merge` and when to use `git rebase` +- Rebase when updating your branch with master +- Merge when bringing changes from feature to master +- Reference: <https://www.atlassian.com/git/tutorials/merging-vs-rebasing> diff --git a/doc/topics/git/merge_requests.md b/doc/topics/git/merge_requests.md new file mode 100644 index 00000000000..751bf8195d0 --- /dev/null +++ b/doc/topics/git/merge_requests.md @@ -0,0 +1,8 @@ +--- +redirect_to: '../../user/project/merge_requests/index.md' +--- + +This document was moved to [another location](../../user/project/merge_requests/index.md). + +<!-- This redirect file can be deleted after <2021-08-13>. --> +<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page --> diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png b/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png Binary files differdeleted file mode 100644 index d8dc9fc8097..00000000000 --- a/doc/topics/git/numerous_undo_possibilities_in_git/img/branching.png +++ /dev/null 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 eba471882f1..b151ddfff71 100644 --- a/doc/topics/git/numerous_undo_possibilities_in_git/index.md +++ b/doc/topics/git/numerous_undo_possibilities_in_git/index.md @@ -5,289 +5,215 @@ info: To determine the technical writer assigned to the Stage/Group associated w type: howto --- -# Numerous undo possibilities in Git **(FREE)** +# Undo possibilities in Git **(FREE)** -This tutorial shows you different ways of undoing your work in Git. -We assume you have a basic working knowledge of Git. Check the GitLab -[Git documentation](../index.md) for reference. +[Nothing in Git is deleted](https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery), +so when you work in Git, you can undo your work. -We only provide some general information about the commands to get you started. -For more advanced examples, refer to the [Git book](https://git-scm.com/book/en/v2). +All version control systems have options for undoing work. However, +because of the de-centralized nature of Git, these options are multiplied. +The actions you take are based on the +[stage of development](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) +you are in. -A few different techniques exist to undo your changes, based on the stage -of the change in your current development. Remember that -[nothing in Git is really deleted](https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery). -Until Git cleans detached commits - commits that cannot be accessed by branch or tag - -you can view them with `git reflog` command, and access them with direct commit ID. -Read more about [redoing the undo](#redoing-the-undo) in the section below. +For more information about working with Git and GitLab: -> For more information about working with Git and GitLab: -> -> - <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Learn why [North Western Mutual chose GitLab](https://youtu.be/kPNMyxKRRoM) for their Enterprise source code management. -> - Learn how to [get started with Git](https://about.gitlab.com/resources/whitepaper-moving-to-git/). +- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Learn why [North Western Mutual chose GitLab](https://youtu.be/kPNMyxKRRoM) for their enterprise source code management. +- Learn how to [get started with Git](https://about.gitlab.com/resources/whitepaper-moving-to-git/). +- For more advanced examples, refer to the [Git book](https://git-scm.com/book/en/v2). -## Introduction +## When you can undo changes -This guide is organized depending on the [stage of development](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository): +In the standard Git workflow: -- Where do you want to undo your changes from? -- Were they shared with other developers? +1. You create or edit a file. It starts in the unstaged state. If it's new, it is not yet tracked by Git. +1. You add the file to your local repository (`git add`), which puts the file into the staged state. +1. You commit the file to your local repository (`git commit`). +1. You can then share the file with other developers, by committing to a remote repository (`git push`). -Because Git tracks changes, a created or edited file is in the unstaged state -(if created it is untracked by Git). After you add it to a repository (`git add`) you put -a file into the **staged** state, which is then committed (`git commit`) to your -local repository. After that, file can be shared with other developers (`git push`). -This tutorial covers: +You can undo changes at any point in this workflow: -- [Undo local changes](#undo-local-changes) which were not pushed to a remote repository: - - - Before you commit, in both unstaged and staged state. - - After you committed. - -- Undo changes after they are pushed to a remote repository: - - - [Without history modification](#undo-remote-changes-without-changing-history) (preferred way). - - [With history modification](#undo-remote-changes-with-modifying-history) (requires +- [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 coordination with team and force pushes). - - [Use cases when modifying history is generally acceptable](#where-modifying-history-is-generally-acceptable). - - [How to modify history](#how-modifying-history-is-done). - - [How to remove sensitive information from repository](#deleting-sensitive-information-from-commits). -### Branching strategy +## Undo local changes -[Git](https://git-scm.com/) is a de-centralized version control system. Beside regular -versioning of the whole repository, it has possibilities to exchange changes -with other repositories. +Until you push your changes to a remote repository, changes +you make in Git are only in your local development environment. -To avoid chaos with -[multiple sources of truth](https://git-scm.com/about/distributed), various -development workflows have to be followed. It depends on your internal -workflow how certain changes or commits can be undone or changed. +### Undo unstaged local changes -[GitLab Flow](https://about.gitlab.com/topics/version-control/what-is-gitlab-flow/) provides a good -balance between developers clashing with each other while -developing the same feature and cooperating seamlessly. However, it does not enable -joined development of the same feature by multiple developers by default. +When you make a change, but have not yet staged it, you can undo your work. -When multiple developers develop the same feature on the same branch, clashing -with every synchronization is unavoidable. However, a proper or chosen Git Workflow -prevents lost or out-of-sync data when the feature is complete. +1. Confirm that the file is unstaged (that you did not use `git add <file>`) by running `git status`: -You can also -read through this blog post on [Git Tips & Tricks](https://about.gitlab.com/blog/2016/12/08/git-tips-and-tricks/) -to learn how to do things in Git. + ```shell + $ git status + On branch main + Your branch is up-to-date with 'origin/main'. + Changes not staged for commit: + (use "git add <file>..." to update what will be committed) + (use "git checkout -- <file>..." to discard changes in working directory) -## Undo local changes + modified: <file> + no changes added to commit (use "git add" and/or "git commit -a") + ``` -Until you push your changes to any remote repository, they only affect you. -That broadens your options on how to handle undoing them. Still, local changes -can be on various stages and each stage has a different approach on how to tackle them. +1. Choose an option and undo your changes: -### Unstaged local changes (before you commit) + - To overwrite local changes: -When a change is made, but not added to the staged tree, Git -proposes a solution to discard changes to the file. + ```shell + git checkout -- <file> + ``` -Suppose you edited a file to change the content using your favorite editor: + - To save local changes so you can [re-use them later](#quickly-save-local-changes): -```shell -vim <file> -``` + ```shell + git stash + ``` -Because you did not `git add <file>` to staging, it should be under unstaged files (or -untracked if file was created). You can confirm that with: + - To discard local changes to all files, permanently: -```shell -$ git status -On branch master -Your branch is up-to-date with 'origin/master'. -Changes not staged for commit: - (use "git add <file>..." to update what will be committed) - (use "git checkout -- <file>..." to discard changes in working directory) - - modified: <file> -no changes added to commit (use "git add" and/or "git commit -a") -``` + ```shell + git reset --hard + ``` -At this point there are 3 options to undo the local changes you have: +### Undo staged local changes -- Discard all local changes, but save them for possible re-use [later](#quickly-save-local-changes): +If you added a file to staging, you can undo it. - ```shell - git stash - ``` +1. Confirm that the file is staged (that you used `git add <file>`) by running `git status`: -- Discarding local changes (permanently) to a file: + ```shell + $ git status + On branch main + Your branch is up-to-date with 'origin/main'. + Changes to be committed: + (use "git restore --staged <file>..." to unstage) - ```shell - git checkout -- <file> - ``` + new file: <file> + ``` -- Discard all local changes to all files permanently: +1. Choose an option and undo your changes: - ```shell - git reset --hard - ``` + - To unstage the file but keep your changes: -Before executing `git reset --hard`, keep in mind that there is also a way to -just temporary store the changes without committing them using `git stash`. -This command resets the changes to all files, but it also saves them in case -you would like to apply them at some later time. You can read more about it in -[section below](#quickly-save-local-changes). + ```shell + git restore --staged <file> + ``` -### Quickly save local changes + - To unstage everything but keep your changes: -You are working on a feature when a boss drops by with an urgent task. Because your -feature is not complete, but you need to swap to another branch, you can use -`git stash` to: + ```shell + git reset + ``` -- Save what you have done. -- Swap to another branch. -- Commit, push, and test. -- Return to the feature branch. -- Run `git stash pop`. -- Resume your work. + - To unstage the file to current commit (HEAD): -The example above shows that discarding all changes is not always a preferred option. -However, Git provides a way to save them for later, while resetting the repository to state without -them. This is achieved by Git stashing command `git stash`, which in fact saves your -current work and runs `git reset --hard`, but it also has various -additional options like: + ```shell + git reset HEAD <file> + ``` -- `git stash save`, which enables including temporary commit message, which helps you identify changes, among with other options -- `git stash list`, which lists all previously stashed commits (yes, there can be more) that were not `pop`ed -- `git stash pop`, which redoes previously stashed changes and removes them from stashed list -- `git stash apply`, which redoes previously stashed changes, but keeps them on stashed list + - To discard all local changes, but save them for [later](#quickly-save-local-changes): -### Staged local changes (before you commit) + ```shell + git stash + ``` -If you add some files to staging, but you want to remove them from the -current commit while retaining those changes, move them outside -of the staging tree. You can also discard all changes with -`git reset --hard` or think about `git stash` [as described earlier.](#quickly-save-local-changes) + - To discard everything permanently: -Lets start the example by editing a file with your favorite editor to change the -content and add it to staging: + ```shell + git reset --hard + ``` -```shell -vim <file> -git add <file> -``` - -The file is now added to staging as confirmed by `git status` command: - -```shell -$ git status -On branch master -Your branch is up-to-date with 'origin/master'. -Changes to be committed: - (use "git reset HEAD <file>..." to unstage) - - new file: <file> -``` +### Quickly save local changes -Now you have 4 options to undo your changes: +If you want to change to another branch, you can use [`git stash`](https://www.git-scm.com/docs/git-stash). -- Unstage the file to current commit (HEAD): +1. From the branch where you want to save your work, type `git stash`. +1. Swap to another branch (`git checkout <branchname>`). +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. +1. Run a version of `git stash`: - ```shell - git reset HEAD <file> - ``` + - Use `git stash pop` to redo previously stashed changes and remove them from stashed list. + - Use `git stash apply` to redo previously stashed changes, but keep them on stashed list. -- Unstage everything - retain changes: +## Undo committed local changes - ```shell - git reset - ``` +When you commit to your local repository (`git commit`), the version control system 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. -- Discard all local changes, but save them for [later](#quickly-save-local-changes): +### Undo staged local changes without modifying history - ```shell - git stash - ``` +You can revert a commit while retaining the commit history. -- Discard everything permanently: +This example uses five commits `A`,`B`,`C`,`D`,`E`, which were committed in order: `A-B-C-D-E`. +The commit you want to undo is `B`. - ```shell - git reset --hard - ``` +1. Find the commit SHA of the commit you want to revert to. To look + through a log of commits, type `git log`. +1. Choose an option and undo your changes: -## Committed local changes + - To swap additions and deletions changes introduced by commit `B`: -After you commit, your changes are recorded by the version control system. -Because you haven't pushed to your remote repository yet, your changes are -still not public (or shared with other developers). At this point, undoing -things is a lot easier, we have quite some workaround options. After you push -your code, you have fewer options to troubleshoot your work. + ```shell + git revert <commit-B-SHA> + ``` -### Without modifying history + - To undo changes on a single file or directory from commit `B`, but retain them in the staged state: -Through the development process some of the previously committed changes do not -fit anymore in the end solution, or are source of the bugs. After you find the -commit which triggered bug, or identify a faulty commit, you can -revert it with `git revert commit-id`. + ```shell + git checkout <commit-B-SHA> <file> + ``` -This command inverts (swaps) the additions and -deletions in that commit, so that it does not modify history. Retaining history -can be helpful in future to notice that some changes have been tried -unsuccessfully in the past. + - To undo changes on a single file or directory from commit `B`, but retain them in the unstaged state: -In our example we assume there are commits `A`,`B`,`C`,`D`,`E` committed in this order: `A-B-C-D-E`, -and `B` is the commit you want to undo. There are many different ways to identify commit -`B` as bad. One of them is to pass a range to `git bisect` command. The provided range includes -last known good commit (we assume `A`) and first known bad commit where the bug was detected (we assume `E`). + ```shell + git reset <commit-B-SHA> <file> + ``` -```shell -git bisect A..E -``` +#### Undo multiple committed changes -Bisect provides us with commit ID of the middle commit to test, and then guide us -through the bisection process. You can read more about it [in official Git Tools](https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git) -Our example results in commit `B`, which introduced the bug/error. We have -these options to remove all or part of it from our repository: +You can recover from multiple commits. For example, if you have done commits `A-B-C-D` +on your feature branch and then realize that `C` and `D` are wrong. -- Undo (swap additions and deletions) changes introduced by commit `B`: +To recover from multiple incorrect commits: - ```shell - git revert commit-B-id - ``` +1. Check out the last correct commit. In this example, `B`. -- Undo changes on a single file or directory from commit `B`, but retain them in the staged state: + ```shell + git checkout <commit-B-SHA> + ``` - ```shell - git checkout commit-B-id <file> - ``` +1. Create a new branch. -- Undo changes on a single file or directory from commit `B`, but retain them in the unstaged state: + ```shell + git checkout -b new-path-of-feature + ``` - ```shell - git reset commit-B-id <file> - ``` +1. Add, push, and commit your changes. -- There is one command we also must not forget: **creating a new branch** - from the point where changes are not applicable or where the development has hit a - dead end. For example you have done commits `A-B-C-D` on your feature branch - and then you figure `C` and `D` are wrong. +The commits are now `A-B-C-D-E`. - At this point you either reset to `B` - and do commit `F` (which causes problems with pushing and if forced pushed also with other developers) - because the branch now looks `A-B-F`, which clashes with what other developers have locally (you will - [change history](#with-history-modification)), or you checkout commit `B` create - a new branch and do commit `F`. In the last case, everyone else can still do their work while you - have your new way to get it right and merge it back in later. Alternatively, with GitLab, - you can [cherry-pick](../../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit) - that commit into a new merge request. +Alternatively, with GitLab, +you can [cherry-pick](../../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit) +that commit into a new merge request. - ![Create a new branch to avoid clashing](img/branching.png) +NOTE: +Another solution is to reset to `B` and commit `E`. However, this solution results in `A-B-E`, +which clashes with what other developers have locally. - ```shell - git checkout commit-B-id - git checkout -b new-path-of-feature - # Create <commit F> - git commit -a - ``` +### Undo staged local changes with history modification -### 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: @@ -335,7 +261,7 @@ In case you want to modify something introduced in commit `B`. You can find some more examples in the section explaining [how to modify history](#how-modifying-history-is-done). -### Redoing the Undo +### 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` @@ -379,7 +305,7 @@ it also provides a clear timeline and development structure. ![Use revert to keep branch flowing](img/revert.png) -If you want to revert changes introduced in certain `commit-id`, you can +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 @@ -501,14 +427,6 @@ 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. -## Conclusion - -Various options exist for undoing your work with any version control system, but -because of the de-centralized nature of Git, these options are multiplied (or limited) -depending on the stage of your process. Git also enables rewriting history, but that -should be avoided as it might cause problems when multiple developers are -contributing to the same codebase. - <!-- ## Troubleshooting Include any troubleshooting steps that you can foresee. If you know beforehand what issues diff --git a/doc/topics/git/rollback_commits.md b/doc/topics/git/rollback_commits.md new file mode 100644 index 00000000000..34c2d9687bb --- /dev/null +++ b/doc/topics/git/rollback_commits.md @@ -0,0 +1,81 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Rollback Commits + +## Undo Commits + +- Undo last commit putting everything back into the staging area: + + ```shell + git reset --soft HEAD^ + ``` + +- Add files and change message with: + + ```shell + git commit --amend -m "New Message" + ``` + +- Undo last and remove changes: + + ```shell + git reset --hard HEAD^ + ``` + +- Same as last one but for two commits back: + + ```shell + git reset --hard HEAD^^ + ``` + +**Don't reset after pushing** + +## Reset Workflow + +1. Edit file again 'edit_this_file.rb' +1. Check status +1. Add and commit with wrong message +1. Check log +1. Amend commit +1. Check log +1. Soft reset +1. Check log +1. Pull for updates +1. Push changes + +## Commands + +```shell +# Change file edit_this_file.rb +git status +git commit -am "kjkfjkg" +git log +git commit --amend -m "New comment added" +git log +git reset --soft HEAD^ +git log +git pull origin master +git push origin master +``` + +## Note + +- `git revert` vs `git reset` +- Reset removes the commit while revert removes the changes but leaves the commit +- Revert is safer considering we can revert a revert + +```shell +# Changed file +git commit -am "bug introduced" +git revert HEAD +# New commit created reverting changes +# Now we want to re apply the reverted commit +git log # take hash from the revert commit +git revert <rev commit hash> +# reverted commit is back (new commit created again) +``` diff --git a/doc/topics/git/stash.md b/doc/topics/git/stash.md new file mode 100644 index 00000000000..051103e5f4b --- /dev/null +++ b/doc/topics/git/stash.md @@ -0,0 +1,82 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Git Stash + +We use `git stash` to store our changes when they are not ready to be committed +and we need to change to a different branch. + +- Stash: + + ```shell + git stash save + # or + git stash + # or with a message + git stash save "this is a message to display on the list" + ``` + +- Apply stash to keep working on it: + + ```shell + git stash apply + # or apply a specific one from out stack + git stash apply stash@{3} + ``` + +- Every time we save a stash it gets stacked so by using `list` we can see all our + stashes. + + ```shell + git stash list + # or for more information (log methods) + git stash list --stat + ``` + +- To clean our stack we need to manually remove them: + + ```shell + # drop top stash + git stash drop + # or + git stash drop <name> + # to clear all history we can use + git stash clear + ``` + +- Apply and drop on one command: + + ```shell + git stash pop + ``` + +- If we meet conflicts we need to either reset or commit our changes. +- Conflicts through `pop` doesn't drop a stash afterwards. + +## Git Stash sample workflow + +1. Modify a file +1. Stage file +1. Stash it +1. View our stash list +1. Confirm no pending changes through status +1. Apply with pop +1. View list to confirm changes + +```shell +# Modify edit_this_file.rb file +git add . + +git stash save "Saving changes from edit this file" + +git stash list +git status + +git stash pop +git stash list +git status +``` diff --git a/doc/topics/git/subtree.md b/doc/topics/git/subtree.md new file mode 100644 index 00000000000..54461915a05 --- /dev/null +++ b/doc/topics/git/subtree.md @@ -0,0 +1,52 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Subtree + +- Used when there are nested repositories. +- Not recommended when the amount of dependencies is too large. +- For these cases we need a dependency control system. +- Command are painfully long so aliases are necessary. + +## Subtree Aliases + +- Add: `git subtree add --prefix <target-folder> <url> <branch> --squash` +- Pull: `git subtree pull --prefix <target-folder> <url> <branch> --squash` +- Push: `git subtree add --prefix <target-folder> <url> <branch>` +- Ex: `git config alias.sbp 'subtree pull --prefix st / + git@gitlab.com:balameb/subtree-nested-example.git master --squash'` + +```shell + # Add an alias + # Add + git config alias.sba 'subtree add --prefix st / + git@gitlab.com:balameb/subtree-nested-example.git master --squash' + # Pull + git config alias.sbpl 'subtree pull --prefix st / + git@gitlab.com:balameb/subtree-nested-example.git master --squash' + # Push + git config alias.sbph 'subtree push --prefix st / + git@gitlab.com:balameb/subtree-nested-example.git master' + + # Adding this subtree adds a st dir with a readme + git sba + vi st/README.md + # Edit file + git status shows differences + +``` + +```shell + # Adding, or committing won't change the sub repo at remote + # even if we push + git add -A + git commit -m "Adding to subtree readme" + + # Push to subtree repo + git sbph + # now we can check our remote sub repo +``` diff --git a/doc/topics/git/unstage.md b/doc/topics/git/unstage.md new file mode 100644 index 00000000000..30d26854135 --- /dev/null +++ b/doc/topics/git/unstage.md @@ -0,0 +1,33 @@ +--- +stage: none +group: unassigned +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +comments: false +--- + +# Unstage + +- To remove files from stage use reset HEAD where HEAD is the last commit of the current branch. This unstages the file but maintain the modifications. + + ```shell + git reset HEAD <file> + ``` + +- To revert the file back to the state it was in before the changes we can use: + + ```shell + git checkout -- <file> + ``` + +- To remove a file from disk and repository, use `git rm`. To remove a directory, use the `-r` flag: + + ```shell + git rm '*.txt' + git rm -r <dirname> + ``` + +- If we want to remove a file from the repository but keep it on disk, say we forgot to add it to our `.gitignore` file then use `--cache`: + + ```shell + git rm <filename> --cache + ``` |