Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Feature: Add functionality to discard changes #356

@neuroKip

Description

@neuroKip

Discarding changes

Problem

When there are changes to files that the user isn't interested in keeping, they need a way of throwing away these changes. This is normally implemented via a Discard action for a specific file, or for all files.

Git overview

Git provides a checkout command that changes the working directory back to a previous state. This command can take:

  • a commit (usually a branch name) - updates the working directory to the state of that commit
  • a filename or list of files - updates the named files to the state of the commit (the current HEAD if no commit is specified)

git checkout [file] or git checkout -- [files], will only operate on files that are already tracked by git and will not work for new files. Also, if a file has already been added to the staging area, checkout [file] will not affect the changes in the staging area, it will only affect changes that have not been staged yet.

image

In this situation above, in order to discard changes to the different files, we need to do:

  • README.me: git checkout HEAD -- README.md
  • package.sh: git checkout -- package.sh (git checkout HEAD -- package.sh also works)
  • a: git checkout won't work, we need to manually delete the file.

git clean -f throws away new files / changes to untracked files, but won't reset tracked file changes back to what they were.

git reset --hard throws away all changes to tracked files but doesn't touch untracked (new) files

Solution

Technical backend - git operations

Discard changes to a single file

To implement "Discard changes to a particular file", we should:

  • Check whether the file is new
    • If yes, delete it
    • If no, git checkout HEAD -- [file]

Discard changes to all files

To implement "Discard all changes", there's several alternatives:

  1. clean and reset
  • Run git clean -f to throw away all new (untracked) files
  • Run git reset --hard to reset all changed (tracked) files back to unchanged
  1. checkout and delete
  • Categorize all files by new/existing (untracked/tracked)
  • Delete all new (untracked) files
  • Run git checkout HEAD -- [files] on all existing (tracked) changed files

UI/UX

TBD

API technical details

Given that both discard and discard all requires at least two separate actions (as talked about in #356), that should probably be implemented in RepositoryManager. What we then need is:

RepositoryManager.cs (pseudocode):

DiscardAll():

   GitClient.CleanUntrackedFiles()
   GitClient.Checkout("HEAD")
DiscardFiles(List<GitFile> files):
   
    where file in files.Added: Delete File via System.IO calls
    all other files: GitClient.Checkout("HEAD", files)

We already have GitSwitchBranchesTask which basically does a git checkout. We should probably rename that one to GitCheckout and add an optional files parameter to it, calling either git checkout [branch] or git checkout [branch] -- files depending on whether there's a list of files to checkout. Checking out a branch is the same as checking out HEAD, there's no difference there

old issue body below

To implement a discard changes function in the user interface we first need to add the functionality to our api.

  1. Create GitCheckoutTask,
    a. The goal of this task is to run git checkout.
    1. It should be able to checkout on a specific file
      git checkout path/to/file/to/revert
    2. It should be able to checkout all files
      git checkout -- .
      b. You can use GitAddTask as an example.
      https://github.com/github-for-unity/Unity/blob/master/src/GitHub.Api/Git/Tasks/GitAddTask.cs
  2. Add the functionality to use GitCheckoutTask to GitClient
    a. Create a Discard and DiscardAll method
    b. You can use the methods Add and AddAll as an example
    https://github.com/github-for-unity/Unity/blob/master/src/GitHub.Api/Git/GitClient.cs#L371-393
  3. Add some integration tests
    https://github.com/github-for-unity/Unity/blob/master/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs
    a. We need some integration tests to prove what you did is working correctly
    b. You can use the ShouldDetectFileChanges test as an example, it makes changes to the system and checks if they are there.
    https://github.com/github-for-unity/Unity/blob/master/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs#L24-L62

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions