19 ms·
A walk through the Magit interface
- downerending 7y agoDon't miss "Staging parts of a hunk", which is Magit's killer feature, IMO. You can easily go through your current diff (from staged) and add/remove single lines from the staged delta.
- therein 7y agoHow does it compare to `git add -p`?
- chongli 7y agoIt's nonlinear. With `git add -p` you can press keys to go back and forth through the hunks. If there are a lot of them then it can get tedious. With Magit, on the other hand, you see everything in a window and you can use all of your usual emacs commands to scroll/search that window, and then hit the key to stage the hunks as you desire.
- kqr 7y agoAnd also trivially stage parts of hunks, not just entire hunks. It is great!
- ReidZB 7y agoYou can do this with `git add -p` as well, except maybe not trivially (ha). There's the 's' command to split hunks into smaller ones, and then there's also 'e' to open the patch in your editor where you can change the raw patch to whatever you'd like, although in my experience editing it correctly is not straightforward.
- Twisol 7y agoI've just recently started using the `e` (edit) command in `git add -p`. It takes a little bit to get used to writing "correct" patches, but it's super powerful and I'm using it surprisingly often now.
- eitland 7y agoI guess it might be really effective for those who know emacs. For the rest of us we can select lines in vscode, and then either: - right click, - ctrl+shift+p <type stage, stage selected lines>
- petepete 7y agotig is also fantastic for doing this. - u for hunks - 1 for individual lines https://github.com/jonas/tig https://github.com/jonas/tig
- gen220 7y agoFor those of you who want to stay close to git's CLI... `git` (the binary) respects your choice of editor, as indicated by the environment variable `EDITOR`. You should be able to do something like `EDITOR=code git add -p`, it'll open up hunks for editing in `code` (or intellij, or textedit, or whatever).
- atq2119 7y agoWhat's more, git core comes with `git gui`, which lets you stage line by line. It's not the slickest of tools, but it does the job just fine.
- iLemming 7y agoBut like it was noted in the comment a few levels above - Magit's workflow is nonlinear. It doesn't feel like you're switching from one activity to another. Even when rebasing (which is very transactional), you still can peek into things in other branches, stash and un-stash, resolve conflicts, etc. World doesn't have to freeze just because you're doing "git add -p".
- atq2119 7y agogit gui is not the same thing as git add -p. I'm sure magit is nice. It's just that everything you list as nice things about magit are in vanilla git as well. Maybe you prefer the presentation in magit, that's fine. The point is to be fully aware of the available options - which the author of the article doesn't seem to be, as they only compare against git add -p, not against git gui. The one thing that's truly missing in vanilla git as far as I know is the ability to edit the index directly, without editing the checked out files. (Does magit allow that? It's not an advertised feature in the article as far as I can see...)
- deleted 7y ago[deleted]
- iLemming 7y agoSo let's say you stage a few different things. Then run linter/code formatter/etc. You can see the changes done by the linter, you can refine the diff (so it shows not only the lines that changed, but also highlights the details), you can expand/narrow the context (for example if you can see the change, but can't see the function header and without it it's confusing). Then you can [selectively] stage those changes. What about if you overwrite a few lines of something and now the original only exists in another branch? You can peek into that thing, check the diff, even jump into the version in the other branch (without having to check it out) and selectively "cherry-pick" lines of code. It's a seamless workflow, it doesn't feel like you're doing one thing at a time, it feels more natural and doesn't require undivided focus like: "no, I can't afford a bathroom break right now, I'm in the middle of staging, goddammit."
- dima55 7y agoIf you think that, you should probably be using the commit-patch tool: https://github.com/caldwell/commit-patch https://github.com/caldwell/commit-patch Works on generic diff buffers, and is not tied to git specifically. And you can just edit the diff buffer, which gives you infinite flexibility. Since emacs already has vc mode, the only extra thing magit does is rebasing. For everything else, vc-mode and commit-patch are superior.
- useragent86 7y agoSounds like you haven't used Magit very much. Browsing the manual for a few minutes, or looking at a screencast or YouTube video, would show you how much more Magit does than what you described. Regarding commit-patch specifically, its readme says that, to commit parts of a patch in separate commits, hunks must be "killed, split, or edited" into separate patches. Magit is obviously superior to that: with a few keypresses, hunks in the working tree can be staged, hunks in the index can be unstaged, etc. Unstaged changes in the working tree can quickly be sliced and diced and committed separately. Individual lines can be staged or unstaged by selecting them visually. Magit can even automatically back up changes at each stage of the process into special branches, so if you realize, hours or days later, that you accidentally discarded some code without committing it, you can easily retrieve it. Magit is the most powerful, efficient version control tool. See for yourself: https://magit.vc/ https://magit.vc/
- iLemming 7y ago> the only extra thing magit does is rebasing You have no idea on how many levels that statements is false, there's much more than just the rebase: - You ever needed to see branches in a specific order, sorted by committer-date? - What about filtering them, maybe showing only those that yet not merged to master? - What about ordering commits, searching through them, etc. - You ever wanted to see all the commits authored by you that are at least two months older? - Ever needed to see commits that only include a specific set of files? - What about tracing the evolution of a given function? - Bisects, have you ever done those? - You ever had a stash that you can't pop because you made changes, and now you have to resolve conflicts? - Have you ever thought about cherry-picking a specific line from a stash, another branch, etc.? - Ever needed to work with submodules? - Ever thought about how nice would it be to issue a Pull request without leaving Emacs? I'm not sure when was the last time you tried Magit, but maybe try again. Perhaps then you'd appreciate how much good stuff people built into it. It's impressive because aside from a single (hugely successful) Kickstarter campaign and some small voluntary contributions, maintainer and contributors don't get paid for the fantastic work they do, and your comment in that context sounds a bit disingenuous.
- memco 7y agoI hate to start sounding like a shill for this app, but this is also one of my favorite parts of https://git-fork.com/ https://git-fork.com/. When you are looking at changes you can easily stage any lines you want. I am able to work on multiple feature branches at the same time this way: you can make all the changes at one time stage only the lines you need for this branch commit, switch branches and repeat. It’s also great on a single branch when you want to make the changes as you go but want to commit things in more logical groupings. Helps for example when you are refactoring a few functions and want to stage each piece separately.
- iLemming 7y agoIt's okay. Every time there's a discussion about Magit, people bring their favorite Git GUI to tell everyone how stoked they are to use it. I myself have tried several of them. However, majority of those apps are like Steve Yegge would put it: "are cookie-cutter solutions". Whenever you need a quick way of doing something that's not built into the tool, you have no option but to submit a feature request and wait. Sometimes wait for a very long time. With Magit you can just do it yourself. Emacs lisp is not super difficult to pick up. Besides, there are bunch of forums where people would happily help you. One small example: I needed to see log of commits since the last pull, basically `git log ORIG_HEAD..HEAD`, but in a way that's compatible with Magit, otherwise I would just do it in the command line. It's not something that people would do very often, it's not usually built into the client. To get something like that to work with Magit, literally takes a single line of emacs-lisp.
- memco 7y agoEven that is something that Fork probably can handle with custom actions: https://git-fork.com/blog/page/3/#custom-actions https://git-fork.com/blog/page/3/#custom-actions. I agree that a lot of the times apps are mostly cookie cutter and Fork may not really be all that special, but it definitely feels like the devs try to make the common path easiest, but make it pretty simple to take the desired path without friction.
- bananamerica 7y agoIt is true that other tools have most if not all features of Magit. But I doubt there's a single tool that comes with all of Magit's features.
- sigjuice 7y agoStaging (and committing?) parts of a hunk is cool and I have done this many times myself. However, I am always uncomfortable with it because I am unsure how to incorporate it within the overall workflow. I'd like each commit of mine to at least compile and pass some tests.
- gpderetta 7y agoThe custom buid system we use at $WORK can build and run tests from the index (or any git revision really) specifically to facilitate fine grained commits.
- useragent86 7y agoThe easiest way to do this is to, first, stash all the changes (by pressing "zz" in a magit-status buffer). Then expand the view of that stash's hunks, and press "a" on the hunks or lines you want to apply to the working tree (which does not pop the stash; the stash remains untouched). Run your tests, and when you're ready, stage them to the index and commit them. Then proceed to the next part of the stash that you want to test and apply. It's only a few keystrokes in Magit.
- iLemming 7y agoSo what's the problem? Commit often, make a bunch of commits. Or commit into the same commit over and over (<c e> - extend). Then depending on level of granularity you can either group related things together, or break one big commit into a bunch of smaller ones. Rebasing with Magit is a joy, it feels like you're a tailor and you just need to cut the fabric into nice pieces, and if sometimes things get too big or too small, you can always quickly fix it. And even when it feels that you accidentally ruined everything, you can always look at the reflog and un-ruin everything back to normal.
- RustyRussell 7y agoI agree: what I often want is stash of selective parts, so I can test the current stuff before commit.
- celeritascelery 7y ago
- jimbo1qaz 7y agoGit Extensions and Git Cola (possibly other GUI clients I haven't used) have the ability to view a diff and stage individual lines from it. Unfortunately they don't let me reorder lines in the diff.
- faizshah 7y agoI believe this has been in intellij for a while as well: https://blog.jetbrains.com/idea/2018/02/intellij-idea-2018-1-eap-partial-git-commits-and-more/ https://blog.jetbrains.com/idea/2018/02/intellij-idea-2018-1...
- iLemming 7y agoThat's a partial hunk staging, not line-by-line based. Read the comments. IntelliJ doesn't seem to support that feature, yet (or still). I have used IntelliJ for about seven years. It does have a superb Git integration. That was the only reason why I couldn't switch to Emacs (for a very long time). I refused to believe that anyone could do better than that. I was wrong.
- matttb 7y agoAdd tig to the large list of alternatives that can do this as well
- Dangeranger 7y agoTig is the only other tool I’ve used which comes close to the speed and capability provided by Magit. I’ve recommended it to many people who don’t want to learn Emacs for one reason or another.
- BlueTemplar 7y agoIsn't this what Pijul does, but at a fundamental level, instead of having an extra level of abstraction on top of the snapshot-based git, and can therefore do it even "after the commit has been pushed" ?
- iLemming 7y agoPijul, Mercurial, SVN, Fossil, TFS, ... Who cares? Git has won. Either we like it or not, but we're stuck with it for a long, long time. Ping me when Github starts supporting Pijul repos. I'll send you 20 bucks or something.
- BlueTemplar 7y agoRemember when XML had "won" too? Then JSON came around... Remember how Windows "won" ? I won't ever use Github now (how are you going to export all those non-git features like tickets when github is not desirable anymore, hmm?), and neither should you if you care even a tiny bit about open source software !
- iLemming 7y ago> Remember when XML had "won" too? Then JSON came around... JSON wasn't a very well-thought idea, we tried to "fix" it with yaml (which turned out to be even worse), compare it with EDN (which is far better, but sadly nobody outside of Clojure community uses much) > Remember how Windows "won" Windows still dominates desktop OS market and we're still waiting for "Year of Linux on the desktop". Every year some people claim it to be "this is it", but in reality, it is still far from becoming reality. With WSL now even long-time Linux users are tempted to go back to Windows. And honestly I personally don't like that. My point is - "worse is always better" * As I said: either you like it or not - we're stuck with Git and now with Github too. --- * https://en.wikipedia.org/wiki/Worse_is_better https://en.wikipedia.org/wiki/Worse_is_better
- BlueTemplar 7y agoWindows also pretty much "lost" on servers...
- kbd 7y agoLazygit can do this too: https://youtu.be/CPLdltN7wgE?t=70 https://youtu.be/CPLdltN7wgE?t=70
- kelvie 7y agogit-gui (which has come with git basially since the beginning) also has had this feature for a long time.
- iLemming 7y agoAwww thanks, all of us who use Magit will switch back to git-gui now. Seriously, it's not a competition of which git-client has more features. Magit is much more than just "I can do that" thing. It is extremely efficient, it allows (probably) the most efficient git workflow that can be extended and customized. It's not the most beautiful thing - the same thing can be said about an industrial excavator. But do you want a beauty or the efficiency? (You want beauty? download GitKraken or something) Can you imagine if someone removes all the controls inside the said excavator and replaces them with a single iPad like device in the middle of the dashboard? Yah, perhaps it'll be aesthetically pleasing, but would it be efficient, even if it has access to all the features and digging modes, etc.? If you don't care about the efficiency of your git workflow, fine. But if you do, take my word for it, trust me - you wouldn't find a better way to deal with Git than Magit.
- xemdetia 7y agoI actually use emacs git-gutter to have a more visual way of seeing what's going into a commit or not. Having the inline annotations in the files I am working on it is great for doing the staging parts of a hunk.
- iLemming 7y agoWell, in Magit buffers that show diffs you can do refinements (see exact portion of changed thing in a line highlighted, not just the whole line). You can choose different diffing algorithm, ignore whitespaces, expand or narrow the context (i.e. it shows lines that changed, but you don't see the function header), detect renames, etc.
- trey-jones 7y agoThe granularity of staging and unstaging code, combined with the ease of doing things within the text editor that you're already using anyway are really great. I held off using Magit because I thought learning Emacs would be enough by itself, but Magit is intuitive and easy and I really love it. Made my git usage much more efficient within days of starting to use it.
- tetris11 7y agoSame but one caveat that still bothers me about it is that it's not a scriptable package. I can't hook a function to automatically git pull changes when I open it because the pull command only works when the buffer is up. I'm sure there is some magic to set the current buffer, but for me this is not trivial. Ideally (magit-diff "myfile.py") should be all I need to do.
- iLemming 7y ago> Same but one caveat that still bothers me about it is that it's not a scriptable package. What are you talking about? It's written in Emacs-lisp, the possibilities are virtually limited only by Emacs's capabilities. Explain what you're trying to do, maybe post your problem to emacs.stackexchange, r/emacs. I'm sure people would be able to help you.
- mark_l_watson 7y agoI have only briefly used Magic, but after reading your article, I am committed. Thanks!
- habnds 7y agoprobably only "staged" at this point
- iLemming 7y agoWhat truly makes Magit powerful (like many things in Emacs) that it is extremely extensible. Example: When I'm ready to commit my changes: I can spin-off a new branch: - If I have an Org-mode task that I'm currently clocked-in, it can check if it contains a ticket number, then query the issue-tracking system and generate a branch name based on the description. All it takes is pressing two buttons: `b s`, and the rest is done automatically - I commit my changes, it can use a template and fill out the details, I just need to add a description. I can even make it so it compliant with git-commit format enforcer like gommit. I can add fields like reported-by, cc, etc. with a single keystroke; - If I suddenly find out that I forgot to add something, I don't have to amend, I don't have to modify the commit, I can just stage my change and press `c e` - "extend". It will quietly add it to my previous commit. - Using Forge I can create a PR. Once I push the PR, I can trigger a request to issue-tracker that marks the ticket as in "code review" There are bunch of things that other Git clients can't do* and even when they do it, it's not so easy to extend them to work with different projects, issue-tracking systems, etc. * e.g. you can select a bunch of files in Dired and see git log pertaining changes only to those files https://twitter.com/iLemming/status/1193025618742349824 https://twitter.com/iLemming/status/1193025618742349824
- amluto 7y ago> If I suddenly find out that I forgot to add something, I don't have to amend, I don't have to modify the commit, I can just stage my change and press `c e` - "extend". It will quietly add it to my previous commit. Unless I’ve thoroughly misunderstood you, what you’re saying is that “c e” is equivalent to “git commit --amend”. This sounds suspiciously like “amend[ing]”. Sure, git’s user interface is somewhere between mediocre and abysmal, but it’s not really clear to me that “c e” is a vast improvement. I say this as a former org-mode user and even one-time contributor. Eventually I decided that the sheer number of magic incantations I had to remember to do anything useful wasn’t worth it.
- mgalgs 7y agoIt's actually `git commit --amend --no-edit`, but yes, it's basically "just" a shortcut. Count the keystrokes, though. If you spend much time working with git it's a huge win. Of course you could do something similar with shell aliases or reverse search, but then there are other switches and flags that you need occasionally, etc. And it's sooo much more convenient to have everything in one place right in your editor. It's almost unfair how much faster I can get stuff done than folks who don't use it ;) Magit isn't hype, it's as good as everyone says it is. You just have to try it.
- maitre229 7y agoHi everyone..I am the spiritual master TOFFA of Benin. I intervene spiritually in all areas or problems of life * (+229) 90104935 * all my work is done for free and I am paid after the satisfaction * the Return of affection * * Customer attraction * * Win the trial * * star lotto games * * general protection * * THE MASTER OF WEALTH * * Unlock all people * * Protection ring * 1.) * against poisoning * 2.) magic wallet 3.) * the unwanted fat * 4.) * against accident * 5.) * against the socelerie * 6.) * against bewitchment * * Have a good job at work * * Savings and Lucky Perfumes * * Pencil and lipstick of mystic beauty * * * Return of the loved one * * 🧖 pregnancy problem * * Sexual weakness * * Early ejaculation * Contact me on my number whatsapp I can not say everything on the poster: ** (+ 229) 90104935 all package from the outside is sent by the DHL, the post or international bus
- jacobsenscott 7y agoI love magit. If you deal with a lot of PRs the forge extension is also very nice. My only beef is the main interface can feel very slow sometimes. I've learned to start using the functions directly from the M-x command line when I can. Like rather than going to the main magit interface to stage a file, just M-x stage-file. Time to stash? M-x magit-stash, etc. No need to jump to the main magit UI much of the time.
- flocial 7y agoIt chokes when there are a large number of changes too because it's cycling through all the individual diffs that are initially hidden. I honestly wish there was a sparse mode to keep the initial magit status buffer as minimal as "git status".
- celeritascelery 7y agoYou can also use `C-g` to interrupt the diffing algorithm if you just want to get to the minimal git status buffer. In fact that is the recommended way to deal with it.
- iLemming 7y agoYou can remove things you don't need. For example: ;; who cares about tags to be displayed in magit-refs buffer? (remove-hook 'magit-refs-sections-hook 'magit-insert-tags) Also there are faster shortcuts, like you said, e.g: `magit-file-dispatch (C-c M-g)`
- Myrmornis 7y agoMagit is great, I’ve used it every day for 10 years or something. There’s just one thing I haven’t got used to: 1. Stage some stuff 2. Start writing the commit message 3. Stage something else 4. Commit The content staged at (3) doesn’t make it into the commit. This doesn’t fit my mental model from the command line: I think of “commit” as transfer all the staged content into a commit. Initially magit didn’t do this, but I know it is intentional, and in fact the magit author has explained to me that it accurately reflects the command line. But I just seem totally unable to get used to it! I might even change it locally.
- iLemming 7y agoSeems you need to get comfortable with rebasing. Don't think about your commits (especially if you haven't pushed them out) like something carved in stone. When I work, depending on what I'm doing I either commit often and don't think much about it and then later rebase and group things into meaningful chunks of work, or I just keep committing into a single commit and then at some point break it apart into smaller commits. Most often though I do try to keep commits nice and clean from the get-go, and very often I want to add something into a commit that's a few hashes away from the HEAD. In that case I would just rebase/modify with autostash option. It will stash everything and get into rebase mode, I'll go into the stash, select things I want to be included in the commit and press `a`, then I continue rebasing, it will modify the commit, un-stash and get me to the point where I was before.
- Myrmornis 7y agoThanks but sorry, you've missed the point of my post. If you have time, please read it again. I'm pointing out that, if you think of C-c C-c in the commit buffer as being "commit", then there's an uncomfortable conclusion: magit doesn't put everything that is currently staged into the commit. Instead what magit does is freeze the contents of the commit when you open the commit message composition buffer, so anything staged subsequently doesn't make it into the commit. (In my original message I do say i've been using magit daily for 10 years; i'm extremely familiar with all the rebasing operations you mention. i agree they're very useful and i use them multiple times a day.)
- Myrmornis 7y agoI still use the command line for log and show since they are slower in magit, and this is noticeable in large repos.
- iLemming 7y agoDo you limit number of commits? I set mine to 250, and even that is too big of a number, I usually don't need to see that many commits at once. By not doing it in Magit, you're missing many benefits. Examples: https://twitter.com/iLemming/status/1193025618742349824 https://twitter.com/iLemming/status/1193025618742349824 https://twitter.com/iLemming/status/1058507342830923776 https://twitter.com/iLemming/status/1058507342830923776 Also you can run any arbitrary git command from Magit dispatch, just press `!`
- mkesper 7y agoVery nice article. I was distracted by mentioning themes right at the beginning, though.
- amiga_500 7y agoMagit is amazing. When I use cmd line git now, I feel like a lesser primate.
- zaiste 7y agoI make short YouTube videos about Emacs. I've recently done some Magit and Forge related ones [1]. I record what I learnt, so it's far from perfect. Hopefully this helps someone. [1]: https://www.youtube.com/watch?v=7ywEgcbaiys&list=PLhXZp00uXBk4np17N39WvB80zgxlZfVwj&index=18 https://www.youtube.com/watch?v=7ywEgcbaiys&list=PLhXZp00uXB...