0

This feels like a question I should be able to find already answered but I can't seem to find one and I imagine many posts I've read actually intended to ask what I'm about to try and explain. I'm using VSCode, I have Gitlense if that matters.

I'm a former CVS user. I like git much better... except merging changes. I might have been spoiled by the CVS gui or something:

When I had made local changes that differed from what was in my CVS repo I was able to view the diff just like git: the repo copy on the left and my working copy on the right. Totally makes sense. The lines in the diff were marked differently (the questions I've been able to find) but what I really miss is the ability to CLICK on a change and MOVE it over to the working copy or ignore it. After I had merged these changes I could then check in my changed file.

In git, what I'm finding is... First of all, I can't pull if I have local changes. I have to stash them, the pull, then pop, then diff. I can view the diff as I'm familiar with. Then if I see a change, I'm not allowed to modify my working copy in the diff tool. I have to copy from the diff, goto my working copy, paste the change, go back to the diff and continue scrolling line for line.

Is there a tool or a step I'm missing? I simply want to click a button and move the changes over to the working copy. I'm ok with stash then pop but it seems a little silly to do it every time.

Just now I had to stash over 20 files, pull a whole bunch, and I'm about to do the stash pop and resign myself to spending the day merging changes. Is there an easier way?

  • Sounds like you have a workflow problem. Who is pushing conflicting changes on the same branch and files as you're working on, why aren't you working on separate branches? And why would CVS allow you to look at incoming commits, and say "nah I don't need that" (not clicking the relevant files or lines) and then act as if that's the new truth, basically rewriting history and ignoring your coworkers' changes? Also, you might be interested in the config: `git config --global pull.rebase true`, and `git config --global rebase.autoStash true`. Then your pulls will be rebases and auto-stash. – CodeCaster Dec 16 '21 at 15:34

2 Answers2

1

Firstly, neither CVS nor Git has a single standard GUI, so the reference to "clicking" suggests that part of the difference is not between CVS and Git but between the GUI tools which you have used. There are many GUIs for Git, and integrations with IDEs, of varying quality and complexity. So, for that part, the real question is probably "how do I find a better Git GUI?" (The answer is to search around for one you like the look of and try it out.)

Secondly, git places a much bigger emphasis on commits and branches, rather than files and changes. Branches in git are cheap, and it's common to create new branches every single day.

So the process you're describing with local and remote changes is generally managed in git with multiple branches, and merging between them:

  1. You create a branch "feature-123", and commit your changes as you go
  2. Your colleague creates a different branch "feature-456".
  3. Your colleague finishes first, and merges "feature-456" into a shared branch (e.g. "main", "master", or "develop").
  4. To fetch their changes, you first commit what you have so far, then use "git pull" to merge the shared branch ("main"/"master"/"develop") into your working branch ("feature-123").
  5. At this point, you are presented with the conflicts between the two branches, resolve them, and commit the result.

You might occasionally use "stash" instead of "commit" at step 4, but it would be the exception rather than the rule.

You might also prefer to use "rebase" instead of "merge", but the result is similar.

The crucial part is that two people rarely commit directly to the same branch. Each developer commits to their own branch, and shares it in some way - often using a "Pull Request" or "Merge Request" on some central server like Github, GitLab, BitBucket, etc.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
0

Let me give a more coming-from-CVS-centric answer.

All of the other answers (so far) are correct. But coming from a CVS background, there are times when being told "you're not doing it right" is helpful, and there are times when it is less so.

@IMSoP's comment about GUIs is 100% correct. CVS is a command-line tool. Git is a command-line tool. They each have GUIs that you can use for resolving conflicts. Some GUIs like meld or kdiff3 can be used in either CVS or git. You will need to research the tool that works best for you.

You can indeed continue to work in the same way you've always worked. You edit your files, and periodically git pull from upstream and those upstream commits are either automagically seamlessly pulled into your workspace or you have conflicts to resolve.

The following configurations will set that up for you.

git config pull.rebase true
git config rebase.autoStash true

If you are working on code that gets compiled, this can be problematic as you have suddenly re-touched all the modified files in your workspace and your build system (e.g. gnu make) may see them as changed and cause recompiles. In this case, you may want to create a wrapper script (perhaps call it git-up (*) to mirror cvs up that finds all modified files, notes their timestamps, stashes, pulls, pops the stash, and re-touches your files with the old timestamps for all files that did not get updated from the incoming changes.

For a far more detailed explanation, I suggest you read this StackOverflow answer.

(*): If you put git-up in your path, it can be called like any git command as git up (no dash). Git magic.

Mort
  • 3,379
  • 1
  • 25
  • 40