8 ms·
Having taught git several times within a data science course I find two concepts especially worth extra time: WHY there is a staging area, and what is the diffe
by bagrow 8y ago
Having taught git several times within a data science course I find two concepts especially worth extra time: WHY there is a staging area, and what is the difference between “git” and “github”.
- radarsat1 8y ago> WHY there is a staging area I understand your second point, but I have a hard time understanding the difficulty with this part. Why is it hard for people to understand the idea of staging? You put things in a box one at a time before closing the box. Does it require more explanation than that? What do people find difficult about it?
- altairiumblue 8y agoIsn't the staging area closer to an intermediary box? That's where it can get confusing.
- detaro 8y agoStaging puts things in the box, commit closes the box, puts it on the pile with the other boxes, and gives you a new empty staging box.
- Double_a_92 8y agoBut why is it an extra step? It's basically just a "longterm" selection of what you want to commit.
- detaro 8y agoBecause you not always want to put everything in the box (and if you do, there's a shortcut to do it), and "git commit file1 folder/folder/ * .cpp folder/folder/ * .h ..." for a complex set would be annoying and require you to mentally keep track of it from the beginning. Many beginners will start by always doing "git commit -a" and that's fine, as long as they know there's an alternative once they need it.
- url00 8y agoBut why is the exceptional case the default? Surely, most of the time when you go to commit, it's all the files you've changed?
- IggleSniggle 8y agoNot for me! I often find myself refactoring tangential features while producing a new one. Sometimes that will even intersect in a single file. But that refactoring doesn't come with any changes relevant to the feature I am working on in my branch. So I save them for their own isolated commit(s). While this doesn't happen on every commit, it probably happens for me about every other push. The alternative is bundling in a bunch of changes that have very little to do with the feature that my branch is ostensibly about. EDIT: Now that I think about it, I also have several repos where I have changes that I never intend to ever commit them, because they are development conveniences for me personally.
- Accacin 8y agoSame for me! Webpack config changes to cache settings, config changes to hit a different API for testing, using a different database for testing. Most of these live in my staging area and get stashed and popped when I switch branches/rebase.
- elcomet 8y agoAlmost never actually. I never commit all the changes in my repo (for big projects I often have some small changes in other places, I don't want to commit them)
- Accacin 8y agoNot really. I think of my git use case at work pretty simple. I usually stash, pull down, fast-foward and then pop my stash on top. Occasionally I'll need to rebase too. Just to show I'm not a super advanced user or anything. I'm a JS dev mainly working in React on a web app with a backend team using PHP. Often I'll be working on a branch with maybe 2 or 3 people and I often end up working on a few things at a time. Say I'm working on a feature, and I notice some bug I'll fix that and then get on with my feature. Once I go to commit I pretty much always do a 'git add . -p' and I very rarely want to add all the files I've worked on! Even things like switching a config file to use a service like apiary where I don't want to commit my change to the config to use apiary.. Or change to my webpack config for testing, etc. I've used Perforce, SVN and Git and the whole 'staging' area thing always felt very natural to me. Here are the files you've edited, which ones want to be commited? It gives me a second chance to go through and check everything before I've commited, and often that stops me leaving in any odd comments or debug code.
- Gys 8y agoFor simple projects (like ppl experimenting with git) you will always want to save all changes. So why stage first ?
- tux1968 8y agoNot everyone stays a beginner forever, and it's nice to have a tool that doesn't play to the lowest common denominator. It's really not that hard to just do a "git commit -a" if you want to avoid staging.
- oblio 8y ago> Not everyone stays a beginner forever But the vast majority do, or at best become perpetual intermediates (https://blog.codinghorror.com/defending-perpetual-intermediacy/ https://blog.codinghorror.com/defending-perpetual-intermedia...). 99% of developers out there didn't need a power tool for source control (source control is already quite a power tool many devs can barely handle, even in SVN form...), yet here we are: Git is imposed everywhere, with its horrible UX.
- tux1968 8y agoGit's UX isn't that bad if you're only cloning projects to build them locally and keep them updated. The UX only gets really crufty as you use more and more of the features.
- scrollaway 8y agoUnderstanding the staging area first requires understanding the need for it: The need for atomic commits. The need to create commits that have specific changes in them and are not always a snapshot of the entire world below the git root exactly as is right now.
- pjc50 8y agoPeople are very used to the web "save always" style: There is one document, and you're editing it. Most people will be familiar with the traditional desktop "save" model where you have to do something to make your changes permanent. People often then learn that there is a local file and some remote file: they can cope with a save -> upload workflow. Lots of traditional VCS turn this into a save -> commit workflow. Git adds two stages to this that people can't see the need for without understanding the internals: an extra step between save and commit, and an extra step after commit. (The discussion reminds me of all those people who think that if they just start by talking about monads then people will find Haskell easy and natural...)
- rakoo 8y agoThe don't need to understand the internals for this: just knowing that every save you do will be stored forever as-is makes you double-think about what you put inside
- doubleunplussed 8y agoThere are a whole bunch of layers now, though they're all useful. 1. Is my document saved? 2. Are the changes staged? 3. Are the changed committed? 4. Are the changes pushed to my fork on e.g. github? 5. Are the changes merged into the upstream repository on e.g. github?
- JediWing 8y agoSo I have a solid mental of git, and I understand the theoretical need for the staging area. However, I find the occasions for using the staging area in practice are few and far between, for the simple reason that I can't test and execute the code that's in the staging area without also having the code from the working directory also be there. It feels like after having partially staged some of my working directory, it would be a blind commit with no guarantee that things are working. Very rare is the situation that I can break out a list of files over here that are for feature A and some over there for feature B, and never the two shall interact. I think this is probably what most struggle with regarding the staging area, without being able to articulate it.
- aurumpotest 8y agoI use it quite a lot, especially with `git add -p` to stage only parts of a file for an atomic commit.
- url00 8y agoThis has never made sense to me. I've seen others say that they commit only parts of a file. How does this scenario start? Are you working on solving one problem, but then notice some other unrelated issue and fix that too, before committing the first change?
- acemarke 8y agoPartly, yes. Or, I'll be working on a task overall, and have to touch multiple files in the process. Then when I'm ready to commit, I review all the modified files on disk, and look for ways to break those down into smaller discrete logical changes. I prefer to avoid "big bang" commits as much as possible, because smaller individual commits are easier to inspect, easier to back out if necessary, and provide a better "story" when inspecting a file's history sometime down the road.
- Someone 8y agoBut then, you either never run/tested those smaller individual commits, or you have to do extra work (stash changes, test, restore stash) to do that. I do not see why a source control system should make it easier to make a commit that hasn’t ever existed on disk and thus cannot have been tested. I think the better model would be to stash your changes and have an diff editor between the on-disk working copy and the stashed version that allows you to commit a set of changes as several smaller, more coherent commits. That wouldn’t guarantee that each of those intermediate commits gets tested or even built, but it would guarantee that each smaller commit is in the on-disk copy at some time.
- fdsak 8y agoprobably related changes grouped together
- tokyodude 8y agoMy hurdle was 15-20yrs of no staging area from previous VCSes so the extra step took some time to understand why it was needed.
- allenu 8y agoI think people find it difficult because for most beginners at git, they just want to put everything in the box. Having the option to put just some things in the box seems more complicated than needed. Obviously, as you get better with the tool, you realize the power of literally "staging" your changes into multiple commits, but as beginner, it's not even in your purview.
- recursive 8y agoYes, it requires more explanation than that. I've used git for years, and never really understood why staging is even a thing. Your example is an implementation of the box-putting algorithm, but it doesn't need to be mirrored in the put-box CLI. put-close-box file1 file2 This command could encompass all the putting and closing. Since you only close boxes when you are done putting things in it, I don't see a need or purpose to split it up. put-box file1 file2 close-box A closed box (commit) is always going to contain stuff that was put in it, so why separate commands?
- ezrast 8y agoThat's not convenient when you're putting things into the box piecemeal, especially with `git add -p`. A thing I do frequently is to run `git diff`, scan through it, and add files (or parts of files) one by one in a second terminal. Then I do a final review of the staging area (with `git diff --cached`) to make sure it only has the changes I want and commit. I'm the sole devops engineer at my company and my workflow is a bit more scattered than a typical developer's. Anyway, `git commit file1 file2` by itself is most of the way to being the put-close-box function you want; it just doesn't work for adding/deleting files from the repo. Seems like they could make a lot of people happy by closing that gap and letting `git add` be an intermediate-level feature.
- recursive 8y agoTo me, that ought to be a concern of the "porcelain", although no one uses that word anymore. CLI is particularly bad at certain types of interaction. So to compensate, a mitigation is moved into the underlying model of git. That mitigation is staging. The inconvenience of "piecemeal adding" could have easily been addressed in the UI layer using a more suitable presentation, rather than forcing all clients to follow the stage/commit dichotomy.
- jordigh 8y agoThe staging area is really an extraneous concept that isn't required. It's like a commit that isn't a commit. In Mercurial, I much prefer to just make it an actual commit in the draft phase (the default phase) and just keep rewriting that commit. Mercurial provides tools for both selectively adding and removing hunks from a commit (both `hg amend` and `hg uncommit` accept --interactive for hunk selection). If you're extra paranoid, you can make it a commit in the secret phase so it's not shared prematurely by accident. It's pretty much functionally equivalent and doesn't require an extra location in which your code can be. It's either in your working directory or in a commit. A bonus of this approach is that now you have a meta-history, hidden by default, of what you've "staged" and "unstaged". It's kind of like a reflog but with, in my opinion, a better UI. And of course, the index/cache/staging area in git doesn't use refs, so there's no reflog there.
- nlawalker 8y agoI've helped move a couple teams (kicking and screaming) from TFS to git, and I start back even further than that - why is it so much more complicated than clicking a button to save and share my work, and what is the benefit of that complication?
- tome 8y agoI'm very experienced with git, approaching expert level, and I don't use the staging area. I use git commit --verbose --patch and bypass the staging area entirely. I don't find it helpful.