diff --git a/app/assets/javascripts/pipelines/components/graph_shared/api.js b/app/assets/javascripts/pipelines/components/graph_shared/api.js
index 49cd04d11e9..0fe7d9ffda3 100644
--- a/app/assets/javascripts/pipelines/components/graph_shared/api.js
+++ b/app/assets/javascripts/pipelines/components/graph_shared/api.js
@@ -2,6 +2,11 @@ import axios from '~/lib/utils/axios_utils';
import { reportToSentry } from '../../utils';
export const reportPerformance = (path, stats) => {
+ // FIXME: https://gitlab.com/gitlab-org/gitlab/-/issues/330245
+ if (!path) {
+ return;
+ }
+
axios.post(path, stats).catch((err) => {
reportToSentry('links_inner_perf', `error: ${err}`);
});
diff --git a/app/graphql/mutations/namespace/package_settings/update.rb b/app/graphql/mutations/namespace/package_settings/update.rb
index ca21c3418fc..75c80cfbd3e 100644
--- a/app/graphql/mutations/namespace/package_settings/update.rb
+++ b/app/graphql/mutations/namespace/package_settings/update.rb
@@ -25,6 +25,16 @@ module Mutations
required: false,
description: copy_field_description(Types::Namespace::PackageSettingsType, :maven_duplicate_exception_regex)
+ argument :generic_duplicates_allowed,
+ GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: copy_field_description(Types::Namespace::PackageSettingsType, :generic_duplicates_allowed)
+
+ argument :generic_duplicate_exception_regex,
+ Types::UntrustedRegexp,
+ required: false,
+ description: copy_field_description(Types::Namespace::PackageSettingsType, :generic_duplicate_exception_regex)
+
field :package_settings,
Types::Namespace::PackageSettingsType,
null: true,
diff --git a/app/graphql/types/namespace/package_settings_type.rb b/app/graphql/types/namespace/package_settings_type.rb
index 0720a1cfb4b..af091515979 100644
--- a/app/graphql/types/namespace/package_settings_type.rb
+++ b/app/graphql/types/namespace/package_settings_type.rb
@@ -10,5 +10,7 @@ module Types
field :maven_duplicates_allowed, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether duplicate Maven packages are allowed for this namespace.'
field :maven_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.'
+ field :generic_duplicates_allowed, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether duplicate generic packages are allowed for this namespace.'
+ field :generic_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.'
end
end
diff --git a/app/models/namespace/package_setting.rb b/app/models/namespace/package_setting.rb
index ce0b736e9a5..881b2f3acb3 100644
--- a/app/models/namespace/package_setting.rb
+++ b/app/models/namespace/package_setting.rb
@@ -6,13 +6,15 @@ class Namespace::PackageSetting < ApplicationRecord
PackageSettingNotImplemented = Class.new(StandardError)
- PACKAGES_WITH_SETTINGS = %w[maven].freeze
+ PACKAGES_WITH_SETTINGS = %w[maven generic].freeze
belongs_to :namespace, inverse_of: :package_setting_relation
validates :namespace, presence: true
validates :maven_duplicates_allowed, inclusion: { in: [true, false] }
validates :maven_duplicate_exception_regex, untrusted_regexp: true, length: { maximum: 255 }
+ validates :generic_duplicates_allowed, inclusion: { in: [true, false] }
+ validates :generic_duplicate_exception_regex, untrusted_regexp: true, length: { maximum: 255 }
class << self
def duplicates_allowed?(package)
diff --git a/app/models/packages.rb b/app/models/packages.rb
index e14c9290093..19490d23ce4 100644
--- a/app/models/packages.rb
+++ b/app/models/packages.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
module Packages
+ DuplicatePackageError = Class.new(StandardError)
+
def self.table_name_prefix
'packages_'
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 9d2e514f377..9411cbc35fc 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -995,7 +995,13 @@ class Repository
def search_files_by_wildcard_path(path, ref = 'HEAD')
# We need to use RE2 to match Gitaly's regexp engine
- regexp_string = RE2::Regexp.escape(path).gsub('\*', '.*?')
+ regexp_string = RE2::Regexp.escape(path)
+
+ anything = '.*?'
+ anything_but_not_slash = '([^\/])*?'
+ regexp_string.gsub!('\*\*', anything)
+ regexp_string.gsub!('\*', anything_but_not_slash)
+
raw_repository.search_files_by_regexp("^#{regexp_string}$", ref)
end
diff --git a/app/services/namespaces/package_settings/update_service.rb b/app/services/namespaces/package_settings/update_service.rb
index 0964963647a..cbadbe5c907 100644
--- a/app/services/namespaces/package_settings/update_service.rb
+++ b/app/services/namespaces/package_settings/update_service.rb
@@ -5,7 +5,10 @@ module Namespaces
class UpdateService < BaseContainerService
include Gitlab::Utils::StrongMemoize
- ALLOWED_ATTRIBUTES = %i[maven_duplicates_allowed maven_duplicate_exception_regex].freeze
+ ALLOWED_ATTRIBUTES = %i[maven_duplicates_allowed
+ maven_duplicate_exception_regex
+ generic_duplicates_allowed
+ generic_duplicate_exception_regex].freeze
def execute
return ServiceResponse.error(message: 'Access Denied', http_status: 403) unless allowed?
diff --git a/app/services/packages/generic/create_package_file_service.rb b/app/services/packages/generic/create_package_file_service.rb
index 1451a022a39..42a191fb415 100644
--- a/app/services/packages/generic/create_package_file_service.rb
+++ b/app/services/packages/generic/create_package_file_service.rb
@@ -23,6 +23,10 @@ module Packages
.new(project, current_user, package_params)
.execute
+ unless Namespace::PackageSetting.duplicates_allowed?(package)
+ raise ::Packages::DuplicatePackageError if target_file_is_duplicate?(package)
+ end
+
package.update_column(:status, params[:status]) if params[:status] && params[:status] != package.status
package.build_infos.safe_find_or_create_by!(pipeline: params[:build].pipeline) if params[:build].present?
@@ -40,6 +44,10 @@ module Packages
::Packages::CreatePackageFileService.new(package, file_params).execute
end
+
+ def target_file_is_duplicate?(package)
+ package.package_files.with_file_name(params[:file_name]).exists?
+ end
end
end
end
diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml
index 52cf0248f21..4e373dda013 100644
--- a/app/views/shared/snippets/_snippet.html.haml
+++ b/app/views/shared/snippets/_snippet.html.haml
@@ -8,7 +8,7 @@
= link_to gitlab_snippet_path(snippet) do
= snippet.title
- %ul.controls
+ %ul.controls{ data: { qa_selector: 'snippet_file_count_content', qa_snippet_files: snippet.statistics&.file_count } }
%li
= snippet_file_count(snippet)
%li
@@ -16,7 +16,7 @@
= sprite_icon('comments', css_class: 'gl-vertical-align-text-bottom')
= notes_count
%li
- %span.sr-only
+ %span.sr-only{ data: { qa_selector: 'snippet_visibility_content', qa_snippet_visibility: visibility_level_label(snippet.visibility_level) } }
= visibility_level_label(snippet.visibility_level)
= visibility_level_icon(snippet.visibility_level)
diff --git a/changelogs/unreleased/293755-generic-dupe-settings.yml b/changelogs/unreleased/293755-generic-dupe-settings.yml
new file mode 100644
index 00000000000..fd2e5a8d1d8
--- /dev/null
+++ b/changelogs/unreleased/293755-generic-dupe-settings.yml
@@ -0,0 +1,5 @@
+---
+title: Add setting to allow or disallow duplicates for generic packages
+merge_request: 60664
+author:
+type: added
diff --git a/changelogs/unreleased/327414-agent-proxy-request-count.yml b/changelogs/unreleased/327414-agent-proxy-request-count.yml
new file mode 100644
index 00000000000..1f3bf7027b6
--- /dev/null
+++ b/changelogs/unreleased/327414-agent-proxy-request-count.yml
@@ -0,0 +1,5 @@
+---
+title: Add kubernetes_agent_proxy_request to usage ping
+merge_request: 60978
+author:
+type: changed
diff --git a/db/migrate/20210429192653_add_generic_package_duplicate_settings_to_namespace_package_settings.rb b/db/migrate/20210429192653_add_generic_package_duplicate_settings_to_namespace_package_settings.rb
new file mode 100644
index 00000000000..8c328eb52fc
--- /dev/null
+++ b/db/migrate/20210429192653_add_generic_package_duplicate_settings_to_namespace_package_settings.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddGenericPackageDuplicateSettingsToNamespacePackageSettings < ActiveRecord::Migration[6.0]
+ # rubocop:disable Migration/AddLimitToTextColumns
+ # limit is added in 20210429193106_add_text_limit_to_namespace_package_settings_generic_duplicate_exception_regex
+ def change
+ add_column :namespace_package_settings, :generic_duplicates_allowed, :boolean, null: false, default: true
+ add_column :namespace_package_settings, :generic_duplicate_exception_regex, :text, null: false, default: ''
+ end
+ # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20210429193106_add_text_limit_to_namespace_package_settings_generic_duplicate_exception_regex.rb b/db/migrate/20210429193106_add_text_limit_to_namespace_package_settings_generic_duplicate_exception_regex.rb
new file mode 100644
index 00000000000..5d02ad3e2f5
--- /dev/null
+++ b/db/migrate/20210429193106_add_text_limit_to_namespace_package_settings_generic_duplicate_exception_regex.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTextLimitToNamespacePackageSettingsGenericDuplicateExceptionRegex < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :namespace_package_settings, :generic_duplicate_exception_regex, 255
+ end
+
+ def down
+ remove_text_limit :namespace_package_settings, :generic_duplicate_exception_regex
+ end
+end
diff --git a/db/schema_migrations/20210429192653 b/db/schema_migrations/20210429192653
new file mode 100644
index 00000000000..5e380380d72
--- /dev/null
+++ b/db/schema_migrations/20210429192653
@@ -0,0 +1 @@
+c2b5ad6786e1c71ccff391b03fcd0635dfd42d69484443291a692cef9f3ffda5
\ No newline at end of file
diff --git a/db/schema_migrations/20210429193106 b/db/schema_migrations/20210429193106
new file mode 100644
index 00000000000..49f1838a585
--- /dev/null
+++ b/db/schema_migrations/20210429193106
@@ -0,0 +1 @@
+e0898e4e439cde4e3b84808e7505490fe956cf17922f5c779b3384997d36cafd
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 5bf73b4955a..ce42f7362ca 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -14798,6 +14798,9 @@ CREATE TABLE namespace_package_settings (
namespace_id bigint NOT NULL,
maven_duplicates_allowed boolean DEFAULT true NOT NULL,
maven_duplicate_exception_regex text DEFAULT ''::text NOT NULL,
+ generic_duplicates_allowed boolean DEFAULT true NOT NULL,
+ generic_duplicate_exception_regex text DEFAULT ''::text NOT NULL,
+ CONSTRAINT check_31340211b1 CHECK ((char_length(generic_duplicate_exception_regex) <= 255)),
CONSTRAINT check_d63274b2b6 CHECK ((char_length(maven_duplicate_exception_regex) <= 255))
);
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index be5de5c86ac..28f91c7139e 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -3911,6 +3911,8 @@ Input type: `UpdateNamespacePackageSettingsInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| `genericDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
+| `genericDuplicatesAllowed` | [`Boolean`](#boolean) | Indicates whether duplicate generic packages are allowed for this namespace. |
| `mavenDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
| `mavenDuplicatesAllowed` | [`Boolean`](#boolean) | Indicates whether duplicate Maven packages are allowed for this namespace. |
| `namespacePath` | [`ID!`](#id) | The namespace path where the namespace package setting is located. |
@@ -10488,6 +10490,8 @@ Namespace-level Package Registry settings.
| Name | Type | Description |
| ---- | ---- | ----------- |
+| `genericDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
+| `genericDuplicatesAllowed` | [`Boolean!`](#boolean) | Indicates whether duplicate generic packages are allowed for this namespace. |
| `mavenDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
| `mavenDuplicatesAllowed` | [`Boolean!`](#boolean) | Indicates whether duplicate Maven packages are allowed for this namespace. |
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index f815bfbc5a9..23cdce8187b 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -487,7 +487,7 @@ Use local includes instead of symbolic links.
> - It's not recommended for production use.
> - To use it in GitLab self-managed instances, ask a GitLab administrator to enable it. **(CORE ONLY)**
-You can use wildcard paths (`*`) with `include:local`.
+You can use wildcard paths (`*` and `**`) with `include:local`.
Example:
@@ -495,7 +495,19 @@ Example:
include: 'configs/*.yml'
```
-When the pipeline runs, it adds all `.yml` files in the `configs` folder into the pipeline configuration.
+When the pipeline runs, GitLab:
+
+- Adds all `.yml` files in the `configs` directory into the pipeline configuration.
+- Does not add `.yml` files in subfolders of the `configs` directory. To allow this,
+ add the following configuration:
+
+ ```yaml
+ # This matches all `.yml` files in `configs` and any subfolder in it.
+ include: 'configs/**.yml'
+
+ # This matches all `.yml` files only in subfolders of `configs`.
+ include: 'configs/**/*.yml'
+ ```
The wildcard file paths feature is under development and not ready for production use. It is
deployed behind a feature flag that is **disabled by default**.
diff --git a/doc/development/internal_api.md b/doc/development/internal_api.md
index 7cf740d16a0..57dd1c0a65b 100644
--- a/doc/development/internal_api.md
+++ b/doc/development/internal_api.md
@@ -453,7 +453,8 @@ metric counters.
| Attribute | Type | Required | Description |
|:----------|:-------|:---------|:------------|
-| `gitops_sync_count` | integer| yes | The number to increase the `gitops_sync_count` counter by |
+| `gitops_sync_count` | integer| no | The number to increase the `gitops_sync_count` counter by |
+| `k8s_api_proxy_request_count` | integer| no | The number to increase the `k8s_api_proxy_request_count` counter by |
```plaintext
POST /internal/kubernetes/usage_metrics
diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md
index 8c60a768b46..80816bf583a 100644
--- a/doc/development/usage_ping/dictionary.md
+++ b/doc/development/usage_ping/dictionary.md
@@ -2902,6 +2902,18 @@ Status: `data_available`
Tiers: `premium`, `ultimate`
+### `counts.kubernetes_agent_k8s_api_proxy_request`
+
+Count of Kubernetes API proxy requests
+
+[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_all/20210505015532_kubernetes_agent_k8s_api_proxy_request.yml)
+
+Group: `group::configure`
+
+Status: `implemented`
+
+Tiers: `premium`, `ultimate`
+
### `counts.kubernetes_agents`
Count of Kubernetes agents
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 eb1c0a597f3..2426fa2f7cb 100644
--- a/doc/topics/git/numerous_undo_possibilities_in_git/index.md
+++ b/doc/topics/git/numerous_undo_possibilities_in_git/index.md
@@ -5,139 +5,134 @@ 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:
->
-> - 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/).
+- 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
-
-[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.
-
-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.
-
-[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 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.
-
-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.
## Undo local changes
-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.
+Until you push your changes to a remote repository, changes
+you make in Git are only in your local development environment.
-### Unstaged local changes (before you commit)
+### Undo unstaged local changes before you commit
-When a change is made, but not added to the staged tree, Git
-proposes a solution to discard changes to the file.
+When you make a change, but have not yet staged it, you can undo your work.
-Suppose you edited a file to change the content using your favorite editor:
+1. Confirm that the file is unstaged (that you did not use `git add `) by running `git status`:
-```shell
-vim
-```
+ ```shell
+ $ git status
+ On branch main
+ Your branch is up-to-date with 'origin/main'.
+ Changes not staged for commit:
+ (use "git add ..." to update what will be committed)
+ (use "git checkout -- ..." to discard changes in working directory)
-Because you did not `git add ` to staging, it should be under unstaged files (or
-untracked if file was created). You can confirm that with:
+ modified:
+ no changes added to commit (use "git add" and/or "git commit -a")
+ ```
-```shell
-$ git status
-On branch master
-Your branch is up-to-date with 'origin/master'.
-Changes not staged for commit:
- (use "git add ..." to update what will be committed)
- (use "git checkout -- ..." to discard changes in working directory)
+1. Choose an option and undo your changes:
- modified:
-no changes added to commit (use "git add" and/or "git commit -a")
-```
+ - To overwrite local changes:
-At this point there are 3 options to undo the local changes you have:
+ ```shell
+ git checkout --
+ ```
-- Discard all local changes, but save them for possible re-use [later](#quickly-save-local-changes):
+ - To save local changes so you can [re-use them later](#quickly-save-local-changes):
- ```shell
- git stash
- ```
+ ```shell
+ git stash
+ ```
-- Discarding local changes (permanently) to a file:
+ - To discard local changes to all files, permanently:
- ```shell
- git checkout --
- ```
+ ```shell
+ git reset --hard
+ ```
-- Discard all local changes to all files permanently:
+### Undo staged local changes before you commit
- ```shell
- git reset --hard
- ```
+If you added a file to staging, you can undo it.
-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).
+1. Confirm that the file is staged (that you used `git add `) by running `git status`:
+
+ ```shell
+ $ git status
+ On branch main
+ Your branch is up-to-date with 'origin/main'.
+ Changes to be committed:
+ (use "git restore --staged ..." to unstage)
+
+ new file:
+ ```
+
+1. Choose an option and undo your changes:
+
+ - To unstage the file but keep your changes:
+
+ ```shell
+ git restore --staged
+ ```
+
+ - To unstage everything but keep your changes:
+
+ ```shell
+ git reset
+ ```
+
+ - To unstage the file to current commit (HEAD):
+
+ ```shell
+ git reset HEAD
+ ```
+
+ - To discard all local changes, but save them for [later](#quickly-save-local-changes):
+
+ ```shell
+ git stash
+ ```
+
+ - To discard everything permanently:
+
+ ```shell
+ git reset --hard
+ ```
### Quickly save local changes
-You are working on a feature when a boss drops by with an urgent task. Because your
+You are working on a feature when someone 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:
@@ -159,60 +154,7 @@ additional options like:
- `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
-### Staged local changes (before you commit)
-
-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)
-
-Lets start the example by editing a file with your favorite editor to change the
-content and add it to staging:
-
-```shell
-vim
-git add
-```
-
-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 ..." to unstage)
-
- new file:
-```
-
-Now you have 4 options to undo your changes:
-
-- Unstage the file to current commit (HEAD):
-
- ```shell
- git reset HEAD
- ```
-
-- Unstage everything - retain changes:
-
- ```shell
- git reset
- ```
-
-- Discard all local changes, but save them for [later](#quickly-save-local-changes):
-
- ```shell
- git stash
- ```
-
-- Discard everything permanently:
-
- ```shell
- git reset --hard
- ```
-
-## Committed local changes
+## Undo committed local changes
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
@@ -289,6 +231,9 @@ these options to remove all or part of it from our repository:
### 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 +280,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`
@@ -501,14 +446,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.
-