Adding says to git “this is a file I want you to pay attention to” (you only have to do this once). Committing says “I made a change to the file I want you to remember.”. Pushing says “I want you to send this change to the master repo.” No need to push if everything is local.
Ah. I hadn’t understood that - I thought I needed to add each time. Thanks!
I took a class on webdesign last year and used the desktop client to upload projects. As someone whose knowledge level is very basic I found it extremely easy to use - not the deep git experience but it gets the job done.
Well, sort of. I’m just going to be explicit on the offchange there’s a misunderstanding.
So: initially, files aren’t tracked by git. If, in a git repository with one file that I’m not tracking, I type
git status, I get this:
> git status On branch master Initial commit Untracked files: (use "git add <file>..." to include in what will be committed) text.md
So: let’s add it:
> git add text.md > git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: text.md
OK, so that file is now going to be tracked as a new file. It’s not commited yet - it will be added when I commit:
> git commit -m "First commit." [master (root-commit) 2c0836a] First commit. 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 text.md
Now, if I alter that file, and then look at the status:
> git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: text.md no changes added to commit (use "git add" and/or "git commit -a")
So: the file is modified, and because git is tracking it, it’s picked up automatically. But: if I do a commit, nothing will be added. You have to add the file to the current index in order for it to be committed. Say there’s another file I’ve also altered in there, called
> git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: moretext.md modified: text.md no changes added to commit (use "git add" and/or "git commit -a")
They’re both marked as modified. I want to commit the changes to
text.md, but not the ones to
add one, but not the other:
> git add text.md > git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: text.md Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: moretext.md
Can you see? The file I’ve
added is going to be staged for commit; the file I haven’t won’t. If I do a
git commit now, only one file will go out.
This is also true of the GUI versions: you don’t automatically commit everything you’ve altered, unless you want to. You choose precisely what goes into each commit.
Now, having made your way through all that terminal guff, here’s the really useful metaphor: I like to think of the working index as a dumb waiter. I have all this food kicking around, but I only want the stuff I’ve finished to go up. So I stage it all, using
git add, onto the dumb waiter, and then my
commit sends only that out.
add adds a file to be tracked and stages it; future
adds are just staging those changes.
Incidentally, this talk - Git for Humans is a really good, clear explanation of git for a technical-but-not-necessarily-programmers audience. (Audio of Alice delivering it is online here).
I found this super useful too as we get into the “HOLY SHIT, I’M GOING TO RUIN EVERYTHING” territory:
I’ve only used Git a little bit and mostly through the client with a GUI but I’ve been using Perforce at work for quite a long time (also with the visual client, P4v). I’m a programmer but not a fan of command lines-driven tools .
Does anyone know a good “Git for Perforce users” page/article/documentation ?
Looks like somebody wrote a book about it.
Awesome, thanks for the link .
A quick note on why I tend to talk about Git with command-line tools:
Git is weird in many ways, especially if you’re used to non-distributed version control like Subversion or Perforce. Most of the desktop implementations - even the GitHub GUI - abstract certain things away. This is entirely understandable: GUIs are abstractions, and most of the time this is for the better. GitHub desktop does a lot of what most people need, it’s clear and friendly, focuses on GitHub-specific interactions like pull requests, and so forth.
And yet: whenever anything unusual has happened, or I’ve needed to work out what the hell is going on, or I need functionality they hide (GitHub Desktop has no
stash!), these UIs fail me a little. This is especially true once you start getting into heavy branch/merge/rebase territory, in my opinion; the first time you discover that you are
(not currently on any branch), for instance, is an existential crisis that fails most GUIs’ abstractions.
So I pick the tool that has no abstraction, and is a bit ugly and hard to use, but is also clearer at all times about what is going on under the abstractions - and the knowledge from which can usually be applied to whichever GUI you’ve chosen to use.
(Also: copying what I usually do, versus screengrabbing something foreign, was faster when it was basically bedtime).
Annoying discovery: the process I would recommend for tracking an upstream branch, which is how I work on docs, and how I’d work on Norns… doesn’t work in Github Desktop:
This is infuriating and means making a visual guide will be way harder than I’d like.
Maybe sourcetree is a useful alternative? https://www.sourcetreeapp.com
No experience with it though, since I agree with you and use git from the cli. I’d suggest anyone who wants to use git to do the same, once you get going it’s so much faster and clearer/easier to understand how it actually works
I am a bit late with a recommendation (and lots of cool stuff already posted, especially the Github for Poets videos!!) but as someone who only recently got stuck into git for the first time I found the free Codecademy course quite useful (https://www.codecademy.com/learn/learn-git) as it lets you have a go in a dummy terminal and get a sense of the results.
I’ve used SourceTree in the past, I’d still be using it if it was available for Linux.
I’d say it’s more aimed at people that are already comfortable with Git on the command line. I personally used it for viewing diffs (GUIs are better for this IMO) and for interactively staging hunks (handy for reviewing a big commit).
I also used it quite a bit on Windows as CLIs never fit my flow on that OS.
From what I recall the GitHub client is good for new users because it hides so much stuff, SourceTree doesn’t hide anything.
@infovore at least it has support for an
upstream repo! It had no support for any remote originally, from my experience teaching people to
upstream/master is one of the bigger pain points with Git, and it’s also the best reason to get people to work on a feature branch.
“interactively staging hunks” is a lovely phrase
I’ve been happy with GitKraken https://www.gitkraken.com/ (former github desktop and sourcetree user). the visuals are great for really seeing what’s going on (esp in large projects w/ many collaborators) and it doesn’t hide much/any functionality that I’ve found. I would recommend it for beginners.
My experience too. That being said, my initial exposure to Git GUI stuff was the Eclipse IDE plugins in school. So that may also be some bias I have.
I have been exploring the switch from atom to vs code this past week, and I do have to say I like the integrated diff pane and using it as interactive
git adding. It’s a bet more featured than
git add -p (though that is still a great little tool). edit: Still use command-line for all the other stuff. I have to do GPG verification of commits for another project I work on, and this breaks vs code’s commit feature in the GUI pane, probably most other GUIs too.
also random thought for people who are new to git:
git add . and other ways of not interactively checking what you are staging with
git add and staging stuff all at once for commit has ended up biting me and causing a lot of the wonky state stuff infovore is talking about).
It may not be as up to date, but I really like this little chrome extension. It reminds me a bit of the teletype cheatsheet.
i use https://gitextensions.github.io/ - it’s a windows UI (but can run on other platforms via mono). having a visual tree representation really helped figuring out what some of the commands do and, surprisingly, encouraged me to use command-line tools more often. try using git commands wherever possible and use a UI to visually confirm what effect that command had - this really speeds up understanding. i still prefer to do commits via the UI, i like to double check everything before committing (and to make sure all the
print("wtf") have been removed…) and i like how it shows diffs.
one thing that was helpful in the beginning:
git fetch grabs the latest updates from github (or wherever the remote repository lives) to your local copy.
git merge can then be used to merge those changes into your local branches.
git pull does both, for convenience. until you do
git fetch your local repo won’t “know” about the latest updates posted by other contributors, and until you do
git merge the changes will not be applied to your local branch. if you use Git Extensions try doing a
git fetch, then refresh the UI and you will see exactly what is happening.
a possibly useful metaphor: imagine the remote repository as the main office of some company, and your local repo copy as a regional branch.
git fetch - check if there were any new instructions from the main office and get them
git merge - apply those instructions
git commit - prepare your local instructions for the main office to be mailed
git push - mail them to the main office
using this metaphor, until you send your response to the main office (“push”) you can always cancel it (“unstage” in git terms). “commits” in this sense are like separate envelopes. you could create several of them for different changes, and then push them all at once.
There’s an old document called git from the bottom up that helped me. It requires an understanding of a cryptographic hash but not much else.
Here’s a good cheat sheet I keep on my desk.
FWIW, the same drop down can show tags
I can’t agree with this more. I’ve slowly weaned myself off of it and onto the CLI (of necessity), but IMO Gitkraken is the best visual representation/tool I’ve found (and I’ve looked at a lot). I still use it when I a) need a visual representation of the whole history, and b) need to quickly jump around to different files/commits; there’s simply no way a CLI can match this.
EDIT: I feel like I should mention that Gitkraken runs equally well on all modern platforms (well, not iOS or Android, but you know what I mean )
Shameless plug; I have a cheat sheet of my own - "
git Beyond The Basics, or What You Need To Know To REALLY Fuck Things Up"
It’s a bit random, and applies to what I need to remember for day-to-day work, but it captures some of the things I really wish someone had told me just after I learned the basics.
PRs, issues, comments (and CORRECTIONS, for sure!) are all welcome (the irony/recursive nature of that statement is not lost on me ).