Git stage changes and revert not staged changes

Answered

 

Hello,

looking for following equivalent in GUI

```

$ echo "hello" > file.txt

$ git add file.txt

$ echo "Hello there!" > file.txt

$ git checkout -- file.txt

$ cat file.txt

hello```

2
26 comments

IDE does not distinguish between staged and not staged changes. There is no way of reverting all unstaged keeping staged.

See https://youtrack.jetbrains.com/issue/IDEA-63391

As an alternative to the stage area, you could use changelists, btw. Imagine staged is one changelist, and non-staged is another one.

0
Avatar
Permanently deleted user

It is not an alternative, I can have one file on one changelist at one time only. What I'm looking for is exactly what provided shell commands are doing:

  1. change a file
  2. accept changes as a candidate for commit
  3. perform next changes to a file
  4. revert step 3.
1

> I can have one file on one changelist at one time only

That is not true. Starting from 2018.1 each changed chunk in a file can be assigned to a separate changelist.

So you can 

  1. change a file
  2. when you are happy with changes, create a new changelist and switch to it
  3. perform next change
  4. Rever the changelist, so changes in step 3 will be removed, while others will not.

This can be even more powerful than the stage, in some cases, as you could have several groups of changes in the file, probably related to different features, not only staged and unstaged.

0
Avatar
Permanently deleted user

 

You are right, seems like it is working. The only disadvantage is that it is a custom solution (even if looks like more powerful) and is not compatible with other tools. I like some scripting stuff around.

Thank You for Your advice.

1
Avatar
Permanently deleted user

Staging area support would be nice...

2

@Nicolas

Why do you need stage? What use-case do you solve with it that can't be solved with changelists?

See also https://youtrack.jetbrains.com/issue/IDEA-63391

-1
Avatar
Permanently deleted user

@Dmitriy Thanks for your quick response. Here are a couple exemple I can take from the top of my head (anybody else can help provide such use-cases please ?) :

- Resolving merge conflicts.
- My colleagues might not be familiar with Intellij, so it would also be valuable for cooperation and the like.

Here's a question for you; Why hasn't a GUI for git stage been implemented ? Could such an interface exist beside your implementation of changelog, or is changelog making it impossible for you to implement git stage ?

Thanks :-)

0

> Resolving merge conflicts

Why do you need the stage here? Yes, you need to stage version of the file that you want to commit, but IDE does it for you if you use the built-in merge tool. Also, you still could call Git - Add on the file from the context menu.

> My colleagues might not be familiar with IntelliJ, so it would also be valuable for cooperation and the like

Both stage and changelists are local and specific to your copy of the repo. It does not affect your colleagues - they could use stage or whatever they want in their repositories. Could you please clarify?

> Why hasn't a GUI for git stage been implemented

For various reasons. And indeed, it does not co-exist with changelists and the way IDE handles changes. 

 

0
Avatar
Permanently deleted user

@Dmitriy by cooperation I mean having someone sit next to you, look at your code together, pair programming, etc.

0

TBH I am not sure how stage or changelist make any difference for a person sitting next to you. You are to discuss-review code, it is not important how you would commit it then, AFAIU.

0
Avatar
Permanently deleted user

@Dmitriy ok, intellij’s won’t implement a visual representation of GIT’s staging area as it brings close to no improvements (it actually would be a down-grade) over their current abstraction of this concept (changelog)

1
Avatar
Permanently deleted user

Is there a way to add/remove a set of lines (hunk) to and from one changelist to another?

In that way some changes to 'a' file could be in one changelist and some other changes to the same file can be in a different changelist.

(This is something that can be done with stage/unstage concept)

 

0

> Is there a way to add/remove a set of lines (hunk) to and from one changelist to another?

Hunk-level works easily - just drag n drop hunks between changelists in sidebar, or there's a context menu also in the code editor.

I think line-level is not as easy right now, https://youtrack.jetbrains.com/issue/IDEA-186988 is still unsolved.

1
Avatar
Permanently deleted user

Thanks @Leho,

But, take the case where we have a file having 2 chunks of changes, lets call them: chunk_1 and chunk_2

and 2 changelists as: changelist_1 and changelist_2

Problem: assume initially, chunk_1 and chunk_2 are in changelist_1 then I move chunk_2 in to changelist_2, and now in the "Local Changes" window if i select the file in the changelist_1, in the "Preview Diff" section it still shown as both chunk_1 and chunk_2 have changed (under changelist_1 - confusing) , this is same if i preview the changelist_2, it will be shown as both chunk_1 and chunk_2 have changed in changelist_2. Only way to know exactly which chunk belongs in which changelist, I have to:

Select the file in the changelist_1 (or changelist_2) > Jump to Source (F4) > Scroll to locate the change > Click on the change, and that indicate which chagelist owns the chunk


You see, 5 clicks are not fun :)

Especially when there are dozens of chunk changes to a file

The key is to be able to clearly differentiate (visualize) between,
- the changes that are not yet committed, but still stable
- and ongoing changes

Can we do this with changelist?

0

>  in the "Preview Diff" section it still shown as both chunk_1 and chunk_2 have changed

Preview diff shows only changes that belong to the current changelist (saying e.g. 1 changed (1 inactive) to indicate that there are other changes in the fie), with an ability to jump to another change.

If it shows you both changes, then they are probably not divided into changelists. If the changes are properly divided between changelists but diff does not indicate it - please submit an issue to 

Full diff indeed shows all changes, but changes of the current changelist are shown with a colored background, while changes of other changelist are shown with just colored borders. So there is a way to know which change is in which changelsit without the 5 clicks you described.

> The key is to be able to clearly differentiate (visualize) between. Can we do this with changelist? 

Yes, you can. E.g. consider Changelist_1 is stable and Changelist_2 is ongoing.

0
Avatar
Permanently deleted user

I think this whole discussion went off the rails a bit. The concept of a Changelist is a fine additional feature but it's not the same thing as the standard staging functionality in Git. I don't understand the insistence that developers familiar with Git have to change their workflow.

It is a reasonable request for a Git client to understand Git. Why not be able to stage lines, hunks, files, etc. like other clients? SourceTree for example, has excellent staging support.

Git interoperability is another important user experience issue. If I stage things via git command line... what happens in IntelliJ? Or if I use another git client? In all git supported client apps, they should do the same thing, because it's Git after all.

Here's an 8 year old issue: https://youtrack.jetbrains.com/issue/IDEA-63391 . Just support Git better, that's all that's being asked for. No need to push your changelists on everyone.

8

>> The key is to be able to clearly differentiate (visualize) between [...] Can we do this with changelist?

> Yes, you can. E.g. consider Changelist_1 is stable and Changelist_2 is ongoing.

I think this is not true in general. It works in the specific example above but let's look at another case. You may have made some changes, and everything is fine so far. To mark it as "stable", you put it into another Changelist as you have mentioned above. Now, you continue working. Since you are working on the same thing, there is a very high chance that you will touch the same chunk of code again. IntelliJ will put the changes on the chunk directly into the "stable" Changelist but everything else into "ongoing". By now, you have two Changelists which will not compile by their own and you might not even realize. By now, there is no way you can go back to the "stable" changes.

I worked with git before I have used IntelliJ. After starting to use IntelliJ, I tried to migrate to Changelists but my workflow seemed impossible to map. Therefore, I'm still using the cmd and ignore the feature of IntelliJ right now. It is a little bit annoying because I cannot use the nice diff-view from IntelliJ for the staging area, but it works better than using Changelists for me.

1
Avatar
Permanently deleted user

More than completely agree with @Nicolas Leblanc5. The git flow is bypassed by intellij behavior.

we have policy (and I am completely agree with it) in our company to use the IDE (eclipse, Intellij, VS code) only for comparing task, pre commit tasks. all the other actions are done in git bash (commit, fetch pull, push, rebase...) to prevent devs to simply click on button and checkboxs without understanding all the consequences... Intellij is the worst at this game as it completely change/rename the standard git flow.
See how it is simple to bypass the hooks on commit on Intellij (uncheck a checkbox) or change default pull config...
before this policy, we had multiple major git events and 95% of them were with intellij users.
Please allow us to prepare commit in the git way using intellij be adding files/part of files to stage area and to commit them using git bash.
chengeset intellij provide does not answer to the request as it is not available from git. BTW git allow and encourage you not to use this king of thing (changeset) and to use branches.

6

I sure agree with those calling for more synergy from IntelliJ with basic Git behaviors, especially staging. In pairing sessions, we use git staging when we get a pass from our current test, then we move on to either refactor or the next test.  Both of these tasks could have us making a mess out of our current (un-staged) code while trying to accomplish some possibly unreasonable goal.  With staging we simply say to git: throw away all those garbage changes and let's start again from the last point where all the tests worked.  Only after all the tests pass and we have 100% code coverage do we commit the final staged changes. This model works in a number of Git clients, including command line, Emacs and Vim. I'd give my first-born son for support of this workflow from IntellJ and Android Studio. Not to mention that my son is a damned decent software engineer! Deal? :-)

2
Avatar
Permanently deleted user

I couldn't agree more with some of the previous posters. As I see it it is really annoying having to explain to all new hires that we should never use the (in our case) rider version control implementation as it does not follow Git workflows. 
We adapted and are using Git for the simple reason of having a robust and consequent way of working with source code, not following the actual versioning software principles just does not make sense, I would completely understand this if you had your own versioning software but if a company is using Git they are most likely dependent on that the Git standard functionality and workflows are to be used. 

Please at least have an implementation that is just pure Git and compatible with the rest of the Git eco-system, then you can have your home grown abstraction of Git as an option for those who want it. 

For us it wont be possible to use this as we have the same need to have a consistent workflow to ensure quality of what we produce and different competencies at our company use different software, not everyone want to run your software. Even if it is awesome to work on code in, it is just horrible at versioning the code.

2
Avatar
Permanently deleted user

Soo, did nobody thought about hooks yet? There are tools that work pre-commit with the files that have been staged, like lint-staged. This is pretty much unusable with phpstorm when it skips the staging completely.

And there might be other git hook scenarios that expect changes in stage to work. It sound a bit like phpstorm makes a mean --no-verify or something else to skip such scenarios.

0

@...

The stage is not skipped, just not distinguished in the UI. Commit is done via stage. IntelliJ, and PhpStrom as well, first call git add for the selected files, and then git commit, so all hooks run and have stage to work with.

-3
Avatar
Permanently deleted user

So you have to add files to the stage via CLI or is there  something in phpstorm to add them to the stage? Otherwise it seems a bit of an all or nothing approach.

Following reports from my colleagues the husky pre-commit hook running lint-staged does not work.

0
Avatar
Permanently deleted user

Dmitriy Smirnov Confirmed, husky pre-commit hook running lint-staged does not work in Webstorm 2020.1.2

0

> is there something in phpstorm to add them to the stage?

IntelliJ-based IDEs add the changes you select in UI to stage automatically during the Commit operation.

You select some files or chunks in the Local Changest/diff with checkboxes, and call commit. Then IDE calls git add with respective options (or git update-index if only some chunks need to be committed), and after the staging area is ready, git commit is called. You can check the exact commands IDE uses in the Console tab of the Git (Version Control in earlier versions) toolwindow.

Here is a sample sequence from a test project:

15:57:23.419: [test] git -c credential.helper= -c core.quotepath=false -c log.showSignature=false add --ignore-errors -A -f -- src/com/company/Main.java
15:57:23.456: [test] git -c credential.helper= -c core.quotepath=false -c log.showSignature=false commit -F /private/var/folders/m9/rlw07bcd68519gg_px55hcdm0000gp/T/git-commit-msg-1.txt --
[master 406eb94] Some change
1 file changed, 1 insertion(+), 1 deletion(-)

As you can see, it is the same sequence of commands one would use in CLI to stage and commit a file. No flags to skip hooks or something. So if git is configured to run hooks - it should.

There is an option to skip hooks in the Commit UI - the Run git hooks checkbox. However, it is always enabled by default and needs to be explicitly disabled on every commit. Disabling it adds the --no-verify flag to the commit command.

Husky hooks, however, depend on node, and it could happen that is not properly inherited or misconfigured  . https://github.com/typicode/husky#node-version-managers

If properly setup, Husky hook runs correctly for git commands called by the IDE - here is sample output of the Console from my project:

01:52:22.798: [YT workflows] git -c credential.helper= -c core.quotepath=false -c log.showSignature=false add --ignore-errors -A -f -- "ZD links.js"
01:52:22.810: [YT workflows] git -c credential.helper= -c core.quotepath=false -c log.showSignature=false commit -F /private/var/folders/m9/rlw07bcd68519gg_px55hcdm0000gp/T/git-commit-msg-.txt --
husky > pre-commit (node v13.10.1)
⚠ Some of your tasks use `git add` command. Please remove it from the config since all modifications made by tasks will be automatically added to the git commit index.
[STARTED] Preparing...
[SUCCESS] Preparing...
[STARTED] Running tasks...
[STARTED] Running tasks for *.{js,jsx}
[STARTED] Running tasks for src/**/*.scss
[STARTED] eslint . --fix
[FAILED] eslint . --fix [ENOENT]
[FAILED] eslint . --fix [ENOENT]
[SUCCESS] Running tasks...
[STARTED] Applying modifications...
[STARTED] Reverting to original state because of errors...
[SUCCESS] Reverting to original state because of errors...
[STARTED] Cleaning up...
[SUCCESS] Cleaning up...
✖ eslint . --fix failed without output (ENOENT).
husky > pre-commit hook failed (add --no-verify to bypass)
0

Dmitriy Smirnov - the issue I have with this is that I want to run my pre-commit hooks before the commit operation, so that I can check my code linting etc. as I go along, not just during commit. pre-commit in particular, which is very popular in the Python domain right now, supports this approach, but it will stash any changes that are not staged so that it can check only those changes which are going into the current commit (as it should). So I can't run e.g. pylint via pre-commit with PyCharm except as part of making a commit, whereas I want to run it during development so I can fix things up as I go along, not have to make a big bundle of changes at the last stage of committing.

It would therefore be really helpful if all the changes in the current changelist could be kept in sync with the git stage, to support this paradigm. I don't see why it would be an insurmountable problem to look at changes to the current changelist and map them onto the staging area?

0

Please sign in to leave a comment.