I think anyone who uses the CLI is either trying too hard or hasn't realized the beauty of a git GUI.
- My commit time is usually much faster than coworkers, with higher accuracy (less frequent accidental commits, etc.)
- I don't remember the last time I made an irreversible change to the repo, or had an "oh shit" moment. And that's despite using some interesting git features.
- Staging individual files, folders, lines of code, or hunks is easy. Makes maintaining multiple trains of though / addressing bugs while working on other code a non-issue.
- It's easy to keep files uncommitted for long periods of time intentionally, without slowing down my workflow.
- It's much easier to get an overview of the changes I'm making.
When I've tried GUI's, I'm not 100% sure what's going on under the covers. Sometimes they try to obfuscate things. While I'm probably not the worlds most advanced user, I know enough to know what I want to do, and how to do it. The CLI let's me do it. The GUI get's in my way.
The one exception to this I've found is GitUp (mac only, sadly), and it's excellent. It's whole model is, "what operations can I perform on this graph," which is exactly the model git has. It's great.
Pick the right tool for the right job, man.
Joking aside, think about the ratio of tasks. Most of the git commands I do is deadly simple. There might be once-in-a-year complex tasks that are more suitable to CLI, but for 99% of the tasks I think GUI could have a net gain in total. Although I'm not a GUI user in this particular case, I'd advocate to use whatever most intuitive to you when possible.
Disclaimer: I don't think C syntax is that bad.
It looks like you mindlessly associate a CLI with a poor -- or suboptimal -- user experience. In fact even your choice of weasel words conveys the idea that you want to mindlessly push an irrational belief in spite of not being able to provide arguments to support it. The truth of the matter is that git -- or any other VCS -- operated through commands that change the current state of the repo. The command line interface excels when the user wants to run commands. Any GUI developed for command line tool will end up doing nothing more than replicate what the CLI already does, and will do so poorly.
Put another way, Git is a process that can be rendered pictorially. Words (i.e., CLI) are a less intuitive abstraction.
Pardon me for stating the obvious :)
Understanding that git reset --soft moves HEAD but doesn't change the staged snapshot or working directory, whilst --mixed updates the staged snapshot to match the commit but doesn't touch the working directory was very useful. And knowing that reset --hard updates both staging and the working directory to the commit was where I suddenly "got it".
No way. Only if you define “good” as “good at the kind of project that git is good at,” where it will hold vacuously.
I suffer daily through the cyst that is git LFS, and it’s a joke. It would be funny if it weren’t so tragic. I hear that it’s not doing any better in large scale mono repo land. Google doesn’t use it, afaik. Microsoft does (but multi repo, last I heard), Facebook doesn’t (custom Mercurial, some tasty quotes at ). Not a glowing “fundamentally better”, exactly.
2. Microsoft uses Git in single large-scale mono repo form, for - believe it or not - Windows. It clocks in at about 3.5 million files, and a full clone weighs in at 300GB:
They had to change git itself to be able to do that. So no, the article itself shows it was not ready for that big a repository.
That’s my point: without LFS it’s even worse to work with large files. If LFS is the best option you have, forget it. That’s an entire area of projects (anything with assets) you can’t use Git for.
Pretty cool stuff. Doesn't seem to address the large-files case so much as the many-files case, though. I would love better git support for large files.
That's why I end up using the plumbing commands to do things that porcelain commands don't let me do directly. For example, I'll use git diff along with git apply and recountdiff (from the patchutils package) to stage individual hunks or edit hunks prior to staging.
git porcelain is a CLI. I am well aware that it is only a subset of git's CLI.
This looks fantastic, thanks for mentioning it! I've been looking for a GUI that doesn't mesh poorly with [whatever patterns my team uses] / without always pushing other features or a signup.
I use CLI for almost everything but sometimes it helps to have a visual representation of the repo.
it's reasonably fast until I throw it at a huge monorepo :) but it still works (~2fps)! even `gitk` errors on this one.
missing some hotkeys (like prev/next commit buttons in preview)
freezes on remote-repo actions like fetch/pull/etc. likely due to our enterprisey ssh setup.
generally missing a bit of polish. click targets are small, could use some more config (and only in one location, "search commits" is in its own thing), etc
If I can figure out how to fix the remote freeze-up, it might become my daily driver, which would be a first for a Git GUI.
I hadn't thought about the prev/next preview missing hotkeys, but you're right. I realized what I do is go into preview with space, leave preview with space, and then use the arrow keys to select the next commit I'm interested in. So in effect, "space, down, space" is hotkey for next commit.
Bummer about the remote freeze thing. I think the dev is reasonably responsive to bug reports.
I've got a list of things myself I think could be better, but I've been too lazy to attempt any of them. But I do try to proselytize in the hopes it'll pick up a bigger community. :-)
A gui with drag-and-drop to rebase a graph also seems like it would work well...
The best one, I think, being Magit for Emacs (if you can call that a 'GUI' given you can run it in the terminal).
If you get used to commit things by-line instead of by-file (which is generally highly recommended with git), and also clean up your history/squash things a lot, using git cli gets VERY tedious very fast; I'd rather do it in several keypresses because why not.
But that still doesn't help explain its benefits to someone who hasn't tried it. For the crowdfunding campaign that I ran earlier this year I wrote a few articles. For those unfamiliar with Magit I would recommend  and the more visual .
> It's Achilles' heel is speed, though -- too damn slow. (Last time I tried it, anyway, which was a while ago.)
Don't remember a single of case of it feeling too slow in the last few years, whether on linux/mac... (maybe it just got better over time though)
I also plan to make Magit faster across all platforms.
It seems like the sort of ui that needs to be near-instant in order to be usable, the premise being you can tap the various shortcuts to assemble a command very rapidly. But on windows this is an exercise in frustration because each command takes at least a second or two at best to execute and often much longer.
I think that the distinction that makes a Commnad Line Interface is the REPL.
I consider anything with a non-linear UI that you can see a GUI.
This. A thousand times over. I like to see exactly what git is doing and when; I don't want any magic stuff under the covers done for me.
As soon as I saw that button I knew I'd have trouble using it.. what will "sync" do? Push my branches? Pull tracking branches? Will merge commits get implicitly created? Or will it just fetch? From what servers? I didn't want to risk having my local master get pushed into production just because GH wants to make things easy for me, so I just quit it and went back to the CLI.
Personally, I use the CLI and often have no idea what I'm doing ;)
A GUI works fine if you want to get things done. If you like to know what goes on under the hood, it's just confuse you.
It's pretty sweet that GitExtensions displays the exact command executed. Actually, it made learning vastly easier for the people I taught after myself.
Some people do better with GUIs; others the CLI.
One example of this is the table at the bottom of this page: https://git-scm.com/blog/2011/07/11/reset.html
I do like the Gitx-dev fork by Rowanj . Clean and simple. Unfortunately just for Mac OS though.
To make matters worse, what in a Mac GUI would be called “Revert” or “Discard Changes” is called “Discard”, something that, to me, feels more destructive than it is.
End effect? We have “Discard” being less destructive than “Remove”, while, to me, it feels the other way around.
(I may remember this wrong, but if I do, I think that’s a sign of the problem of not following platform conventions in your software)
Still hoping for a git repl that just does graph queries/transformations though.
Staging, especially partially staging hunks and lines when doing multiple things at once, is way easier in a GUI when you can scroll around for context and easily undo.
For everything else I prefer the command line, because it's faster and I know exactly what is going to happen. I can do what I need to do, no fighting. If I'm just committing everything, I use the CLI. If it's more complicated I use the GUI to stage and commit, and a CLI to rebase/merge/push.
No thanks, it’s CLI for me, regardless if the IDE promises git support.
As long as all you're doing is pull, branch, merge and commit, I don't think it matters.
I use one or more GUIs for visualizing branches, and old branch cleanup, and yes, committing single lines from hunks that can't be split.
However for everything else CLI is fairly close to optimal, including interactive adding/rebasing, and don't want to use whatever shitty editor your tool has in it, I want to use vim with syntax highlighting so I can properly format my commit messages. Even something as simple as viewing a full commit is faster in the CLI because you can just pipe it to less or send it to an editor versus whatever tradeoffs a GUI has to make to stay performant, make use of screen space, etc.
One last tool is Fugitive. This blows away anything else I've ever seen for interactively traversing history at the line level.
Could you elaborate here? Personally I've always been able to commit just the pieces I need via `git add -p`. Never had problems staging a single line before.
Since this is text I should say: I'm not doubting you, I just like to know the limitations of the tools I'm using.
E.g. if you have two consecutive lines changed, it's not possible to split them, they are one "hunk".
(Waiting for someone to chime in with how to split a hunk and change my life).
In there you can remove added lines (prefixed by '+') by removing them, and re-adding removed lines (prefixed by '-') by replacing the '-' with a space ' '.
You can also use 'e' option to edit the hunk to e.g. remove one of the added line.
Nothing as easy as clicking a line in a GUI though.
So even though I edit in vim, I jump back to emacs for magit for bigger commits or multiple smaller commits (where I need to see diffs to be sure I capture my changes).
I have desired something as useful in vim, but I didn't think there was anything. I'll take another look at fugitive.
As soon I started to work with git, I installed fugitive. My learning curve of fugitive has been slow, and I have never be able to stage efficiently with it.
And then, a colleague showed me magit: I waited for a year that something similar comes to vim, trying to push this idea to fugitive https://github.com/tpope/vim-fugitive/issues/569 , without success.
Finally, some first experiments showed that partial hunk stage was feasible, and I created vimagit.
As you will see, it is far from whole magit features. For the moment, it "only" focuses on stage/unstage and commit feature (which is the main use case to me). The current workflow is quite robust: you can easily navigate through all the diffs to review them, stage by file/hunk/line/part of line, write the commit message (or amend the last commit), jump to the diff locations in their files... I continue to use fugitive for Gblame and Gdiff.
Next major features should be git stash (be able to prepare a stash like a commit, by file/hunk/line) and some git log related feature (to easily git commit --fixup a chosen commit in a log for example).
All that said, I don't really use it for committing, mostly because I have a shell open right next to the editor anyway.
Sorry if I'm being think, but how do you do that? Are you talking about Gblame?
- It's a live dashboard. A GUI gives me live, persistent information organized well on the screen. I appreciate the power of the CLI for accomplishing tasks, but I've never understood how people prefer it when it comes to simply viewing and understanding the state of something. I don't see why I'd want to run a bunch of commands to see stuff scroll by in my format-constrained terminal when I can have a live, all-up view of multiple aspects of a repo all at once, with relevant, context-sensitive commands on whatever I click on.
- It's discoverable. Most of what I've learned about git has been through clicking around in Git Extensions.
- The structure and organization of the UI helps me to understand how git operates. When I open the "Pull" dialog, for example, the way the controls in the UI are grouped and the kinds of controls that are used help me logically understand what "Pull" can do.
It doesn't have all the bells and whistles of a GUI, but if you need to look at all the branches, and commits to a repository. tig is an excellent tool. tig doesn't issue any commands though, its only a browser, you'll still need to know the CLI. (essentially a ncurses version of gitk)
I'm normally in a ssh session on a remote box where my compile & run cycles happen. tig is curses based, so no X11 needed, filled in a really nice itch of mine.
- Open source (and free)
The one with the best usability was Git Extensions: https://github.com/gitextensions/gitextensions
It is somewhat old ugly, and open a little too much of dialogs, but the workflow really works. It guides you to make the right thing.
A great plus is that it already comes with Kdiff3, a great open source 3 way diff open source program.
I think maybe the term you're looking for is "freeware"?
It's impossible to sing those names loudly enough.
I've only had to merge a branch once, and here I was completely confused on what was going end. This may be SourceTree's fault or git's fault. Maybe my lack of understanding.
I hate git, I don't understand git, I don't want to have to understand git, and I think the command line interface makes every UI error in the book. But SourceTree has made me like git.
I really like Magit, which is a git GUI you can use without leaving Emacs. It handles 90% of my git needs and is very tightly integrated into my IDE (Emacs). I still use some shell commands (like git mv) occasionally but those are simply m-! away.
It treats my "assume everything works like vim" habit well
If we take Ranger for example, who calls itself the "CLI file manager", then Magit is rather a "git CLI".
Why? It is designed for git and graphically displays revisions allowing you to pick and chose chunks of file and to revert individual changes.
It's also free for hobby / open source
but worth buying for commerical work, but it is pricey, and I think getting the lifelong updates is the way to go.
Or, you know, understands and thinks in the semantics of the underlying tool and is already working in other text-based tools.
Even someone who perfectly understands git can make a typo or have a brain-fart of a day. A GUI significantly reduces the chances of something like that for all users.
Sometimes dev obsession with tool purity does more damage than good.
(Note: I use the CLI almost exclusively.)
Nah, it’s just a lot easier than you make it out to be. GUIs are fine too, but if you read the documentation and don’t just memorize a fixed set of commands there’s nothing dangerous, slow, or inconvenient in going about a standard workflow using the CLI.
And yes, lots of people don’t have time for this. Totally okay. Don’t generalize to “anyone who uses the CLI is trying too hard”.
In a CLI I know exactly what's happening.
That's just my opinion though. If people feel comfortable working in a GUI all the more power to them.
Maybe not in the way Source Tree uses it, but there certainly is! I've had to use it a few times.
> git-revert - Revert some existing commits
If you don’t have a good mental model for git, you’re gonna have a bad time.
Don't use clients if you don't even understand the basic git workflows. And those usually don't support the advanced oh shit situations this article is about.
Probably a failure of whatever UI you're using. I manage just fine.
The common statement from CLI types is that "it's just whatever you're better at using" which is true conceptually, but practically, again, CLI users make more mistakes either from fat fingers or lack of understanding of git.
Understanding git conceptually from a UI point of view is easy. You don't even have to have a full understanding of git to be effective at using it, if the UI is good. I'm shit with the git CLI, but I understand what git is doing.
Yes it's easy to do dumb shit in a GUI, the same is true for CLI. In fact, it's less likely that there'd be a button for doing something dumb than it is that a git novice would find some command on StackOverflow and attempt to use it without fully understanding the ramifications of it.
Usually I use the included gitk to view the repo, and the CLI to manipulate it.
I've suffered a lot of git GUI bugs. The admittedly large repositories I sometimes deal with cause things to hang and stall, breaking my flow. I keep filing bug reports - truncated diffs because new files were "too large" (presumably someone trying to fix the hang and stall issue), a client that only renders the top half of the window consistently when on a portrait 4K monitor, etc.
The git CLI is simply second nature enough to me at this point that waiting for a GUI to load, refresh, etc. is rarely faster. It does happen, but it's not the common case. Getting a good summary of a set of changes is sometimes one of them. Picking individual hunks/lines is sometimes another - although I prefer to commit with such frequency when using git, that it's extremely rare I have changes that belong in different commits.
Then, looking at perforce, I'm finding more and more cases where I'm dropping out of P4V and into command line tools. Any kind of mass move/edit seems easier to do through the command line. Command line diffs were way easier to review than P4V's file based diff interface when I had changes involving 1 or 2 line tweaks spread across dozens to hundreds of files (such as verifying function rename changelists didn't accidentally pick up other changes.)
I think anyone who's swayed by the beauty of a git GUI has much more patience than me.
"Sourcetree (Not Responding)" - I typed this out while waiting for my Visual Rust tab to focus. Euhg.
I could've made a commit from the command line in that amount of time.
GUI for partial commits and reviewing my change, and then command line for basically everything else (merge, checkout, branch, etc).
Here's a few handy ones:
alias currentbranch='git rev-parse --abbrev-ref HEAD'
alias gpush='git push origin $(currentbranch)'
alias gsync='git pull origin $(currentbranch)'
alias ga='git add -A'
alias gc='git checkout'
alias gcm='git commit -m'
alias gca='git commit --amend'
# and my personal favorite (list recent branches)
alias gb='git for-each-ref --sort=-committerdate refs/heads/ --format="%(HEAD) %(color:yellow)%(refname:short)%(color:reset)" | head -n 20'
I do not care if someone is using a gui.
- If i can use git on an cli, i can use git on any server with an cli. I do need this for when i use git on my ansible maschine or on my home media server or when doing something with build infrastructure (jenkins -> git -> cli)
On the opposite side gui users can often be unaware of the actual model and instead be working with imperfect internal models with be GUI being a crutch.
In both cases there is lack of desire to learn but I'm often more sympathetic to the latter where people want just enough information to do their work well as oppossed to the former who often make things harder than they have to be in all areas and have lost touch with true expertise in favor of appearance of expertise.
The GUI is said to be a major leap forward in human conputer usage, in the context the CLI just strikes me as either (elitist?) jargon, or brogrammer bravado. In either case, not really a step forward but certain macho. I still don't get it.
Or just couldn't be bothered with leaving terminal. I refuse to reach for
mouse for any repository operation when everything else I do from console.
Like I said, super-rare situation.
Right click on any commit and I can create a new branch there, copy the SHA, do a mixed reset to that location, rebase on it, etc. SO much easier to visualize the actual tree of commits you're working with.
I'm sure some people do do all that from the command line. But every CLI coworker of mine has really only known the basics of branching and committing. The GUI unlocks the repo and all of its branches and commits as something you can play with and explore.
I typically use git gui to commit changes, the cli for other operations, and occasionally source tree to visualize branches and compare with remote repos.
And you can also learn useful things by reading the console sometimes. There is no magic.
Do you mean that as "not committed", or "not pushed"?
If you mean not committed, then why is it a good thing? You should be committing often. Then you push after you are satisfied. It is much easier to revert mistakes that way.
I haven't looked back because I haven't found the need.
It has many of the advantages that you describe; makes it easier to get an overview of what's going on, makes it easier to stage individual files, folder, lines of code, hunks, etc.
There are a couple of cases in which I need to fall back to the Git command line, but it's not very often, and I do find it substantially improves my life.
I often see files that clearly shouldn't have been committed. I always bring up using Sourcetree or something else, but everyone seems to think that it's okay the way it is. I can't force it on them and to each their own. It is really frustrating though, because there's this stigma against using a git GUI, but the end results of using one are (in my experience) significantly better.
Seriously though, I'm somewhat new to git and any problem I come across (which are many as a new learner) are solved with command line options. I'm not even familiar with the best GUI options out there and have been trying to learn what seemed to be the "standard" way of git'ing.
(full disclosure: as of last week I actually work for the company behind gitkraken but I started using it far before I realized they were local)
Why do you think it's okay to share this opinion?
Friends don't let friends (especially those who don't learn how to use their tools) rewrite shared git history. If you don't understand rebase, amends, etc can do to your (and everyone else's) repo, DON'T DO IT.
$ pushd ..
$ cp -a my-project my-project-before-I-did-git-surgery
$ pushd ..
$ rm -rf my-project
$ cp -a my-project-before-I-did-git-surgery my-project
If it is committed, it is safe. You can go back to it. If you messed up your branch, just reset it to something that was good. No need to do manual backups.
When you commit in git, that saves the whole project as a "snapshot". If you find yourself lost in some rebase hell or whatever, just reset HEAD back to a previous commit. It's simple as that! (git reset --hard <commit>)
Why I decided to reply to your comment was because this is a very crucial part of learning git. When you realize that you can always go back to what was before, you can start experimenting more freely.
Unless part of your surgery involves files that do not yet live in the history, or you're working on a detached HEAD in a mid-merge state, or... git reset --hard is a very dangerous operation unless you're 100% sure of the entire state of the repository. That is a very rapid way to lose work if you're not perfectly diligent.
And sure, you shouldn't have to back up .git or your workspace, but sometimes, it's a hell of a lot easier to ripcord out and say "screw it" if you have a complete workspace from before you decided to launch down the rebase hole or whatever.
Sometimes it's okay to take liberties with good practices - especially when learning, or when the world is on fire and a push needs to happen now.
The unwanted reality we live in.
I disagree. I don't have much experience using git with big teams, but at least for small team where a developer usually owns a feature branch, force pushing to the branch to take into account criticism on commits can be helpful. Of course, in that case, feature branches are considered non shared.
Git own "next" branch is actually force pushed to all the time, to remove patches which didn't make the cut for example.
This, in contrast with just reviewing the latest commit, potentially going back to the rest of the changes with an eye towards the latest commit.
It frankly bugs the piss out of me when people rebase and ask me to review their latest changes - it feels disrespectful of my time.
Hm? Criticism on commits should be additive. The commit was made, response was made, and a new commit addresses the response. Rewriting history breaks a lot of things and removes context. Another approach:
1) Add commit addressing criticism.
2) Squash when merging feature in to master, which is one of the only cases where I think rewriting history is OK.
Much cleaner master history, no rewriting history (which you should never do once another checkout sees your branch, including GitHub), and a number of other benefits. If you're routinely force pushing feature branches, something is broken in your workflow, IMO.
"It is impossible to make anything foolproof because fools are so ingenious."
Yes, Git is a sharper tool with fewer blade guards than other version control systems, including HG. That sharpness and relative lack of safety mechanisms, however, lets you do things you can't in other systems. The real problem is that folks use these tools without attempting to understand them and cargo-cult onto a workflow which leaves them open to screwing things up.
To continue the "git off my lawn" moment - I've had to use the reflog exactly zero times in the past few years, despite using rebase locally on a fairly frequent basis (and sadly remotely to fix other's bungles as well). This is only because I respect git for its sharp edges, and when it comes time to re-write history with rebase, I work carefully.
Then they used the resulting variable in 'make clean'. That was more of an, 'oh shit, git pull' sort of thing though.
But you can still chop off your thumb in your local history, and that's safe to fix - you just have to know where the duct tape is.
And, frankly, since all rebase does is re-write history, I fail to see how it's inherently productive, especially in the context of re-writing the history of previously shared commits. Yes, it is capable of cleaning up and reducing the number of commits you have to read through when looking at history, but that's such a rare event that optimizing for it (especially by normalizing dangerous commands like `git push -f`) seems, well, premature.
But to enable this "revert-first" culture, you have to design your commits to basically be super easy to revert. That means no merges in the master branch, you want to keep your revision history as clean as possible. One commit, as little dependencies as possible. Rebase is the right tool to use for this. The goal is a tidy linear history.
How are these concepts related to each other? Merges don't make reverting any harder.
After a revert, all the commits that were merged, are still merged, but then they're deleted. The next time you pull, git will delete the changes in your working branch.
In a merge workflow, you have to either fail forward (fix the problem, rather than backing out the merge), or reset/rebase the shared branch, and email repair instructions to everyone on the team.
When you say, it’s not safe, it sounds like you could lose work or someone could be hurt, when it’s more likely that the removed ancestors could be merged back in by someone not using ‘git pull —rebase’, or other devs being put out by having to resolve some conflicts. It’s not great, but it’s a far cry from unsafe or DANGEROUS! MUST AVOID! PUBLIC SHAMING!
If you have one rebase with a force push a week, people will quickly stop asking "who did the force push", since it has become normal. They'll instead just let the force push come through to their local repo, just to find out that the force push rolled the repo back a year. Now productivity is halted dead until someone goes in and fixes it and makes yet another force push.
The worst part to me is that it makes the repo lossy. The entire purpose of having version control is actively subverted in the name of "clean".
I don't understand the business requirement for a non-lossy repo. In my experience, we need to be able to link a release to a specific commit, and we need to show that the changes were reviewed & tested before they were deployed. We use tags for this.
I also think the entire purpose of source control is to be able to answer question like "who changed this? when was it changed? why?".
> Now productivity is halted dead
Because of a bad push to a single repo? I really like the distributed nature of git, which lets me stay productive even when other repos and branches elsewhere are having issues. I would avoid treating git as 'SVN but newer'.