pkg update and first config fix
org-brain not working, add org-roam
This commit is contained in:
@@ -1,382 +1,395 @@
|
||||
Authors
|
||||
=======
|
||||
|
||||
The following people have contributed to Magit, including the
|
||||
libraries `git-commit.el`, `magit-popup.el`, and `with-editor.el`
|
||||
which are distributed as separate Elpa packages.
|
||||
|
||||
For statistics see https://magit.vc/stats/authors.html.
|
||||
For statistics see https://magit.vc/stats/magit/authors.html.
|
||||
|
||||
Names below are sorted alphabetically.
|
||||
Authors
|
||||
-------
|
||||
|
||||
Author
|
||||
------
|
||||
- Marius Vollmer
|
||||
- Jonas Bernoulli
|
||||
|
||||
- Marius Vollmer <marius.vollmer@gmail.com>
|
||||
Active Maintainers
|
||||
------------------
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
- Jonas Bernoulli
|
||||
- Kyle Meyer
|
||||
|
||||
- Jonas Bernoulli <jonas@bernoul.li>
|
||||
Former Maintainers
|
||||
------------------
|
||||
|
||||
Developers
|
||||
----------
|
||||
- Nicolas Dudebout
|
||||
- Noam Postavsky
|
||||
- Peter J. Weisberg
|
||||
- Phil Jackson
|
||||
- Rémi Vanicat
|
||||
- Yann Hodique
|
||||
|
||||
- Kyle Meyer <kyle@kyleam.com>
|
||||
- Noam Postavsky <npostavs@users.sourceforge.net>
|
||||
All Contributors
|
||||
----------------
|
||||
|
||||
Retired Maintainers and Developers
|
||||
----------------------------------
|
||||
|
||||
- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
|
||||
- Peter J. Weisberg <pj@irregularexpressions.net>
|
||||
- Pieter Praet <pieter@praet.org>
|
||||
- Phil Jackson <phil@shellarchive.co.uk>
|
||||
- Rémi Vanicat <vanicat@debian.org>
|
||||
- Yann Hodique <yann.hodique@gmail.com>
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
- Aaron Culich <aculich@gmail.com>
|
||||
- Aaron Madlon-Kay <aaron@madlon-kay.com>
|
||||
- Abdo Roig-Maranges <abdo.roig@gmail.com>
|
||||
- Adam Benanti <0entropy@protonmail.com>
|
||||
- Adam Kruszewski <adam@kruszewski.name>
|
||||
- Adam Porter <adam@alphapapa.net>
|
||||
- Adam Spiers <emacs@adamspiers.org>
|
||||
- Adeodato Simó <dato@net.com.org.es>
|
||||
- Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
- Alan Falloon <alan.falloon@gmail.com>
|
||||
- Alban Gruin <alban@pa1ch.fr>
|
||||
- Aleksey Uimanov <s9gf4ult@gmail.com>
|
||||
- Alexander Gramiak <fice-t@protonmail.com>
|
||||
- Alexander Miller <alexanderm@web.de>
|
||||
- Alex Branham <alex.branham@gmail.com>
|
||||
- Alex Dunn <adunn@ucsb.edu>
|
||||
- Alexey Voinov <alexey.v.voinov@gmail.com>
|
||||
- Alex Kost <alezost@gmail.com>
|
||||
- Alex Ott <alexott@gmail.com>
|
||||
- Allen Li <darkfeline@felesatra.moe>
|
||||
- Andreas Fuchs <asf@boinkor.net>
|
||||
- Andreas Liljeqvist <andreas.liljeqvist@robacks.se>
|
||||
- Andreas Rottmann <a.rottmann@gmx.at>
|
||||
- Andrei Chițu <andrei.chitu1@gmail.com>
|
||||
- Andrew Eggenberger <andrew.eggenberger@gmail.com>
|
||||
- Andrew Kirkpatrick <andrew.kirkpatrick@adelaide.edu.au>
|
||||
- Andrew Psaltis <apsaltis@vmware.com>
|
||||
- Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
|
||||
- Andrey Smirnov <andrew.smirnov@gmail.com>
|
||||
- Andriy Kmit' <dev@madand.net>
|
||||
- Andy Sawyer <git@pureabstract.org>
|
||||
- Aria Edmonds <aria@ar1as.space>
|
||||
- Arialdo Martini <arialdomartini@gmail.com>
|
||||
- Arnau Roig Ninerola <arnau.ninerola@outlook.com>
|
||||
- Ashlynn Anderson <pea@pea.sh>
|
||||
- Barak A. Pearlmutter <barak+git@pearlmutter.net>
|
||||
- Bar Magal <bmagamb@gmail.com>
|
||||
- Bart Bakker <bart@thesoftwarecraft.com>
|
||||
- Basil L. Contovounesios <contovob@tcd.ie>
|
||||
- Bastian Beischer <beischer@physik.rwth-aachen.de>
|
||||
- Bastian Beranek <bastian.beranek@inovex.de>
|
||||
- Benjamin Motz <benjamin.motz@mailbox.org>
|
||||
- Ben North <ben@redfrontdoor.org>
|
||||
- Ben Walton <bwalton@artsci.utoronto.ca>
|
||||
- Bob Uhl <buhl@zvelo.com>
|
||||
- Boruch Baum <boruch_baum@gmx.com>
|
||||
- Bradley Wright <brad@intranation.com>
|
||||
- Brandon W Maister <quodlibetor@gmail.com>
|
||||
- Brian Leung <leungbk@mailfence.com>
|
||||
- Brian Warner <warner@lothar.com>
|
||||
- Bryan Shell <bryan.shell@orbitz.com>
|
||||
- Buster Copley <buster@buster.me.uk>
|
||||
- Carl Lieberman <liebermancarl@gmail.com>
|
||||
- Chillar Anand <anand21nanda@gmail.com>
|
||||
- Chris Bernard <cebernard@gmail.com>
|
||||
- Chris Done <chrisdone@gmail.com>
|
||||
- Chris LaRose <cjlarose@gmail.com>
|
||||
- Chris Moore <dooglus@gmail.com>
|
||||
- Chris Ring <chris@ringthis.com>
|
||||
- Chris Shoemaker <chris@mojotech.com>
|
||||
- Christian Dietrich <christian.dietrich@informatik.uni-erlangen.de>
|
||||
- Christian Kluge <ckfrakturfreak@web.de>
|
||||
- Christophe Junke <junke.christophe@gmail.com>
|
||||
- Christopher Monsanto <chris@monsan.to>
|
||||
- Clément Pit-Claudel <clement.pitclaudel@live.com>
|
||||
- Cornelius Mika <cornelius.mika@gmail.com>
|
||||
- Craig Andera <candera@wangdera.com>
|
||||
- Dale Hagglund <dale.hagglund@gmail.com>
|
||||
- Damien Cassou <damien@cassou.me>
|
||||
- Dan Davison <dandavison7@gmail.com>
|
||||
- Dan Erikson <derikson3@gmail.com>
|
||||
- Daniel Brockman <daniel@gointeractive.se>
|
||||
- Daniel Farina <drfarina@acm.org>
|
||||
- Daniel Fleischer <danflscr@gmail.com>
|
||||
- Daniel Gröber <daniel@dps.uibk.ac.at>
|
||||
- Daniel Hackney <dan@haxney.org>
|
||||
- Daniel Kraus <daniel@kraus.my>
|
||||
- Daniel Mai <daniel@danielmai.net>
|
||||
- Daniel Martín <mardani29@yahoo.es>
|
||||
- Daniel Nagy <danielnagy@posteo.de>
|
||||
- Dan LaManna <dan.lamanna@gmail.com>
|
||||
- Danny Zhu <dzhu@dzhu.us>
|
||||
- Dato Simó <dato@net.com.org.es>
|
||||
- David Abrahams <dave@boostpro.com>
|
||||
- David Ellison <davidehellison@gmail.com>
|
||||
- David Hull <david.hull@openx.com>
|
||||
- David L. Rager <ragerdl@gmail.com>
|
||||
- David Wallin <david.wallin@gmail.com>
|
||||
- Dean Kariniemi <8913263+d3k4r@users.noreply.github.com>
|
||||
- Dennis Paskorz <dennis@walltowall.com>
|
||||
- Divye Kapoor <divye@google.com>
|
||||
- Dominique Quatravaux <dominique.quatravaux@epfl.ch>
|
||||
- Duianto Vebotci <vebotci@openmailbox.org>
|
||||
- Eli Barzilay <eli@barzilay.org>
|
||||
- Eric Davis <ed@npri.org>
|
||||
- Eric <e.a.gebhart@gmail.com>
|
||||
- Eric Prud'hommeaux <eric@w3.org>
|
||||
- Eric Schulte <schulte.eric@gmail.com>
|
||||
- Erik Anderson <erikbpanderson@gmail.com>
|
||||
- Evan Torrie <etorrie@gmail.com>
|
||||
- Evgkeni Sampelnikof <esabof@gmail.com>
|
||||
- Eyal Lotem <eyal.lotem@gmail.com>
|
||||
- Fabian Wiget <fabacino@gmail.com>
|
||||
- Felix Geller <fgeller@gmail.com>
|
||||
- Felix Yan <felixonmars@archlinux.org>
|
||||
- Feng Li <fengli@blackmagicdesign.com>
|
||||
- Florian Ragwitz <rafl@debian.org>
|
||||
- Franklin Delehelle <franklin.delehelle@odena.eu>
|
||||
- Frédéric Giquel <frederic.giquel@laposte.net>
|
||||
- Fritz Grabo <fritz.grabo@gmail.com>
|
||||
- Fritz Stelzer <brotzeitmacher@gmail.com>
|
||||
- Geoff Shannon <geoffpshannon@gmail.com>
|
||||
- George Kadianakis <desnacked@gmail.com>
|
||||
- Graham Clark <grclark@gmail.com>
|
||||
- Graham Dobbins <gdobbins@protonmail.com>
|
||||
- Greg A. Woods <woods@planix.com>
|
||||
- Greg Lucas <greg@glucas.net>
|
||||
- Gregory Heytings <ghe@sdf.org>
|
||||
- Greg Sexton <gregsexton@gmail.com>
|
||||
- Guillaume Martres <smarter@ubuntu.com>
|
||||
- Hannu Koivisto <azure@iki.fi>
|
||||
- Hans-Peter Deifel <hpdeifel@gmx.de>
|
||||
- Hussein Ait-Lahcen <hussein.ait-lahcen@fretlink.com>
|
||||
- Ian Eure <ian.eure@gmail.com>
|
||||
- Ian Milligan <ianmllgn@gmail.com>
|
||||
- Ilya Grigoriev <ilyagr@users.noreply.github.com>
|
||||
- Ingmar Sittl <ingmar.sittl@elektrobit.com>
|
||||
- Ingo Lohmar <i.lohmar@gmail.com>
|
||||
- Ioan-Adrian Ratiu <adi@adirat.com>
|
||||
- Ivan Brennan <ivan.brennan@gmail.com>
|
||||
- Jan Tatarik <jan.tatarik@xing.com>
|
||||
- Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
- Jeff Bellegarde <jbellegarde@whitepages.com>
|
||||
- Jeff Dairiki <dairiki@dairiki.org>
|
||||
- Jeremy Meng <yumeng@microsoft.com>
|
||||
- Jesse Alama <jesse.alama@gmail.com>
|
||||
- Jim Blandy <jimb@red-bean.com>
|
||||
- Joakim Jalap <JOJA@stoneridge.com>
|
||||
- Johannes Altmanninger <aclopte@gmail.com>
|
||||
- Johann Klähn <johann@jklaehn.de>
|
||||
- John Mastro <john.b.mastro@gmail.com>
|
||||
- John Morris <john@zultron.com>
|
||||
- John Wiegley <johnw@newartisans.com>
|
||||
- Jonas Bernoulli <jonas@bernoul.li>
|
||||
- Jonas Galvão Xavier <jonas.agx@gmail.com>
|
||||
- Jonathan Arnett <jonathan@scriptdrop.co>
|
||||
- Jonathan del Strother <me@delstrother.com>
|
||||
- Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com>
|
||||
- Jonathan Roes <jroes@jroes.net>
|
||||
- Jonathon McKitrick <jonathon.mckitrick@doublethedonation.com>
|
||||
- Jon Vanderwijk <jonathn@github.com>
|
||||
- Jordan Galby <gravemind2a@gmail.com>
|
||||
- Jordan Greenberg <jordan@softwareslave.com>
|
||||
- Josh Elsasser <jelsasser@appneta.com>
|
||||
- Josiah Schwab <jschwab@gmail.com>
|
||||
- Julien Danjou <julien@danjou.info>
|
||||
- Justin Burkett <justin@burkett.cc>
|
||||
- Justin Caratzas <justin.caratzas@gmail.com>
|
||||
- Justin Guenther <jguenther@gmail.com>
|
||||
- Justin Thomas <justin.thomas1@gmail.com>
|
||||
- Kan-Ru Chen <kanru@kanru.info>
|
||||
- Kenny Ballou <kballou@devnulllabs.io>
|
||||
- Keshav Kini <keshav.kini@gmail.com>
|
||||
- Kevin Brubeck Unhammer <unhammer@fsfe.org>
|
||||
- Kevin J. Foley <kfoley15@gmail.com>
|
||||
- Kévin Le Gouguec <kevin.legouguec@gmail.com>
|
||||
- Kimberly Wolk <kimwolk@hotmail.com>
|
||||
- Knut Olav Bøhmer <bohmer@gmail.com>
|
||||
- Kyle Meyer <kyle@kyleam.com>
|
||||
- Laurent Laffont <laurent.laffont@gmail.com>
|
||||
- Laverne Schrock <laverne@schrock.email>
|
||||
- Leandro Facchinetti <me@leafac.com>
|
||||
- Lele Gaifax <lele@metapensiero.it>
|
||||
- Leo Liu <sdl.web@gmail.com>
|
||||
- Leonardo Etcheverry <leo@kalio.net>
|
||||
- Leo Vivier <leo.vivier+dev@gmail.com>
|
||||
- Lingchao Xin <douglarek@users.noreply.github.com>
|
||||
- Lin Sun <sunlin7@yahoo.com>
|
||||
- Li-Yun Chang <michael142536@gmail.com>
|
||||
- Lluís Vilanova <vilanova@ac.upc.edu>
|
||||
- Loic Dachary <loic@dachary.org>
|
||||
- Louis Roché <louis@louisroche.net>
|
||||
- Luís Oliveira <luismbo@gmail.com>
|
||||
- Luke Amdor <luke.amdor@gmail.com>
|
||||
- Magnus Malm <magnusmalm@gmail.com>
|
||||
- Mak Kolybabi <mak@kolybabi.com>
|
||||
- Manuel Vázquez Acosta <mva.led@gmail.com>
|
||||
- Marcel Wolf <mwolf@ml1.net>
|
||||
- Marc Herbert <marc.herbert@gmail.com>
|
||||
- Marcin Bachry <hegel666@gmail.com>
|
||||
- Marco Craveiro <marco.craveiro@gmail.com>
|
||||
- Marco Wahl <marcowahlsoft@gmail.com>
|
||||
- Marc Sherry <msherry@gmail.com>
|
||||
- Marian Schubert <marian.schubert@gmail.com>
|
||||
- Mario Rodas <marsam@users.noreply.github.com>
|
||||
- Marius Vollmer <marius.vollmer@gmail.com>
|
||||
- Mark Hepburn <Mark.Hepburn@csiro.au>
|
||||
- Mark Karpov <markkarpov@opmbx.org>
|
||||
- Mark Oteiza <mvoteiza@udel.edu>
|
||||
- Martin Joerg <martin.joerg@gmail.com>
|
||||
- Martin Polden <mpolden@yahoo-inc.com>
|
||||
- Matthew Fluet <matthew.fluet@gmail.com>
|
||||
- Matthew Kraai <kraai@ftbfs.org>
|
||||
- Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
|
||||
- Matus Goljer <dota.keys@gmail.com>
|
||||
- Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
||||
- Michael Fogleman <michaelwfogleman@gmail.com>
|
||||
- Michael Griffiths <mikey@cich.li>
|
||||
- Michael Heerdegen <michael_heerdegen@web.de>
|
||||
- Michal Sojka <sojkam1@fel.cvut.cz>
|
||||
- Miciah Masters <miciah.masters@gmail.com>
|
||||
- Miles Bader <miles@gnu.org>
|
||||
- Miloš Mošić <mosic.milos@gmail.com>
|
||||
- Mitchel Humpherys <mitch.special@gmail.com>
|
||||
- Moritz Bunkus <moritz@bunkus.org>
|
||||
- Naoya Yamashita <conao3@gmail.com>
|
||||
- Natalie Weizenbaum <nex342@gmail.com>
|
||||
- Nguyễn Tuấn Anh <ubolonton@gmail.com>
|
||||
- Nic Ferier <nic@ferrier.me.uk>
|
||||
- Nick Alcock <nick.alcock@oracle.com>
|
||||
- Nick Alexander <nalexander@mozilla.com>
|
||||
- Nick Dimiduk <ndimiduk@gmail.com>
|
||||
- Nicklas Lindgren <nili@gulmohar.se>
|
||||
- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
|
||||
- Nicolas Petton <nicolas@petton.fr>
|
||||
- Nicolas Richard <theonewiththeevillook@yahoo.fr>
|
||||
- Nikolay Martynov <mar.kolya@gmail.com>
|
||||
- Noam Postavsky <npostavs@users.sourceforge.net>
|
||||
- N. Troy de Freitas <me@ntdef.com>
|
||||
- Ola x Nilsson <olani@axis.com>
|
||||
- Ole Arndt <oliver.arndt@cegedim.com>
|
||||
- Oleh Krehel <ohwoeowho@gmail.com>
|
||||
- Orivej Desh <orivej@gmx.fr>
|
||||
- Óscar Fuentes <ofv@wanadoo.es>
|
||||
- Pancho Horrillo <pancho@pancho.name>
|
||||
- Paul Stadig <paul@stadig.name>
|
||||
- Pavel Holejsovsky <pavel.holejsovsky@upek.com>
|
||||
- Pekka Pessi <nospam@pessi.fi>
|
||||
- Peter Eisentraut <peter@eisentraut.org>
|
||||
- Peter Jaros <peter.a.jaros@gmail.com>
|
||||
- Peter J. Weisberg <pj@irregularexpressions.net>
|
||||
- Peter Vasil <mail@petervasil.net>
|
||||
- Philippe Cavalaria <philippe.cavalaria@gmail.com>
|
||||
- Philippe Vaucher <philippe.vaucher@gmail.com>
|
||||
- Philipp Fehre <pfehre@twitter.com>
|
||||
- Philipp Haselwarter <philipp@haselwarter.org>
|
||||
- Philipp Stephani <phst@google.com>
|
||||
- Philip Weaver <philip.weaver@gmail.com>
|
||||
- Phil Jackson <phil@shellarchive.co.uk>
|
||||
- Phil Sainty <phil@catalyst.net.nz>
|
||||
- Pierre Neidhardt <ambrevar@gmail.com>
|
||||
- Pieter Praet <pieter@praet.org>
|
||||
- Prathamesh Sonpatki <csonpatki@gmail.com>
|
||||
- Pritam Baral <pritam@pritambaral.com>
|
||||
- rabio <rabiodev@o2.pl>
|
||||
- Radon Rosborough <radon.neon@gmail.com>
|
||||
- Rafael Laboissiere <rafael@laboissiere.net>
|
||||
- Raimon Grau <raimon@3scale.net>
|
||||
- Ramkumar Ramachandra <artagnon@gmail.com>
|
||||
- Remco van 't Veer <rwvtveer@xs4all.nl>
|
||||
- Rémi Vanicat <vanicat@debian.org>
|
||||
- René Stadler <mail@renestadler.de>
|
||||
- Richard Kim <emacs18@gmail.com>
|
||||
- Robert Boone <robo4288@gmail.com>
|
||||
- Robin Green <greenrd@greenrd.org>
|
||||
- Roey Darwish Dror <roey.ghost@gmail.com>
|
||||
- Roger Crew <crew@cs.stanford.edu>
|
||||
- Romain Francoise <romain@orebokech.com>
|
||||
- Ron Parker <rparker@a123systems.com>
|
||||
- Roy Crihfield <rscrihf@gmail.com>
|
||||
- Rüdiger Sonderfeld <ruediger@c-plusplus.net>
|
||||
- Russell Black <black.russell@gmail.com>
|
||||
- Ryan C. Thompson <rct@thompsonclan.org>
|
||||
- Sam Cedarbaum <scedarbaum@gmail.com>
|
||||
- Samuel Bronson <naesten@gmail.com>
|
||||
- Samuel W. Flint <swflint@flintfam.org>
|
||||
- Sanjoy Das <sanjoy@playingwithpointers.com>
|
||||
- Sean Allred <code@seanallred.com>
|
||||
- Sean Bryant <sbryant@hackinggibsons.com>
|
||||
- Sean Whitton <spwhitton@spwhitton.name>
|
||||
- Sebastian Wiesner <lunaryorn@gmail.com>
|
||||
- Sébastien Gross <seb@chezwam.org>
|
||||
- Seong-Kook Shin <cinsky@gmail.com>
|
||||
- Sergey Pashinin <sergey@pashinin.com>
|
||||
- Sergey Vinokurov <serg.foo@gmail.com>
|
||||
- Servilio Afre Puentes <afrepues@mcmaster.ca>
|
||||
- Siavash Askari Nasr <siavash.askari.nasr@gmail.com>
|
||||
- Silent Sphere <silentsphere110@gmail.com>
|
||||
- Simon Pintarelli <simon.pintarelli@cscs.ch>
|
||||
- Štěpán Němec <stepnem@gmail.com>
|
||||
- Steven Chow <steve@myfreestuffapp.com>
|
||||
- Steven E. Harris <seh@panix.com>
|
||||
- Steven Thomas <sthomas314@gmail.com>
|
||||
- Steven Vancoillie <steven.vancoillie@runbox.com>
|
||||
- Steve Purcell <steve@sanityinc.com>
|
||||
- Suhail Shergill <suhailshergill@gmail.com>
|
||||
- Sylvain Rousseau <thisirs@gmail.com>
|
||||
- Syohei Yoshida <syohex@gmail.com>
|
||||
- Szunti <Szunti@users.noreply.github.com>
|
||||
- Takafumi Arakaki <aka.tkf@gmail.com>
|
||||
- Tassilo Horn <tsdh@gnu.org>
|
||||
- TEC <tec@tecosaur.com>
|
||||
- Teemu Likonen <tlikonen@iki.fi>
|
||||
- Teruki Shigitani <teruki.shigitani@gmail.com>
|
||||
- Thierry Volpiatto <thievol@posteo.net>
|
||||
- Thomas A Caswell <tcaswell@gmail.com>
|
||||
- Thomas Fini Hansen <xen@xen.dk>
|
||||
- Thomas Frössman <thomasf@jossystem.se>
|
||||
- Thomas Jost <thomas.jost@gmail.com>
|
||||
- Thomas Riccardi <riccardi.thomas@gmail.com>
|
||||
- Tibor Simko <tibor.simko@cern.ch>
|
||||
- Timo Juhani Lindfors <timo.lindfors@iki.fi>
|
||||
- Tim Perkins <tprk77@gmail.com>
|
||||
- Tim Wraight <tim@wraight.net>
|
||||
- Ting-Yu Lin <aethanyc@gmail.com>
|
||||
- Tom Feist <shabble@metavore.org>
|
||||
- Toon Claes <toon@iotcl.com>
|
||||
- Topi Miettinen <toiwoton@gmail.com>
|
||||
- Troy Hinckley <t.macman@gmail.com>
|
||||
- Tsuyoshi Kitamoto <tsuyoshi.kitamoto@gmail.com>
|
||||
- Tunc Uzlu <bb2020@users.noreply.github.com>
|
||||
- Vineet Naik <vineet@helpshift.com>
|
||||
- Vitaly Ostashov <hotosho@yandex-team.ru>
|
||||
- Vladimir Panteleev <git@thecybershadow.net>
|
||||
- Vladimir Sedach <vas@oneofus.la>
|
||||
- Wei Huang <weih@opera.com>
|
||||
- Wilfred Hughes <me@wilfred.me.uk>
|
||||
- Win Treese <treese@acm.org>
|
||||
- Wojciech Siewierski <wojciech@siewierski.eu>
|
||||
- Wouter Bolsterlee <wouter@bolsterl.ee>
|
||||
- Xavier Noria <fxn@hashref.com>
|
||||
- Xu Chunyang <mail@xuchunyang.me>
|
||||
- Yann Herklotz <git@yannherklotz.com>
|
||||
- Yann Hodique <yann.hodique@gmail.com>
|
||||
- Ynilu <ynilu.chang@gmail.com>
|
||||
- York Zhao <gtdplatform@gmail.com>
|
||||
- Yuichi Higashi <aaa707b@gmail.com>
|
||||
- Yuri Khan <yurivkhan@gmail.com>
|
||||
- Zach Latta <zach@zachlatta.com>
|
||||
- zakora <zakora@users.noreply.github.com>
|
||||
- Zhu Zihao <all_but_last@163.com>
|
||||
- zilongshanren <guanghui8827@126.com>
|
||||
- Aaron Culich
|
||||
- Aaron L. Zeng
|
||||
- Aaron Madlon-Kay
|
||||
- Abdo Roig-Maranges
|
||||
- Adam Benanti
|
||||
- Adam Kruszewski
|
||||
- Adam Porter
|
||||
- Adam Spiers
|
||||
- Adeodato Simó
|
||||
- Ævar Arnfjörð Bjarmason
|
||||
- Alan Falloon
|
||||
- Alban Gruin
|
||||
- Aleksey Uimanov
|
||||
- Alexander Gramiak
|
||||
- Alexander Miller
|
||||
- Alex Branham
|
||||
- Alex Dunn
|
||||
- Alexey Voinov
|
||||
- Alex Kost
|
||||
- Alex Ott
|
||||
- Allen Li
|
||||
- Andreas Fuchs
|
||||
- Andreas Liljeqvist
|
||||
- Andreas Rottmann
|
||||
- Andrei Chițu
|
||||
- Andrew Eggenberger
|
||||
- Andrew Kirkpatrick
|
||||
- Andrew Psaltis
|
||||
- Andrew Schwartzmeyer
|
||||
- Andrey Smirnov
|
||||
- Andriy Kmit'
|
||||
- Andy Sawyer
|
||||
- Angel de Vicente
|
||||
- Aria Edmonds
|
||||
- Arialdo Martini
|
||||
- Arnau Roig Ninerola
|
||||
- Ashlynn Anderson
|
||||
- Barak A. Pearlmutter
|
||||
- Bar Magal
|
||||
- Bart Bakker
|
||||
- Basil L. Contovounesios
|
||||
- Bastian Beischer
|
||||
- Bastian Beranek
|
||||
- Benjamin Motz
|
||||
- Ben North
|
||||
- Ben Walton
|
||||
- Ben Zanin
|
||||
- Bob Uhl
|
||||
- Boruch Baum
|
||||
- Bradley Wright
|
||||
- Brandon W Maister
|
||||
- Brennan Vincent
|
||||
- Brian Leung
|
||||
- Brian Warner
|
||||
- Bryan Shell
|
||||
- Buster Copley
|
||||
- Cameron Chaparro
|
||||
- Carl Lieberman
|
||||
- Chillar Anand
|
||||
- Chris Bernard
|
||||
- Chris Done
|
||||
- Chris LaRose
|
||||
- Chris Moore
|
||||
- Chris Ring
|
||||
- Chris Shoemaker
|
||||
- Christian Dietrich
|
||||
- Christian Kluge
|
||||
- Christophe Junke
|
||||
- Christopher Monsanto
|
||||
- Clément Pit-Claudel
|
||||
- Cornelius Mika
|
||||
- Craig Andera
|
||||
- Daanturo
|
||||
- Dale Hagglund
|
||||
- Damien Cassou
|
||||
- Dan Davison
|
||||
- Dan Erikson
|
||||
- Daniel Brockman
|
||||
- Daniel Farina
|
||||
- Daniel Fleischer
|
||||
- Daniel Gröber
|
||||
- Daniel Hackney
|
||||
- Daniel Kraus
|
||||
- Daniel Mai
|
||||
- Daniel Martín
|
||||
- Daniel Nagy
|
||||
- Dan Kessler
|
||||
- Dan LaManna
|
||||
- Danny Zhu
|
||||
- Dato Simó
|
||||
- David Abrahams
|
||||
- David Ellison
|
||||
- David Hull
|
||||
- David L. Rager
|
||||
- David Wallin
|
||||
- Dean Kariniemi
|
||||
- Dennis Paskorz
|
||||
- Divye Kapoor
|
||||
- Dominique Quatravaux
|
||||
- Duianto Vebotci
|
||||
- Eli Barzilay
|
||||
- Ellis Kenyo
|
||||
- Eric
|
||||
- Eric Davis
|
||||
- Eric Prud'hommeaux
|
||||
- Eric Schulte
|
||||
- Erik Anderson
|
||||
- Evan Torrie
|
||||
- Evgkeni Sampelnikof
|
||||
- Eyal Lotem
|
||||
- Fabian Wiget
|
||||
- Felix Geller
|
||||
- Felix Yan
|
||||
- Feng Li
|
||||
- Florian Ragwitz
|
||||
- Franklin Delehelle
|
||||
- Frédéric Giquel
|
||||
- Fritz Grabo
|
||||
- Fritz Stelzer
|
||||
- Geoff Shannon
|
||||
- George Kadianakis
|
||||
- Géza Herman
|
||||
- Graham Clark
|
||||
- Graham Dobbins
|
||||
- Greg A. Woods
|
||||
- Greg Lucas
|
||||
- Gregory Heytings
|
||||
- Greg Sexton
|
||||
- Greg Steuck
|
||||
- Guillaume Martres
|
||||
- Hannu Koivisto
|
||||
- Hans-Peter Deifel
|
||||
- hokomo
|
||||
- Hussein Ait-Lahcen
|
||||
- Ian Eure
|
||||
- Ian Milligan
|
||||
- Ilya Grigoriev
|
||||
- Ingmar Sittl
|
||||
- Ingo Lohmar
|
||||
- Ioan-Adrian Ratiu
|
||||
- Ivan Brennan
|
||||
- Jan Tatarik
|
||||
- Jasper St. Pierre
|
||||
- Jean-Louis Giordano
|
||||
- Jeff Bellegarde
|
||||
- Jeff Dairiki
|
||||
- Jeremy Meng
|
||||
- Jesse Alama
|
||||
- Jim Blandy
|
||||
- Joakim Jalap
|
||||
- Johannes Altmanninger
|
||||
- Johannes Maier
|
||||
- Johann Klähn
|
||||
- John Mastro
|
||||
- John Morris
|
||||
- John Wiegley
|
||||
- Jonas Bernoulli
|
||||
- Jonas Galvão Xavier
|
||||
- Jonathan Arnett
|
||||
- Jonathan del Strother
|
||||
- Jonathan Leech-Pepin
|
||||
- Jonathan Roes
|
||||
- Jonathon McKitrick
|
||||
- Jon Vanderwijk
|
||||
- Jordan Galby
|
||||
- Jordan Greenberg
|
||||
- Jorge Israel Peña
|
||||
- Josh Elsasser
|
||||
- Josiah Schwab
|
||||
- Julien Danjou
|
||||
- Justin Burkett
|
||||
- Justin Caratzas
|
||||
- Justin Guenther
|
||||
- Justin Thomas
|
||||
- Kan-Ru Chen
|
||||
- Kenny Ballou
|
||||
- Keshav Kini
|
||||
- Kevin Brubeck Unhammer
|
||||
- Kevin J. Foley
|
||||
- Kévin Le Gouguec
|
||||
- Kimberly Wolk
|
||||
- Knut Olav Bøhmer
|
||||
- Kyle Meyer
|
||||
- Laurent Laffont
|
||||
- Laverne Schrock
|
||||
- Leandro Facchinetti
|
||||
- Lele Gaifax
|
||||
- Leo Liu
|
||||
- Leonardo Etcheverry
|
||||
- Leo Vivier
|
||||
- Li Chen
|
||||
- Lingchao Xin
|
||||
- Lin Sun
|
||||
- Li-Yun Chang
|
||||
- Lluís Vilanova
|
||||
- Loic Dachary
|
||||
- Louis Roché
|
||||
- Luís Oliveira
|
||||
- Luke Amdor
|
||||
- Magnus Malm
|
||||
- Mak Kolybabi
|
||||
- Manuel Vázquez Acosta
|
||||
- Marcel Wolf
|
||||
- Marc Herbert
|
||||
- Marcin Bachry
|
||||
- Marco Craveiro
|
||||
- Marco Wahl
|
||||
- Marc Sherry
|
||||
- Marian Schubert
|
||||
- Mario Rodas
|
||||
- Marius Vollmer
|
||||
- Mark Hepburn
|
||||
- Mark Karpov
|
||||
- Mark Oteiza
|
||||
- Martin Joerg
|
||||
- Martin Polden
|
||||
- Matthew Fluet
|
||||
- Matthew Kraai
|
||||
- Matthieu Hauglustaine
|
||||
- Matus Goljer
|
||||
- Maxim Cournoyer
|
||||
- Michael Fogleman
|
||||
- Michael Griffiths
|
||||
- Michael Heerdegen
|
||||
- Michal Sojka
|
||||
- Miciah Masters
|
||||
- Miles Bader
|
||||
- Miloš Mošić
|
||||
- Mitchel Humpherys
|
||||
- Moritz Bunkus
|
||||
- Nacho Barrientos
|
||||
- Naoya Yamashita
|
||||
- Natalie Weizenbaum
|
||||
- Nguyễn Tuấn Anh
|
||||
- Nic Ferier
|
||||
- Nick Alcock
|
||||
- Nick Alexander
|
||||
- Nick Dimiduk
|
||||
- Nicklas Lindgren
|
||||
- Nicolas Dudebout
|
||||
- Nicolas Petton
|
||||
- Nicolas Richard
|
||||
- Nikolay Martynov
|
||||
- Noam Postavsky
|
||||
- N. Troy de Freitas
|
||||
- Ola x Nilsson
|
||||
- Ole Arndt
|
||||
- Oleh Krehel
|
||||
- Orivej Desh
|
||||
- Óscar Fuentes
|
||||
- Pancho Horrillo
|
||||
- Paul Stadig
|
||||
- Pavel Holejsovsky
|
||||
- Pekka Pessi
|
||||
- Peter Eisentraut
|
||||
- Peter Jaros
|
||||
- Peter J. Weisberg
|
||||
- Peter Vasil
|
||||
- Philippe Cavalaria
|
||||
- Philippe Vaucher
|
||||
- Philipp Fehre
|
||||
- Philipp Haselwarter
|
||||
- Philipp Stephani
|
||||
- Philip Weaver
|
||||
- Phil Jackson
|
||||
- Phil Sainty
|
||||
- Pierre Neidhardt
|
||||
- Pieter Praet
|
||||
- Prathamesh Sonpatki
|
||||
- Pritam Baral
|
||||
- rabio
|
||||
- Radon Rosborough
|
||||
- Rafael Laboissiere
|
||||
- Raimon Grau
|
||||
- Ramkumar Ramachandra
|
||||
- Remco van 't Veer
|
||||
- Rémi Vanicat
|
||||
- René Stadler
|
||||
- Richard Kim
|
||||
- Robert Boone
|
||||
- Robert Irelan
|
||||
- Robin Green
|
||||
- Roey Darwish Dror
|
||||
- Roger Crew
|
||||
- Romain Francoise
|
||||
- Ron Parker
|
||||
- Roy Crihfield
|
||||
- Rüdiger Sonderfeld
|
||||
- Russell Black
|
||||
- Ryan C. Thompson
|
||||
- Sam Cedarbaum
|
||||
- Samuel Bronson
|
||||
- Samuel W. Flint
|
||||
- Sanjoy Das
|
||||
- Sean Allred
|
||||
- Sean Bryant
|
||||
- Sean Farley
|
||||
- Sean Whitton
|
||||
- Sebastian Wiesner
|
||||
- Sébastien Gross
|
||||
- Seong-Kook Shin
|
||||
- Sergey Pashinin
|
||||
- Sergey Vinokurov
|
||||
- Servilio Afre Puentes
|
||||
- Shuguang Sun
|
||||
- Siavash Askari Nasr
|
||||
- Silent Sphere
|
||||
- Simon Pintarelli
|
||||
- Stefan Kangas
|
||||
- Štěpán Němec
|
||||
- Steven Chow
|
||||
- Steven E. Harris
|
||||
- Steven Thomas
|
||||
- Steven Vancoillie
|
||||
- Steve Purcell
|
||||
- Suhail Shergill
|
||||
- Sylvain Rousseau
|
||||
- Syohei Yoshida
|
||||
- Szunti
|
||||
- Takafumi Arakaki
|
||||
- Tassilo Horn
|
||||
- TEC
|
||||
- Teemu Likonen
|
||||
- Teruki Shigitani
|
||||
- Thierry Volpiatto
|
||||
- Thomas A Caswell
|
||||
- Thomas Fini Hansen
|
||||
- Thomas Frössman
|
||||
- Thomas Jost
|
||||
- Thomas Riccardi
|
||||
- Tibor Simko
|
||||
- Timo Juhani Lindfors
|
||||
- Tim Perkins
|
||||
- Tim Wraight
|
||||
- Ting-Yu Lin
|
||||
- Tom Feist
|
||||
- Toon Claes
|
||||
- Topi Miettinen
|
||||
- Troy Hinckley
|
||||
- Tsuyoshi Kitamoto
|
||||
- Tunc Uzlu
|
||||
- Vineet Naik
|
||||
- Vitaly Ostashov
|
||||
- Vladimir Ivanov
|
||||
- Vladimir Panteleev
|
||||
- Vladimir Sedach
|
||||
- Waqar Hameed
|
||||
- Wei Huang
|
||||
- Wilfred Hughes
|
||||
- Win Treese
|
||||
- Wojciech Siewierski
|
||||
- Wouter Bolsterlee
|
||||
- Xavier Noria
|
||||
- Xu Chunyang
|
||||
- Yann Herklotz
|
||||
- Yann Hodique
|
||||
- Ynilu
|
||||
- York Zhao
|
||||
- Yuichi Higashi
|
||||
- Yuri Khan
|
||||
- Zach Latta
|
||||
- zakora
|
||||
- Zhu Zihao
|
||||
- zilongshanren
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
;;; git-rebase.el --- Edit Git rebase files -*- lexical-binding: t -*-
|
||||
;;; git-rebase.el --- Edit Git rebase files -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Phil Jackson <phil@shellarchive.co.uk>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; This file is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; This file is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this file. If not, see <http://www.gnu.org/licenses/>.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -149,35 +146,36 @@
|
||||
(defvar git-rebase-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map special-mode-map)
|
||||
(define-key map (kbd "C-m") 'git-rebase-show-commit)
|
||||
(define-key map (kbd "p") 'git-rebase-backward-line)
|
||||
(define-key map (kbd "n") 'forward-line)
|
||||
(define-key map (kbd "M-p") 'git-rebase-move-line-up)
|
||||
(define-key map (kbd "M-n") 'git-rebase-move-line-down)
|
||||
(define-key map (kbd "c") 'git-rebase-pick)
|
||||
(define-key map (kbd "k") 'git-rebase-kill-line)
|
||||
(define-key map (kbd "C-k") 'git-rebase-kill-line)
|
||||
(define-key map (kbd "b") 'git-rebase-break)
|
||||
(define-key map (kbd "e") 'git-rebase-edit)
|
||||
(define-key map (kbd "l") 'git-rebase-label)
|
||||
(define-key map (kbd "MM") 'git-rebase-merge)
|
||||
(define-key map (kbd "Mt") 'git-rebase-merge-toggle-editmsg)
|
||||
(define-key map (kbd "m") 'git-rebase-edit)
|
||||
(define-key map (kbd "f") 'git-rebase-fixup)
|
||||
(define-key map (kbd "q") 'undefined)
|
||||
(define-key map (kbd "r") 'git-rebase-reword)
|
||||
(define-key map (kbd "w") 'git-rebase-reword)
|
||||
(define-key map (kbd "s") 'git-rebase-squash)
|
||||
(define-key map (kbd "t") 'git-rebase-reset)
|
||||
(define-key map (kbd "x") 'git-rebase-exec)
|
||||
(define-key map (kbd "y") 'git-rebase-insert)
|
||||
(define-key map (kbd "z") 'git-rebase-noop)
|
||||
(define-key map (kbd "SPC") 'git-rebase-show-or-scroll-up)
|
||||
(define-key map (kbd "DEL") 'git-rebase-show-or-scroll-down)
|
||||
(define-key map (kbd "C-x C-t") 'git-rebase-move-line-up)
|
||||
(define-key map [M-up] 'git-rebase-move-line-up)
|
||||
(define-key map [M-down] 'git-rebase-move-line-down)
|
||||
(define-key map [remap undo] 'git-rebase-undo)
|
||||
(define-key map (kbd "C-m") #'git-rebase-show-commit)
|
||||
(define-key map (kbd "p") #'git-rebase-backward-line)
|
||||
(define-key map (kbd "n") #'forward-line)
|
||||
(define-key map (kbd "M-p") #'git-rebase-move-line-up)
|
||||
(define-key map (kbd "M-n") #'git-rebase-move-line-down)
|
||||
(define-key map (kbd "c") #'git-rebase-pick)
|
||||
(define-key map (kbd "k") #'git-rebase-kill-line)
|
||||
(define-key map (kbd "C-k") #'git-rebase-kill-line)
|
||||
(define-key map (kbd "b") #'git-rebase-break)
|
||||
(define-key map (kbd "e") #'git-rebase-edit)
|
||||
(define-key map (kbd "l") #'git-rebase-label)
|
||||
(define-key map (kbd "M M") #'git-rebase-merge)
|
||||
(define-key map (kbd "M t") #'git-rebase-merge-toggle-editmsg)
|
||||
(define-key map (kbd "m") #'git-rebase-edit)
|
||||
(define-key map (kbd "f") #'git-rebase-fixup)
|
||||
(define-key map (kbd "q") #'undefined)
|
||||
(define-key map (kbd "r") #'git-rebase-reword)
|
||||
(define-key map (kbd "w") #'git-rebase-reword)
|
||||
(define-key map (kbd "s") #'git-rebase-squash)
|
||||
(define-key map (kbd "t") #'git-rebase-reset)
|
||||
(define-key map (kbd "u") #'git-rebase-update-ref)
|
||||
(define-key map (kbd "x") #'git-rebase-exec)
|
||||
(define-key map (kbd "y") #'git-rebase-insert)
|
||||
(define-key map (kbd "z") #'git-rebase-noop)
|
||||
(define-key map (kbd "SPC") #'git-rebase-show-or-scroll-up)
|
||||
(define-key map (kbd "DEL") #'git-rebase-show-or-scroll-down)
|
||||
(define-key map (kbd "C-x C-t") #'git-rebase-move-line-up)
|
||||
(define-key map [M-up] #'git-rebase-move-line-up)
|
||||
(define-key map [M-down] #'git-rebase-move-line-down)
|
||||
(define-key map [remap undo] #'git-rebase-undo)
|
||||
map)
|
||||
"Keymap for Git-Rebase mode.")
|
||||
|
||||
@@ -261,6 +259,7 @@ If the region is active, act on all lines touched by the region."
|
||||
(?r . "reword")
|
||||
(?s . "squash")
|
||||
(?t . "reset")
|
||||
(?u . "update-ref")
|
||||
(?x . "exec"))
|
||||
"Alist mapping single key of an action to the full name.")
|
||||
|
||||
@@ -294,7 +293,8 @@ If the region is active, act on all lines touched by the region."
|
||||
(bare . ,(concat (regexp-opt '("b" "break" "noop") "\\(?1:")
|
||||
" *$"))
|
||||
(label . ,(concat (regexp-opt '("l" "label"
|
||||
"t" "reset")
|
||||
"t" "reset"
|
||||
"u" "update-ref")
|
||||
"\\(?1:")
|
||||
" \\(?3:[^ \n]+\\) ?\\(?4:.*\\)"))
|
||||
(merge . ,(concat "\\(?1:m\\|merge\\) "
|
||||
@@ -318,7 +318,7 @@ instance with all nil values is returned."
|
||||
git-rebase-line-regexps)))
|
||||
(git-rebase-action
|
||||
:action-type type
|
||||
:action (when-let ((action (match-string-no-properties 1)))
|
||||
:action (and-let* ((action (match-string-no-properties 1)))
|
||||
(or (cdr (assoc action git-rebase-short-options))
|
||||
action))
|
||||
:action-options (match-string-no-properties 2)
|
||||
@@ -550,6 +550,20 @@ input, remove the reset command on the current line, if any."
|
||||
""))
|
||||
arg))
|
||||
|
||||
(defun git-rebase-update-ref (arg)
|
||||
"Insert an update-ref action after the current line.
|
||||
If there is already an update-ref action on the current line,
|
||||
then edit that instead. With a prefix argument, insert a new
|
||||
action even when there is already one on the current line. With
|
||||
empty input, remove the action on the current line, if any."
|
||||
(interactive "P")
|
||||
(git-rebase-set-noncommit-action
|
||||
"update-ref"
|
||||
(lambda (initial)
|
||||
(or (magit-completing-read "Ref" (magit-list-refs) nil nil initial)
|
||||
""))
|
||||
arg))
|
||||
|
||||
(defun git-rebase-merge (arg)
|
||||
"Add a merge command after the current commit.
|
||||
If there is already a merge command on the current line, then
|
||||
@@ -639,15 +653,15 @@ Like `undo' but works in read-only buffers."
|
||||
(undo arg)))
|
||||
|
||||
(defun git-rebase--show-commit (&optional scroll)
|
||||
(let ((disable-magit-save-buffers t))
|
||||
(let ((magit--disable-save-buffers t))
|
||||
(save-excursion
|
||||
(goto-char (line-beginning-position))
|
||||
(--if-let (with-slots (action-type target) (git-rebase-current-line)
|
||||
(and (eq action-type 'commit)
|
||||
target))
|
||||
(pcase scroll
|
||||
(`up (magit-diff-show-or-scroll-up))
|
||||
(`down (magit-diff-show-or-scroll-down))
|
||||
('up (magit-diff-show-or-scroll-up))
|
||||
('down (magit-diff-show-or-scroll-down))
|
||||
(_ (apply #'magit-show-commit it
|
||||
(magit-diff-arguments 'magit-revision-mode))))
|
||||
(ding)))))
|
||||
@@ -689,10 +703,10 @@ Like `forward-line' but go into the opposite direction."
|
||||
(define-derived-mode git-rebase-mode special-mode "Git Rebase"
|
||||
"Major mode for editing of a Git rebase file.
|
||||
|
||||
Rebase files are generated when you run 'git rebase -i' or run
|
||||
Rebase files are generated when you run \"git rebase -i\" or run
|
||||
`magit-interactive-rebase'. They describe how Git should perform
|
||||
the rebase. See the documentation for git-rebase (e.g., by
|
||||
running 'man git-rebase' at the command line) for details."
|
||||
running \"man git-rebase\" at the command line) for details."
|
||||
:group 'git-rebase
|
||||
(setq comment-start (or (magit-get "core.commentChar") "#"))
|
||||
(setq git-rebase-comment-re (concat "^" (regexp-quote comment-start)))
|
||||
@@ -705,11 +719,11 @@ running 'man git-rebase' at the command line) for details."
|
||||
(with-editor-mode 1))
|
||||
(when git-rebase-confirm-cancel
|
||||
(add-hook 'with-editor-cancel-query-functions
|
||||
'git-rebase-cancel-confirm nil t))
|
||||
(setq-local redisplay-highlight-region-function 'git-rebase-highlight-region)
|
||||
(setq-local redisplay-unhighlight-region-function 'git-rebase-unhighlight-region)
|
||||
(add-hook 'with-editor-pre-cancel-hook 'git-rebase-autostash-save nil t)
|
||||
(add-hook 'with-editor-post-cancel-hook 'git-rebase-autostash-apply nil t)
|
||||
#'git-rebase-cancel-confirm nil t))
|
||||
(setq-local redisplay-highlight-region-function #'git-rebase-highlight-region)
|
||||
(setq-local redisplay-unhighlight-region-function #'git-rebase-unhighlight-region)
|
||||
(add-hook 'with-editor-pre-cancel-hook #'git-rebase-autostash-save nil t)
|
||||
(add-hook 'with-editor-post-cancel-hook #'git-rebase-autostash-apply nil t)
|
||||
(setq imenu-prev-index-position-function
|
||||
#'magit-imenu--rebase-prev-index-position-function)
|
||||
(setq imenu-extract-index-name-function
|
||||
@@ -786,48 +800,73 @@ By default, this is the same except for the \"pick\" command."
|
||||
nil t))
|
||||
(goto-char (line-beginning-position))
|
||||
(pcase-dolist (`(,cmd . ,desc) git-rebase-command-descriptions)
|
||||
(insert (format "%s %-8s %s\n"
|
||||
(insert (format (propertize "%s %s %s\n"
|
||||
'font-lock-face 'font-lock-comment-face)
|
||||
comment-start
|
||||
(substitute-command-keys (format "\\[%s]" cmd))
|
||||
(string-pad
|
||||
(substitute-command-keys (format "\\[%s]" cmd)) 8)
|
||||
desc)))
|
||||
(while (re-search-forward (concat git-rebase-comment-re
|
||||
"\\( ?\\)\\([^\n,],\\) "
|
||||
"\\([^\n ]+\\) ")
|
||||
nil t)
|
||||
(let ((cmd (intern (concat "git-rebase-" (match-string 3)))))
|
||||
(if (not (fboundp cmd))
|
||||
(delete-region (line-beginning-position) (1+ (line-end-position)))
|
||||
(replace-match " " t t nil 1)
|
||||
(replace-match
|
||||
(format "%-8s"
|
||||
(mapconcat #'key-description
|
||||
(--remove (eq (elt it 0) 'menu-bar)
|
||||
(reverse (where-is-internal
|
||||
cmd git-rebase-mode-map)))
|
||||
", "))
|
||||
t t nil 2))))))))
|
||||
(while (re-search-forward
|
||||
(concat git-rebase-comment-re "\\(?:"
|
||||
"\\( \\.? *\\)\\|"
|
||||
"\\( +\\)\\([^\n,],\\) \\([^\n ]+\\) \\)")
|
||||
nil t)
|
||||
(if (match-string 1)
|
||||
(replace-match (make-string 10 ?\s) t t nil 1)
|
||||
(let ((cmd (intern (concat "git-rebase-" (match-string 4)))))
|
||||
(if (not (fboundp cmd))
|
||||
(delete-region (line-beginning-position)
|
||||
(1+ (line-end-position)))
|
||||
(add-text-properties (line-beginning-position)
|
||||
(1+ (line-end-position))
|
||||
'(font-lock-face font-lock-comment-face))
|
||||
(replace-match " " t t nil 2)
|
||||
(replace-match
|
||||
(string-pad
|
||||
(save-match-data
|
||||
(substitute-command-keys (format "\\[%s]" cmd)))
|
||||
8)
|
||||
t t nil 3)))))))))
|
||||
|
||||
(add-hook 'git-rebase-mode-hook 'git-rebase-mode-show-keybindings t)
|
||||
(add-hook 'git-rebase-mode-hook #'git-rebase-mode-show-keybindings t)
|
||||
|
||||
(defun git-rebase-mode-disable-before-save-hook ()
|
||||
(set (make-local-variable 'before-save-hook) nil))
|
||||
|
||||
(add-hook 'git-rebase-mode-hook 'git-rebase-mode-disable-before-save-hook)
|
||||
(add-hook 'git-rebase-mode-hook #'git-rebase-mode-disable-before-save-hook)
|
||||
|
||||
;;;###autoload
|
||||
(defconst git-rebase-filename-regexp "/git-rebase-todo\\'")
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist
|
||||
(cons git-rebase-filename-regexp 'git-rebase-mode))
|
||||
(cons git-rebase-filename-regexp #'git-rebase-mode))
|
||||
|
||||
(add-to-list 'with-editor-server-window-alist
|
||||
(cons git-rebase-filename-regexp 'switch-to-buffer))
|
||||
(cons git-rebase-filename-regexp #'switch-to-buffer))
|
||||
|
||||
(with-eval-after-load 'recentf
|
||||
(add-to-list 'recentf-exclude git-rebase-filename-regexp))
|
||||
|
||||
(add-to-list 'with-editor-file-name-history-exclude git-rebase-filename-regexp)
|
||||
|
||||
;;; Imenu Support
|
||||
|
||||
(defun magit-imenu--rebase-prev-index-position-function ()
|
||||
"Move point to previous commit in git-rebase buffer.
|
||||
Used as a value for `imenu-prev-index-position-function'."
|
||||
(catch 'found
|
||||
(while (not (bobp))
|
||||
(git-rebase-backward-line)
|
||||
(when (git-rebase-line-p)
|
||||
(throw 'found t)))))
|
||||
|
||||
(defun magit-imenu--rebase-extract-index-name-function ()
|
||||
"Return imenu name for line at point.
|
||||
Point should be at the beginning of the line. This function
|
||||
is used as a value for `imenu-extract-index-name-function'."
|
||||
(buffer-substring-no-properties (line-beginning-position)
|
||||
(line-end-position)))
|
||||
|
||||
;;; _
|
||||
(provide 'git-rebase)
|
||||
;;; git-rebase.el ends here
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-apply.el --- apply Git diffs -*- lexical-binding: t -*-
|
||||
;;; magit-apply.el --- Apply Git diffs -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -50,9 +47,6 @@
|
||||
(url &optional path name args))
|
||||
(declare-function magit-submodule-read-name-for-path "magit-submodule"
|
||||
(path &optional prefer-short))
|
||||
(declare-function borg--maybe-absorb-gitdir "borg" (pkg))
|
||||
(declare-function borg--sort-submodule-sections "borg" (file))
|
||||
(declare-function borg-assimilate "borg" (package url &optional partially))
|
||||
(defvar borg-user-emacs-directory)
|
||||
|
||||
(cl-eval-when (compile load)
|
||||
@@ -109,9 +103,6 @@ is a member of `magit-post-stage-hook-commands'."
|
||||
:group 'magit-commands
|
||||
:type 'hook)
|
||||
|
||||
(defvar magit-post-stage-hook-commands
|
||||
'(magit-stage magit-stage-file magit-stage-modified))
|
||||
|
||||
(defcustom magit-post-unstage-hook nil
|
||||
"Hook run after unstaging changes.
|
||||
This hook is run by `magit-refresh' if `this-command'
|
||||
@@ -120,9 +111,6 @@ is a member of `magit-post-unstage-hook-commands'."
|
||||
:group 'magit-commands
|
||||
:type 'hook)
|
||||
|
||||
(defvar magit-post-unstage-hook-commands
|
||||
'(magit-unstage magit-unstage-file magit-unstage-all))
|
||||
|
||||
;;; Commands
|
||||
;;;; Apply
|
||||
|
||||
@@ -133,15 +121,15 @@ so causes the change to be applied to the index as well."
|
||||
(interactive (and current-prefix-arg (list "--3way")))
|
||||
(--when-let (magit-apply--get-selection)
|
||||
(pcase (list (magit-diff-type) (magit-diff-scope))
|
||||
(`(,(or `unstaged `staged) ,_)
|
||||
(`(,(or 'unstaged 'staged) ,_)
|
||||
(user-error "Change is already in the working tree"))
|
||||
(`(untracked ,(or `file `files))
|
||||
(call-interactively 'magit-am))
|
||||
(`(untracked ,(or 'file 'files))
|
||||
(call-interactively #'magit-am))
|
||||
(`(,_ region) (magit-apply-region it args))
|
||||
(`(,_ hunk) (magit-apply-hunk it args))
|
||||
(`(,_ hunks) (magit-apply-hunks it args))
|
||||
(`(rebase-sequence file)
|
||||
(call-interactively 'magit-patch-apply))
|
||||
(call-interactively #'magit-patch-apply))
|
||||
(`(,_ file) (magit-apply-diff it args))
|
||||
(`(,_ files) (magit-apply-diffs it args)))))
|
||||
|
||||
@@ -258,9 +246,9 @@ adjusted as \"@@ -10,6 +10,7 @@\" and \"@@ -18,6 +19,7 @@\"."
|
||||
(or (magit-region-sections '(hunk file module) t)
|
||||
(let ((section (magit-current-section)))
|
||||
(pcase (oref section type)
|
||||
((or `hunk `file `module) section)
|
||||
((or `staged `unstaged `untracked
|
||||
`stashed-index `stashed-worktree `stashed-untracked)
|
||||
((or 'hunk 'file 'module) section)
|
||||
((or 'staged 'unstaged 'untracked
|
||||
'stashed-index 'stashed-worktree 'stashed-untracked)
|
||||
(oref section children))
|
||||
(_ (user-error "Cannot apply this, it's not a change"))))))
|
||||
|
||||
@@ -298,16 +286,16 @@ at point, stage the file but not its content."
|
||||
(`(unstaged region ,_) (magit-apply-region it "--cached"))
|
||||
(`(unstaged hunk ,_) (magit-apply-hunk it "--cached"))
|
||||
(`(unstaged hunks ,_) (magit-apply-hunks it "--cached"))
|
||||
(`(unstaged file t) (magit-apply-diff it "--cached"))
|
||||
(`(unstaged files t) (magit-apply-diffs it "--cached"))
|
||||
(`(unstaged list t) (magit-apply-diffs it "--cached"))
|
||||
(`(unstaged file nil) (magit-stage-1 "-u" (list (oref it value))))
|
||||
(`(unstaged files nil) (magit-stage-1 "-u" (magit-region-values nil t)))
|
||||
(`(unstaged list nil) (magit-stage-modified))
|
||||
('(unstaged file t) (magit-apply-diff it "--cached"))
|
||||
('(unstaged files t) (magit-apply-diffs it "--cached"))
|
||||
('(unstaged list t) (magit-apply-diffs it "--cached"))
|
||||
('(unstaged file nil) (magit-stage-1 "-u" (list (oref it value))))
|
||||
('(unstaged files nil) (magit-stage-1 "-u" (magit-region-values nil t)))
|
||||
('(unstaged list nil) (magit-stage-modified))
|
||||
(`(staged ,_ ,_) (user-error "Already staged"))
|
||||
(`(committed ,_ ,_) (user-error "Cannot stage committed changes"))
|
||||
(`(undefined ,_ ,_) (user-error "Cannot stage this change")))
|
||||
(call-interactively 'magit-stage-file)))
|
||||
(call-interactively #'magit-stage-file)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-stage-file (file)
|
||||
@@ -351,9 +339,9 @@ ignored) files."
|
||||
(defun magit-stage-untracked (&optional intent)
|
||||
(let* ((section (magit-current-section))
|
||||
(files (pcase (magit-diff-scope)
|
||||
(`file (list (oref section value)))
|
||||
(`files (magit-region-values nil t))
|
||||
(`list (magit-untracked-files))))
|
||||
('file (list (oref section value)))
|
||||
('files (magit-region-values nil t))
|
||||
('list (magit-untracked-files))))
|
||||
plain repos)
|
||||
(dolist (file files)
|
||||
(if (and (not (file-symlink-p file))
|
||||
@@ -371,27 +359,36 @@ ignored) files."
|
||||
(goto-char (oref (magit-get-section
|
||||
`((file . ,repo) (untracked) (status)))
|
||||
start))
|
||||
(let* ((topdir (magit-toplevel))
|
||||
(url (let ((default-directory
|
||||
(file-name-as-directory (expand-file-name repo))))
|
||||
(or (magit-get "remote" (magit-get-some-remote) "url")
|
||||
(concat (file-name-as-directory ".") repo))))
|
||||
(package
|
||||
(and (equal (bound-and-true-p borg-user-emacs-directory)
|
||||
topdir)
|
||||
(file-name-nondirectory (directory-file-name repo)))))
|
||||
(if (and package
|
||||
(y-or-n-p (format "Also assimilate `%s' drone?" package)))
|
||||
(borg-assimilate package url)
|
||||
(magit-submodule-add-1
|
||||
url repo (magit-submodule-read-name-for-path repo package))
|
||||
(when package
|
||||
(borg--sort-submodule-sections
|
||||
(expand-file-name ".gitmodules" topdir))
|
||||
(let ((default-directory borg-user-emacs-directory))
|
||||
(borg--maybe-absorb-gitdir package)))))))
|
||||
(when (and (fboundp 'borg-assimilate)
|
||||
(fboundp 'borg--maybe-absorb-gitdir)
|
||||
(fboundp 'borg--sort-submodule-sections))
|
||||
(let* ((topdir (magit-toplevel))
|
||||
(url (let ((default-directory
|
||||
(file-name-as-directory (expand-file-name repo))))
|
||||
(or (magit-get "remote" (magit-get-some-remote) "url")
|
||||
(concat (file-name-as-directory ".") repo))))
|
||||
(package
|
||||
(and (equal borg-user-emacs-directory topdir)
|
||||
(file-name-nondirectory (directory-file-name repo)))))
|
||||
(if (and package
|
||||
(y-or-n-p (format "Also assimilate `%s' drone?" package)))
|
||||
(borg-assimilate package url)
|
||||
(magit-submodule-add-1
|
||||
url repo (magit-submodule-read-name-for-path repo package))
|
||||
(when package
|
||||
(borg--sort-submodule-sections
|
||||
(expand-file-name ".gitmodules" topdir))
|
||||
(let ((default-directory borg-user-emacs-directory))
|
||||
(borg--maybe-absorb-gitdir package))))))))
|
||||
(magit-wip-commit-after-apply files " after stage")))
|
||||
|
||||
(defvar magit-post-stage-hook-commands
|
||||
'(magit-stage magit-stage-file magit-stage-modified))
|
||||
|
||||
(defun magit-run-post-stage-hook ()
|
||||
(when (memq this-command magit-post-stage-hook-commands)
|
||||
(magit-run-hook-with-benchmark 'magit-post-stage-hook)))
|
||||
|
||||
;;;; Unstage
|
||||
|
||||
(defun magit-unstage ()
|
||||
@@ -408,12 +405,12 @@ ignored) files."
|
||||
(`(staged region ,_) (magit-apply-region it "--reverse" "--cached"))
|
||||
(`(staged hunk ,_) (magit-apply-hunk it "--reverse" "--cached"))
|
||||
(`(staged hunks ,_) (magit-apply-hunks it "--reverse" "--cached"))
|
||||
(`(staged file t) (magit-apply-diff it "--reverse" "--cached"))
|
||||
(`(staged files t) (magit-apply-diffs it "--reverse" "--cached"))
|
||||
(`(staged list t) (magit-apply-diffs it "--reverse" "--cached"))
|
||||
(`(staged file nil) (magit-unstage-1 (list (oref it value))))
|
||||
(`(staged files nil) (magit-unstage-1 (magit-region-values nil t)))
|
||||
(`(staged list nil) (magit-unstage-all))
|
||||
('(staged file t) (magit-apply-diff it "--reverse" "--cached"))
|
||||
('(staged files t) (magit-apply-diffs it "--reverse" "--cached"))
|
||||
('(staged list t) (magit-apply-diffs it "--reverse" "--cached"))
|
||||
('(staged file nil) (magit-unstage-1 (list (oref it value))))
|
||||
('(staged files nil) (magit-unstage-1 (magit-region-values nil t)))
|
||||
('(staged list nil) (magit-unstage-all))
|
||||
(`(committed ,_ ,_) (if magit-unstage-committed
|
||||
(magit-reverse-in-index)
|
||||
(user-error "Cannot unstage committed changes")))
|
||||
@@ -463,6 +460,13 @@ without requiring confirmation."
|
||||
(magit-run-git "reset" "HEAD" "--" magit-buffer-diff-files)
|
||||
(magit-wip-commit-after-apply nil " after unstage"))
|
||||
|
||||
(defvar magit-post-unstage-hook-commands
|
||||
'(magit-unstage magit-unstage-file magit-unstage-all))
|
||||
|
||||
(defun magit-run-post-unstage-hook ()
|
||||
(when (memq this-command magit-post-unstage-hook-commands)
|
||||
(magit-run-hook-with-benchmark 'magit-post-unstage-hook)))
|
||||
|
||||
;;;; Discard
|
||||
|
||||
(defun magit-discard ()
|
||||
@@ -491,8 +495,8 @@ of a side, then keep that side without prompting."
|
||||
(magit-confirm 'discard "Discard hunk")
|
||||
(let ((file (magit-section-parent-value section)))
|
||||
(pcase (cddr (car (magit-file-status file)))
|
||||
(`(?U ?U) (magit-smerge-keep-current))
|
||||
(_ (magit-discard-apply section 'magit-apply-hunk)))))
|
||||
('(?U ?U) (magit-smerge-keep-current))
|
||||
(_ (magit-discard-apply section #'magit-apply-hunk)))))
|
||||
|
||||
(defun magit-discard-apply (section apply)
|
||||
(if (eq (magit-diff-type section) 'unstaged)
|
||||
@@ -511,7 +515,7 @@ of a side, then keep that side without prompting."
|
||||
(magit-confirm 'discard (format "Discard %s hunks from %s"
|
||||
(length sections)
|
||||
(magit-section-parent-value (car sections))))
|
||||
(magit-discard-apply-n sections 'magit-apply-hunks))
|
||||
(magit-discard-apply-n sections #'magit-apply-hunks))
|
||||
|
||||
(defun magit-discard-apply-n (sections apply)
|
||||
(let ((section (car sections)))
|
||||
@@ -543,16 +547,17 @@ of a side, then keep that side without prompting."
|
||||
(`unstaged ?Y)
|
||||
(`untracked ?Z))
|
||||
(cddr (assoc file status)))
|
||||
(`(?Z) (dolist (f (magit-untracked-files nil file))
|
||||
('(?Z) (dolist (f (magit-untracked-files nil file))
|
||||
(push f delete)))
|
||||
((or `(?Z ?? ??) `(?Z ?! ?!)) (push file delete))
|
||||
((or `(?Z ?D ? ) `(,_ ?D ?D)) (push file delete))
|
||||
((or '(?Z ?? ??) '(?Z ?! ?!)) (push file delete))
|
||||
('(?Z ?D ? ) (push file delete))
|
||||
(`(,_ ?D ?D) (push file resolve))
|
||||
((or `(,_ ?U ,_) `(,_ ,_ ?U)) (push file resolve))
|
||||
(`(,_ ?A ?A) (push file resolve))
|
||||
(`(?X ?M ,(or ? ?M ?D)) (push section discard))
|
||||
(`(?Y ,_ ?M ) (push section discard))
|
||||
(`(?X ?A ?M ) (push file discard-new))
|
||||
(`(?X ?C ?M ) (push file discard-new))
|
||||
('(?X ?A ?M ) (push file discard-new))
|
||||
('(?X ?C ?M ) (push file discard-new))
|
||||
(`(?X ?A ,(or ? ?D)) (push file delete))
|
||||
(`(?X ?C ,(or ? ?D)) (push file delete))
|
||||
(`(?X ?D ,(or ? ?M )) (push file resurrect))
|
||||
@@ -654,10 +659,10 @@ of a side, then keep that side without prompting."
|
||||
(setq sections
|
||||
(--remove (member (oref it value) binaries)
|
||||
sections)))
|
||||
(cond ((= (length sections) 1)
|
||||
(cond ((length= sections 1)
|
||||
(magit-discard-apply (car sections) 'magit-apply-diff))
|
||||
(sections
|
||||
(magit-discard-apply-n sections 'magit-apply-diffs)))
|
||||
(magit-discard-apply-n sections #'magit-apply-diffs)))
|
||||
(when binaries
|
||||
(let ((modified (magit-unstaged-files t)))
|
||||
(setq binaries (--separate (member it modified) binaries)))
|
||||
@@ -689,18 +694,18 @@ so causes the change to be applied to the index as well."
|
||||
|
||||
(defun magit-reverse-region (section args)
|
||||
(magit-confirm 'reverse "Reverse region")
|
||||
(magit-reverse-apply section 'magit-apply-region args))
|
||||
(magit-reverse-apply section #'magit-apply-region args))
|
||||
|
||||
(defun magit-reverse-hunk (section args)
|
||||
(magit-confirm 'reverse "Reverse hunk")
|
||||
(magit-reverse-apply section 'magit-apply-hunk args))
|
||||
(magit-reverse-apply section #'magit-apply-hunk args))
|
||||
|
||||
(defun magit-reverse-hunks (sections args)
|
||||
(magit-confirm 'reverse
|
||||
(format "Reverse %s hunks from %s"
|
||||
(length sections)
|
||||
(magit-section-parent-value (car sections))))
|
||||
(magit-reverse-apply sections 'magit-apply-hunks args))
|
||||
(magit-reverse-apply sections #'magit-apply-hunks args))
|
||||
|
||||
(defun magit-reverse-file (section args)
|
||||
(magit-reverse-files (list section) args))
|
||||
@@ -717,10 +722,10 @@ so causes the change to be applied to the index as well."
|
||||
(--separate (member (oref it value) bs)
|
||||
sections))))
|
||||
(magit-confirm-files 'reverse (--map (oref it value) sections))
|
||||
(cond ((= (length sections) 1)
|
||||
(magit-reverse-apply (car sections) 'magit-apply-diff args))
|
||||
(cond ((length= sections 1)
|
||||
(magit-reverse-apply (car sections) #'magit-apply-diff args))
|
||||
(sections
|
||||
(magit-reverse-apply sections 'magit-apply-diffs args)))
|
||||
(magit-reverse-apply sections #'magit-apply-diffs args)))
|
||||
(when binaries
|
||||
(user-error "Cannot reverse binary files"))))
|
||||
|
||||
@@ -771,6 +776,11 @@ a separate commit. A typical workflow would be:
|
||||
(interactive)
|
||||
(magit-call-smerge #'smerge-keep-lower))
|
||||
|
||||
(defun magit-smerge-keep-all ()
|
||||
"Keep all versions of the conflict at point."
|
||||
(interactive)
|
||||
(magit-call-smerge #'smerge-keep-all))
|
||||
|
||||
(defun magit-call-smerge (fn)
|
||||
(pcase-let* ((file (magit-file-at-point t t))
|
||||
(keep (get-file-buffer file))
|
||||
@@ -786,8 +796,8 @@ a separate commit. A typical workflow would be:
|
||||
(condition-case nil
|
||||
(smerge-match-conflict)
|
||||
(error
|
||||
(if (eq fn 'smerge-keep-current)
|
||||
(when (eq this-command 'magit-discard)
|
||||
(if (eq fn #'smerge-keep-current)
|
||||
(when (eq this-command #'magit-discard)
|
||||
(re-search-forward smerge-begin-re nil t)
|
||||
(setq fn
|
||||
(magit-read-char-case "Keep side: " t
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-autorevert.el --- revert buffers when files in repository change -*- lexical-binding: t -*-
|
||||
;;; magit-autorevert.el --- Revert buffers when files in repository change -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
@@ -105,18 +102,14 @@ seconds of user inactivity. That is not desirable."
|
||||
(--when-let (find-buffer-visiting file)
|
||||
(with-current-buffer it
|
||||
(magit-turn-on-auto-revert-mode-if-desired)))
|
||||
(when (and buffer-file-name
|
||||
(when (and (not auto-revert-mode) ; see #3014
|
||||
(not global-auto-revert-mode) ; see #3460
|
||||
buffer-file-name
|
||||
(file-readable-p buffer-file-name)
|
||||
(or (< emacs-major-version 27)
|
||||
(with-no-warnings
|
||||
(condition-case nil
|
||||
(executable-find magit-git-executable t) ; see #3684
|
||||
(wrong-number-of-arguments t)))) ; very old 27 built
|
||||
(compat-executable-find (magit-git-executable) t)
|
||||
(magit-toplevel)
|
||||
(or (not magit-auto-revert-tracked-only)
|
||||
(magit-file-tracked-p buffer-file-name))
|
||||
(not auto-revert-mode) ; see #3014
|
||||
(not global-auto-revert-mode)) ; see #3460
|
||||
(magit-file-tracked-p buffer-file-name)))
|
||||
(auto-revert-mode 1))))
|
||||
|
||||
;;;###autoload
|
||||
@@ -261,7 +254,7 @@ defaults to nil) for any BUFFER."
|
||||
(auto-revert-set-timer))))
|
||||
|
||||
(advice-add 'auto-revert-buffers :around
|
||||
'auto-revert-buffers--buffer-list-filter)
|
||||
#'auto-revert-buffers--buffer-list-filter)
|
||||
|
||||
;;; _
|
||||
(provide 'magit-autorevert)
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
;;; magit-utils.el --- various utilities -*- lexical-binding: t; coding: utf-8 -*-
|
||||
;;; magit-base.el --- Early birds -*- lexical-binding:t; coding:utf-8 -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; Contains code from GNU Emacs https://www.gnu.org/software/emacs,
|
||||
;; released under the GNU General Public License version 3 or later.
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -24,23 +18,27 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;; This file contains code taken from GNU Emacs, which is
|
||||
;; Copyright (C) 1976-2022 Free Software Foundation, Inc.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This library defines several utility functions used by several
|
||||
;; other libraries which cannot depend on one another (because
|
||||
;; circular dependencies are not good). Luckily most (all) of these
|
||||
;; functions have very little (nothing) to do with Git, so we not only
|
||||
;; have to do this, it even makes sense.
|
||||
|
||||
;; Unfortunately there are also some options which are used by several
|
||||
;; libraries which cannot depend on one another, they are defined here
|
||||
;; too.
|
||||
;; This library defines utility functions, options and other things that
|
||||
;; have to be available early on because they are used by several other
|
||||
;; libraries, which cannot depend on one another, because that would lead
|
||||
;; to circular dependencies.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defconst magit--minimal-git "2.2.0")
|
||||
(defconst magit--minimal-emacs "25.1")
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'compat)
|
||||
(require 'compat-26)
|
||||
(require 'compat-27)
|
||||
(require 'dash)
|
||||
(require 'eieio)
|
||||
(require 'seq)
|
||||
@@ -48,6 +46,8 @@
|
||||
|
||||
(require 'crm)
|
||||
|
||||
(require 'magit-section)
|
||||
|
||||
(eval-when-compile (require 'ido))
|
||||
(declare-function Info-get-token "info" (pos start all &optional errorstring))
|
||||
|
||||
@@ -57,11 +57,9 @@
|
||||
(eval-when-compile (require 'which-func))
|
||||
(declare-function which-function "which-func" ())
|
||||
|
||||
(defvar magit-wip-before-change-mode)
|
||||
|
||||
;;; Options
|
||||
|
||||
(defcustom magit-completing-read-function 'magit-builtin-completing-read
|
||||
(defcustom magit-completing-read-function #'magit-builtin-completing-read
|
||||
"Function to be called when requesting input from the user.
|
||||
|
||||
If you have enabled `ivy-mode' or `helm-mode', then you don't
|
||||
@@ -85,6 +83,8 @@ alphabetical order, depending on your version of Ivy."
|
||||
|
||||
(defcustom magit-dwim-selection
|
||||
'((magit-stash-apply nil t)
|
||||
(magit-ediff-resolve-all nil t)
|
||||
(magit-ediff-resolve-rest nil t)
|
||||
(magit-stash-branch nil t)
|
||||
(magit-stash-branch-here nil t)
|
||||
(magit-stash-format-patch nil t)
|
||||
@@ -98,6 +98,7 @@ alphabetical order, depending on your version of Ivy."
|
||||
(forge-browse-pullreq nil t)
|
||||
(forge-edit-topic-title nil t)
|
||||
(forge-edit-topic-state nil t)
|
||||
(forge-edit-topic-draft nil t)
|
||||
(forge-edit-topic-milestone nil t)
|
||||
(forge-edit-topic-labels nil t)
|
||||
(forge-edit-topic-marks nil t)
|
||||
@@ -437,6 +438,45 @@ and delay of your graphical environment or operating system."
|
||||
(const :tag "view manpage using `man'" man)
|
||||
(const :tag "view manpage using `woman'" woman)))
|
||||
|
||||
;;; Section Classes
|
||||
|
||||
(defclass magit-commit-section (magit-section) ())
|
||||
|
||||
(setf (alist-get 'commit magit--section-type-alist) 'magit-commit-section)
|
||||
|
||||
(defclass magit-diff-section (magit-section) () :abstract t)
|
||||
|
||||
(defclass magit-file-section (magit-diff-section)
|
||||
((keymap :initform 'magit-file-section-map)
|
||||
(source :initform nil)
|
||||
(header :initform nil)))
|
||||
|
||||
(defclass magit-module-section (magit-file-section)
|
||||
((keymap :initform 'magit-module-section-map)
|
||||
(range :initform nil)))
|
||||
|
||||
(defclass magit-hunk-section (magit-diff-section)
|
||||
((keymap :initform 'magit-hunk-section-map)
|
||||
(refined :initform nil)
|
||||
(combined :initform nil)
|
||||
(from-range :initform nil)
|
||||
(from-ranges :initform nil)
|
||||
(to-range :initform nil)
|
||||
(about :initform nil)))
|
||||
|
||||
(setf (alist-get 'file magit--section-type-alist) 'magit-file-section)
|
||||
(setf (alist-get 'module magit--section-type-alist) 'magit-module-section)
|
||||
(setf (alist-get 'hunk magit--section-type-alist) 'magit-hunk-section)
|
||||
|
||||
(defclass magit-log-section (magit-section) () :abstract t)
|
||||
(defclass magit-unpulled-section (magit-log-section) ())
|
||||
(defclass magit-unpushed-section (magit-log-section) ())
|
||||
(defclass magit-unmerged-section (magit-log-section) ())
|
||||
|
||||
(setf (alist-get 'unpulled magit--section-type-alist) 'magit-unpulled-section)
|
||||
(setf (alist-get 'unpushed magit--section-type-alist) 'magit-unpushed-section)
|
||||
(setf (alist-get 'unmerged magit--section-type-alist) 'magit-unmerged-section)
|
||||
|
||||
;;; User Input
|
||||
|
||||
(defvar helm-completion-in-region-default-sort-fn)
|
||||
@@ -540,7 +580,7 @@ acts similarly to `completing-read', except for the following:
|
||||
(unless (or (bound-and-true-p helm-mode)
|
||||
(bound-and-true-p ivy-mode))
|
||||
(setq choices (magit--completion-table choices)))
|
||||
(cl-letf (((symbol-function 'completion-pcm--all-completions)))
|
||||
(cl-letf (((symbol-function #'completion-pcm--all-completions)))
|
||||
(when (< emacs-major-version 26)
|
||||
(fset 'completion-pcm--all-completions
|
||||
'magit-completion-pcm--all-completions))
|
||||
@@ -557,14 +597,14 @@ Set up the `crm' variables needed to read multiple values with
|
||||
`read-from-minibuffer'.
|
||||
|
||||
SEP is a regexp matching characters that can separate choices.
|
||||
When SEP is nil, it defaults to `crm-default-separator'.
|
||||
DEFAULT, HIST, and KEYMAP are passed to `read-from-minibuffer'.
|
||||
When KEYMAP is nil, it defaults to `crm-local-completion-map'.
|
||||
When SEP is nil, it defaults to `crm-separator'. DEFAULT, HIST,
|
||||
and KEYMAP are passed to `read-from-minibuffer'. When KEYMAP is
|
||||
nil, it defaults to `crm-local-completion-map'.
|
||||
|
||||
Unlike `completing-read-multiple', the return value is not split
|
||||
into a list."
|
||||
(declare (obsolete magit-completing-read-multiple* "Magit 3.1.0"))
|
||||
(let* ((crm-separator (or sep crm-default-separator))
|
||||
(let* ((crm-separator (or sep crm-separator))
|
||||
(crm-completion-table (magit--completion-table choices))
|
||||
(choose-completion-string-functions
|
||||
'(crm--choose-completion-string))
|
||||
@@ -574,7 +614,7 @@ into a list."
|
||||
(helm-crm-default-separator nil)
|
||||
(ivy-sort-matches-functions-alist nil)
|
||||
(input
|
||||
(cl-letf (((symbol-function 'completion-pcm--all-completions)))
|
||||
(cl-letf (((symbol-function #'completion-pcm--all-completions)))
|
||||
(when (< emacs-major-version 26)
|
||||
(fset 'completion-pcm--all-completions
|
||||
'magit-completion-pcm--all-completions))
|
||||
@@ -604,8 +644,8 @@ third-party completion frameworks."
|
||||
;; that string. Use a variable to pass along the raw user
|
||||
;; input string. aa5f098ab
|
||||
(input nil)
|
||||
(split-string (symbol-function 'split-string))
|
||||
((symbol-function 'split-string)
|
||||
(split-string (symbol-function #'split-string))
|
||||
((symbol-function #'split-string)
|
||||
(lambda (string &optional separators omit-nulls trim)
|
||||
(when (and no-split
|
||||
(equal separators crm-separator)
|
||||
@@ -614,10 +654,10 @@ third-party completion frameworks."
|
||||
(funcall split-string string separators omit-nulls trim)))
|
||||
;; In Emacs 25 this function has a bug, so we use a copy of the
|
||||
;; version from Emacs 26. bef9c7aa3
|
||||
((symbol-function 'completion-pcm--all-completions)
|
||||
((symbol-function #'completion-pcm--all-completions)
|
||||
(if (< emacs-major-version 26)
|
||||
'magit-completion-pcm--all-completions
|
||||
(symbol-function 'completion-pcm--all-completions)))
|
||||
(symbol-function #'completion-pcm--all-completions)))
|
||||
;; Prevent `BUILT-IN' completion from messing up our existing
|
||||
;; order of the completion candidates. aa5f098ab
|
||||
(table (magit--completion-table table))
|
||||
@@ -630,25 +670,10 @@ third-party completion frameworks."
|
||||
;; when reading commit ranges. 798aff564
|
||||
(helm-crm-default-separator
|
||||
(if no-split nil (bound-and-true-p helm-crm-default-separator)))
|
||||
(values
|
||||
(if (and no-split
|
||||
(advice-member-p 'consult-completing-read-multiple
|
||||
'completing-read-multiple))
|
||||
;; Our NO-SPLIT hack is not compatible with `CONSULT's
|
||||
;; implemenation so fall back to the original function.
|
||||
;; #4437
|
||||
(unwind-protect
|
||||
(progn
|
||||
(advice-remove 'completing-read-multiple
|
||||
'consult-completing-read-multiple)
|
||||
(completing-read-multiple
|
||||
prompt table predicate require-match initial-input
|
||||
hist def inherit-input-method))
|
||||
(advice-add 'completing-read-multiple :override
|
||||
'consult-completing-read-multiple))
|
||||
(completing-read-multiple
|
||||
prompt table predicate require-match initial-input
|
||||
hist def inherit-input-method))))
|
||||
;; And now, the moment we have all been waiting for...
|
||||
(values (completing-read-multiple
|
||||
prompt table predicate require-match initial-input
|
||||
hist def inherit-input-method)))
|
||||
(if no-split input values)))
|
||||
|
||||
(defun magit-ido-completing-read
|
||||
@@ -673,7 +698,7 @@ back to built-in `completing-read' for now." :error)
|
||||
initial-input hist def)))
|
||||
|
||||
(defun magit-prompt-with-default (prompt def)
|
||||
(if (and def (> (length prompt) 2)
|
||||
(if (and def (length> prompt 2)
|
||||
(string-equal ": " (substring prompt -2)))
|
||||
(format "%s (default %s): " (substring prompt 0 -2) def)
|
||||
prompt))
|
||||
@@ -681,8 +706,8 @@ back to built-in `completing-read' for now." :error)
|
||||
(defvar magit-minibuffer-local-ns-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map minibuffer-local-map)
|
||||
(define-key map "\s" 'magit-whitespace-disallowed)
|
||||
(define-key map "\t" 'magit-whitespace-disallowed)
|
||||
(define-key map "\s" #'magit-whitespace-disallowed)
|
||||
(define-key map "\t" #'magit-whitespace-disallowed)
|
||||
map))
|
||||
|
||||
(defun magit-whitespace-disallowed ()
|
||||
@@ -782,9 +807,9 @@ ACTION is a member of option `magit-slow-confirm'."
|
||||
(or (not sitems) items))
|
||||
((not sitems)
|
||||
(magit-y-or-n-p prompt action))
|
||||
((= (length items) 1)
|
||||
((length= items 1)
|
||||
(and (magit-y-or-n-p prompt action) items))
|
||||
((> (length items) 1)
|
||||
((length> items 1)
|
||||
(and (magit-y-or-n-p (concat (mapconcat #'identity items "\n")
|
||||
"\n\n" prompt-n)
|
||||
action)
|
||||
@@ -802,8 +827,9 @@ ACTION is a member of option `magit-slow-confirm'."
|
||||
|
||||
(defun magit-confirm-make-prompt (action)
|
||||
(let ((prompt (symbol-name action)))
|
||||
(replace-regexp-in-string
|
||||
"-" " " (concat (upcase (substring prompt 0 1)) (substring prompt 1)))))
|
||||
(string-replace "-" " "
|
||||
(concat (upcase (substring prompt 0 1))
|
||||
(substring prompt 1)))))
|
||||
|
||||
(defun magit-read-number-string (prompt &optional default _history)
|
||||
"Like `read-number' but return value is a string.
|
||||
@@ -836,6 +862,7 @@ See info node `(magit)Debugging Tools' for more information."
|
||||
((not (equal lib "libgit"))
|
||||
(error "Cannot find mandatory dependency %s" lib)))))
|
||||
'(;; Like `LOAD_PATH' in `default.mk'.
|
||||
"compat"
|
||||
"dash"
|
||||
"libgit"
|
||||
"transient"
|
||||
@@ -910,38 +937,6 @@ with the text area."
|
||||
(concat (propertize " " 'display '(space :align-to 0))
|
||||
string)))
|
||||
|
||||
(defun magit-face-property-all (face string)
|
||||
"Return non-nil if FACE is present in all of STRING."
|
||||
(catch 'missing
|
||||
(let ((pos 0))
|
||||
(while (setq pos (next-single-property-change pos 'font-lock-face string))
|
||||
(let ((val (get-text-property pos 'font-lock-face string)))
|
||||
(unless (if (consp val)
|
||||
(memq face val)
|
||||
(eq face val))
|
||||
(throw 'missing nil))))
|
||||
(not pos))))
|
||||
|
||||
(defun magit--add-face-text-property (beg end face &optional append object)
|
||||
"Like `add-face-text-property' but for `font-lock-face'."
|
||||
(while (< beg end)
|
||||
(let* ((pos (next-single-property-change beg 'font-lock-face object end))
|
||||
(val (get-text-property beg 'font-lock-face object))
|
||||
(val (if (listp val) val (list val))))
|
||||
(put-text-property beg pos 'font-lock-face
|
||||
(if append
|
||||
(append val (list face))
|
||||
(cons face val))
|
||||
object)
|
||||
(setq beg pos))))
|
||||
|
||||
(defun magit--propertize-face (string face)
|
||||
(propertize string 'face face 'font-lock-face face))
|
||||
|
||||
(defun magit--put-face (beg end face string)
|
||||
(put-text-property beg end 'face face string)
|
||||
(put-text-property beg end 'font-lock-face face string))
|
||||
|
||||
(defun magit--format-spec (format specification)
|
||||
"Like `format-spec' but preserve text properties in SPECIFICATION."
|
||||
(with-temp-buffer
|
||||
@@ -1029,7 +1024,9 @@ and https://github.com/magit/magit/issues/2295."
|
||||
(and (file-directory-p filename)
|
||||
(file-accessible-directory-p filename)))
|
||||
|
||||
(when (magit--version>= emacs-version "25.1")
|
||||
(when (< emacs-major-version 27)
|
||||
;; Work around https://debbugs.gnu.org/cgi/bugreport.cgi?bug=21559.
|
||||
;; Fixed by cb55ccae8be946f1562d74718086a4c8c8308ee5 in Emacs 27.1.
|
||||
(with-eval-after-load 'vc-git
|
||||
(defun vc-git-conflicted-files (directory)
|
||||
"Return the list of files with conflicts in DIRECTORY."
|
||||
@@ -1104,12 +1101,12 @@ setting `imenu--index-alist' to nil before calling that function."
|
||||
|
||||
(defun magit-custom-initialize-reset (symbol exp)
|
||||
"Initialize SYMBOL based on EXP.
|
||||
Set the symbol, using `set-default' (unlike
|
||||
`custom-initialize-reset' which uses the `:set' function if any.)
|
||||
The value is either the symbol's current value
|
||||
(as obtained using the `:get' function), if any,
|
||||
or the value in the symbol's `saved-value' property if any,
|
||||
or (last of all) the value of EXP."
|
||||
Set the value of the variable SYMBOL, using `set-default'
|
||||
\(unlike `custom-initialize-reset', which uses the `:set'
|
||||
function if any). The value is either the symbol's current
|
||||
value (as obtained using the `:get' function), if any, or
|
||||
the value in the symbol's `saved-value' property if any, or
|
||||
\(last of all) the value of EXP."
|
||||
(set-default-toplevel-value
|
||||
symbol
|
||||
(condition-case nil
|
||||
@@ -1155,10 +1152,10 @@ or (last of all) the value of EXP."
|
||||
"\\*note[ \n\t]+\\([^:]*\\):\\(:\\|[ \n\t]*(\\)?")))
|
||||
(if (and node (string-match "^(gitman)\\(.+\\)" node))
|
||||
(pcase magit-view-git-manual-method
|
||||
(`info (funcall fn fork))
|
||||
(`man (require 'man)
|
||||
('info (funcall fn fork))
|
||||
('man (require 'man)
|
||||
(man (match-string 1 node)))
|
||||
(`woman (require 'woman)
|
||||
('woman (require 'woman)
|
||||
(woman (match-string 1 node)))
|
||||
(_
|
||||
(user-error "Invalid value for `magit-view-git-manual-method'")))
|
||||
@@ -1166,16 +1163,16 @@ or (last of all) the value of EXP."
|
||||
|
||||
;;;###autoload
|
||||
(advice-add 'Info-follow-nearest-node :around
|
||||
'Info-follow-nearest-node--magit-gitman)
|
||||
#'Info-follow-nearest-node--magit-gitman)
|
||||
|
||||
;; When making changes here, then also adjust the copy in docs/Makefile.
|
||||
;;;###autoload
|
||||
(advice-add 'org-man-export :around 'org-man-export--magit-gitman)
|
||||
(advice-add 'org-man-export :around #'org-man-export--magit-gitman)
|
||||
;;;###autoload
|
||||
(defun org-man-export--magit-gitman (fn link description format)
|
||||
(if (and (eq format 'texinfo)
|
||||
(string-match-p "\\`git" link))
|
||||
(replace-regexp-in-string "%s" link "
|
||||
(string-prefix-p "git" link))
|
||||
(string-replace "%s" link "
|
||||
@ifinfo
|
||||
@ref{%s,,,gitman,}.
|
||||
@end ifinfo
|
||||
@@ -1211,7 +1208,7 @@ See <https://github.com/raxod502/straight.el/issues/520>."
|
||||
|
||||
(if (fboundp 'with-connection-local-variables)
|
||||
(defalias 'magit--with-connection-local-variables
|
||||
'with-connection-local-variables)
|
||||
#'with-connection-local-variables)
|
||||
(defmacro magit--with-connection-local-variables (&rest body)
|
||||
"Abridged `with-connection-local-variables' for pre Emacs 27 compatibility.
|
||||
Bind shell file name and switch for remote execution.
|
||||
@@ -1259,5 +1256,5 @@ Like `message', except that `message-log-max' is bound to nil."
|
||||
,@body))))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-utils)
|
||||
;;; magit-utils.el ends here
|
||||
(provide 'magit-base)
|
||||
;;; magit-base.el ends here
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-bisect.el --- bisect support for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-bisect.el --- Bisect support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2011-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -224,10 +221,10 @@ bisect run'."
|
||||
(magit-process-sentinel process event)
|
||||
(when (buffer-live-p (process-buffer process))
|
||||
(with-current-buffer (process-buffer process)
|
||||
(when-let ((section (get-text-property (point) 'magit-section))
|
||||
(output (buffer-substring-no-properties
|
||||
(oref section content)
|
||||
(oref section end))))
|
||||
(when-let* ((section (magit-section-at))
|
||||
(output (buffer-substring-no-properties
|
||||
(oref section content)
|
||||
(oref section end))))
|
||||
(with-temp-file (magit-git-dir "BISECT_CMD_OUTPUT")
|
||||
(insert output)))))
|
||||
(magit-refresh))
|
||||
@@ -250,7 +247,7 @@ bisect run'."
|
||||
"It appears you have invoked `git bisect' from a shell."
|
||||
"There is nothing wrong with that, we just cannot display"
|
||||
"anything useful here. Consult the shell output instead.")))
|
||||
(done-re "^\\([a-z0-9]\\{40\\}\\) is the first bad commit$")
|
||||
(done-re "^\\([a-z0-9]\\{40,\\}\\) is the first bad commit$")
|
||||
(bad-line (or (and (string-match done-re (car lines))
|
||||
(pop lines))
|
||||
(--first (string-match done-re it) lines))))
|
||||
@@ -268,7 +265,7 @@ bisect run'."
|
||||
(when (magit-bisect-in-progress-p)
|
||||
(magit-insert-section (bisect-view)
|
||||
(magit-insert-heading "Bisect Rest:")
|
||||
(magit-git-wash (apply-partially 'magit-log-wash-log 'bisect-vis)
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'bisect-vis)
|
||||
"bisect" "visualize" "git" "log"
|
||||
"--format=%h%x00%D%x00%s" "--decorate=full"
|
||||
(and magit-bisect-show-graph "--graph")))))
|
||||
@@ -295,11 +292,11 @@ bisect run'."
|
||||
'magit-section-secondary-heading))
|
||||
(magit-insert-heading)
|
||||
(magit-wash-sequence
|
||||
(apply-partially 'magit-log-wash-rev 'bisect-log
|
||||
(apply-partially #'magit-log-wash-rev 'bisect-log
|
||||
(magit-abbrev-length)))
|
||||
(insert ?\n)))))
|
||||
(when (re-search-forward
|
||||
"# first bad commit: \\[\\([a-z0-9]\\{40\\}\\)\\] [^\n]+\n" nil t)
|
||||
"# first bad commit: \\[\\([a-z0-9]\\{40,\\}\\)\\] [^\n]+\n" nil t)
|
||||
(magit-bind-match-strings (hash) nil
|
||||
(magit-delete-match)
|
||||
(magit-insert-section (bisect-item)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-blame.el --- blame support for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-blame.el --- Blame support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2012-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -42,11 +39,6 @@
|
||||
(defcustom magit-blame-styles
|
||||
'((headings
|
||||
(heading-format . "%-20a %C %s\n"))
|
||||
(margin
|
||||
(margin-format . (" %s%f" " %C %a" " %H"))
|
||||
(margin-width . 42)
|
||||
(margin-face . magit-blame-margin)
|
||||
(margin-body-face . (magit-blame-dimmed)))
|
||||
(highlight
|
||||
(highlight-face . magit-blame-highlight))
|
||||
(lines
|
||||
@@ -54,6 +46,10 @@
|
||||
(show-message . t)))
|
||||
"List of styles used to visualize blame information.
|
||||
|
||||
The style used in the current buffer can be cycled from the blame
|
||||
popup. Blame commands (except `magit-blame-echo') use the first
|
||||
style as the initial style when beginning to blame in a buffer.
|
||||
|
||||
Each entry has the form (IDENT (KEY . VALUE)...). IDENT has
|
||||
to be a symbol uniquely identifying the style. The following
|
||||
KEYs are recognized:
|
||||
@@ -76,7 +72,8 @@ KEYs are recognized:
|
||||
This can also be a list of formats used for the lines at
|
||||
the same positions within the chunk. If the chunk has
|
||||
more lines than formats are specified, then the last is
|
||||
repeated.
|
||||
repeated. WARNING: Adding this key affects performance;
|
||||
see the note at the end of this docstring.
|
||||
`margin-width'
|
||||
Width of the margin, provided `margin-format' is non-nil.
|
||||
`margin-face'
|
||||
@@ -108,9 +105,22 @@ that is displayed in the margin is made at least `margin-width'
|
||||
characters wide, which may be desirable if the used face sets
|
||||
the background color.
|
||||
|
||||
The style used in the current buffer can be cycled from the blame
|
||||
popup. Blame commands (except `magit-blame-echo') use the first
|
||||
style as the initial style when beginning to blame in a buffer."
|
||||
Blame information is displayed using overlays. Such extensive
|
||||
use of overlays is known to slow down even basic operations, such
|
||||
as moving the cursor. To reduce the number of overlays the margin
|
||||
style had to be removed from the default value of this option.
|
||||
|
||||
Note that the margin overlays are created even if another style
|
||||
is currently active. This can only be prevented by not even
|
||||
defining a style that uses the margin. If you want to use this
|
||||
style anyway, you can restore this definition, which used to be
|
||||
part of the default value:
|
||||
|
||||
(margin
|
||||
(margin-format . (\" %s%f\" \" %C %a\" \" %H\"))
|
||||
(margin-width . 42)
|
||||
(margin-face . magit-blame-margin)
|
||||
(margin-body-face . (magit-blame-dimmed)))"
|
||||
:package-version '(magit . "2.13.0")
|
||||
:group 'magit-blame
|
||||
:type 'string)
|
||||
@@ -153,7 +163,7 @@ and then turned on again when turning off the latter."
|
||||
:package-version '(magit . "2.13.0")
|
||||
:group 'magit-blame
|
||||
:type 'hook
|
||||
:get 'magit-hook-custom-get
|
||||
:get #'magit-hook-custom-get
|
||||
:options '(magit-blame-maybe-update-revision-buffer
|
||||
magit-blame-maybe-show-message))
|
||||
|
||||
@@ -213,6 +223,20 @@ Also see option `magit-blame-styles'."
|
||||
"Face used for dates when blaming."
|
||||
:group 'magit-faces)
|
||||
|
||||
;;; Variables
|
||||
|
||||
(defvar-local magit-blame-buffer-read-only nil)
|
||||
(defvar-local magit-blame-cache nil)
|
||||
(defvar-local magit-blame-disabled-modes nil)
|
||||
(defvar-local magit-blame-process nil)
|
||||
(defvar-local magit-blame-recursive-p nil)
|
||||
(defvar-local magit-blame-type nil)
|
||||
(defvar-local magit-blame-separator nil)
|
||||
(defvar-local magit-blame-previous-chunk nil)
|
||||
|
||||
(defvar-local magit-blame--make-margin-overlays nil)
|
||||
(defvar-local magit-blame--style nil)
|
||||
|
||||
;;; Chunks
|
||||
|
||||
(defclass magit-blame-chunk ()
|
||||
@@ -245,7 +269,10 @@ Also see option `magit-blame-styles'."
|
||||
(magit-blame-arguments))
|
||||
"-L" line rev "--" file)
|
||||
(goto-char (point-min))
|
||||
(car (magit-blame--parse-chunk type)))))
|
||||
(if (eobp)
|
||||
(unless noerror
|
||||
(error "Cannot get blame chunk at eob"))
|
||||
(car (magit-blame--parse-chunk type))))))
|
||||
(noerror nil)
|
||||
(t (error "Buffer does not visit a tracked file")))))))
|
||||
|
||||
@@ -272,41 +299,25 @@ in `magit-blame-read-only-mode-map' instead.")
|
||||
|
||||
(defvar magit-blame-read-only-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "C-m") 'magit-show-commit)
|
||||
(define-key map (kbd "p") 'magit-blame-previous-chunk)
|
||||
(define-key map (kbd "P") 'magit-blame-previous-chunk-same-commit)
|
||||
(define-key map (kbd "n") 'magit-blame-next-chunk)
|
||||
(define-key map (kbd "N") 'magit-blame-next-chunk-same-commit)
|
||||
(define-key map (kbd "b") 'magit-blame-addition)
|
||||
(define-key map (kbd "r") 'magit-blame-removal)
|
||||
(define-key map (kbd "f") 'magit-blame-reverse)
|
||||
(define-key map (kbd "B") 'magit-blame)
|
||||
(define-key map (kbd "c") 'magit-blame-cycle-style)
|
||||
(define-key map (kbd "q") 'magit-blame-quit)
|
||||
(define-key map (kbd "M-w") 'magit-blame-copy-hash)
|
||||
(define-key map (kbd "SPC") 'magit-diff-show-or-scroll-up)
|
||||
(define-key map (kbd "S-SPC") 'magit-diff-show-or-scroll-down)
|
||||
(define-key map (kbd "DEL") 'magit-diff-show-or-scroll-down)
|
||||
(define-key map (kbd "C-m") #'magit-show-commit)
|
||||
(define-key map (kbd "p") #'magit-blame-previous-chunk)
|
||||
(define-key map (kbd "P") #'magit-blame-previous-chunk-same-commit)
|
||||
(define-key map (kbd "n") #'magit-blame-next-chunk)
|
||||
(define-key map (kbd "N") #'magit-blame-next-chunk-same-commit)
|
||||
(define-key map (kbd "b") #'magit-blame-addition)
|
||||
(define-key map (kbd "r") #'magit-blame-removal)
|
||||
(define-key map (kbd "f") #'magit-blame-reverse)
|
||||
(define-key map (kbd "B") #'magit-blame)
|
||||
(define-key map (kbd "c") #'magit-blame-cycle-style)
|
||||
(define-key map (kbd "q") #'magit-blame-quit)
|
||||
(define-key map (kbd "M-w") #'magit-blame-copy-hash)
|
||||
(define-key map (kbd "SPC") #'magit-diff-show-or-scroll-up)
|
||||
(define-key map (kbd "S-SPC") #'magit-diff-show-or-scroll-down)
|
||||
(define-key map (kbd "DEL") #'magit-diff-show-or-scroll-down)
|
||||
map)
|
||||
"Keymap for `magit-blame-read-only-mode'.")
|
||||
|
||||
;;; Modes
|
||||
;;;; Variables
|
||||
|
||||
(defvar-local magit-blame-buffer-read-only nil)
|
||||
(defvar-local magit-blame-cache nil)
|
||||
(defvar-local magit-blame-disabled-modes nil)
|
||||
(defvar-local magit-blame-process nil)
|
||||
(defvar-local magit-blame-recursive-p nil)
|
||||
(defvar-local magit-blame-type nil)
|
||||
(defvar-local magit-blame-separator nil)
|
||||
(defvar-local magit-blame-previous-chunk nil)
|
||||
|
||||
(defvar-local magit-blame--style nil)
|
||||
|
||||
(defsubst magit-blame--style-get (key)
|
||||
(cdr (assoc key (cdr magit-blame--style))))
|
||||
|
||||
;;;; Base Mode
|
||||
|
||||
(define-minor-mode magit-blame-mode
|
||||
@@ -318,11 +329,11 @@ in `magit-blame-read-only-mode-map' instead.")
|
||||
(user-error
|
||||
(concat "Don't call `magit-blame-mode' directly; "
|
||||
"instead use `magit-blame'")))
|
||||
(add-hook 'after-save-hook 'magit-blame--refresh t t)
|
||||
(add-hook 'post-command-hook 'magit-blame-goto-chunk-hook t t)
|
||||
(add-hook 'before-revert-hook 'magit-blame--remove-overlays t t)
|
||||
(add-hook 'after-revert-hook 'magit-blame--refresh t t)
|
||||
(add-hook 'read-only-mode-hook 'magit-blame-toggle-read-only t t)
|
||||
(add-hook 'after-save-hook #'magit-blame--refresh t t)
|
||||
(add-hook 'post-command-hook #'magit-blame-goto-chunk-hook t t)
|
||||
(add-hook 'before-revert-hook #'magit-blame--remove-overlays t t)
|
||||
(add-hook 'after-revert-hook #'magit-blame--refresh t t)
|
||||
(add-hook 'read-only-mode-hook #'magit-blame-toggle-read-only t t)
|
||||
(setq magit-blame-buffer-read-only buffer-read-only)
|
||||
(when (or magit-blame-read-only magit-buffer-file-name)
|
||||
(read-only-mode 1))
|
||||
@@ -333,17 +344,21 @@ in `magit-blame-read-only-mode-map' instead.")
|
||||
(setq magit-blame-separator (magit-blame--format-separator))
|
||||
(unless magit-blame--style
|
||||
(setq magit-blame--style (car magit-blame-styles)))
|
||||
(setq magit-blame--make-margin-overlays
|
||||
(and (cl-find-if (lambda (style)
|
||||
(assq 'margin-format (cdr style)))
|
||||
magit-blame-styles)))
|
||||
(magit-blame--update-margin))
|
||||
(t
|
||||
(when (process-live-p magit-blame-process)
|
||||
(kill-process magit-blame-process)
|
||||
(while magit-blame-process
|
||||
(sit-for 0.01))) ; avoid racing the sentinel
|
||||
(remove-hook 'after-save-hook 'magit-blame--refresh t)
|
||||
(remove-hook 'post-command-hook 'magit-blame-goto-chunk-hook t)
|
||||
(remove-hook 'before-revert-hook 'magit-blame--remove-overlays t)
|
||||
(remove-hook 'after-revert-hook 'magit-blame--refresh t)
|
||||
(remove-hook 'read-only-mode-hook 'magit-blame-toggle-read-only t)
|
||||
(remove-hook 'after-save-hook #'magit-blame--refresh t)
|
||||
(remove-hook 'post-command-hook #'magit-blame-goto-chunk-hook t)
|
||||
(remove-hook 'before-revert-hook #'magit-blame--remove-overlays t)
|
||||
(remove-hook 'after-revert-hook #'magit-blame--refresh t)
|
||||
(remove-hook 'read-only-mode-hook #'magit-blame-toggle-read-only t)
|
||||
(unless magit-blame-buffer-read-only
|
||||
(read-only-mode -1))
|
||||
(magit-blame-read-only-mode -1)
|
||||
@@ -411,17 +426,17 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
(list (line-number-at-pos (window-start))
|
||||
(line-number-at-pos (1- (window-end nil t)))))
|
||||
(set-process-sentinel magit-this-process
|
||||
'magit-blame-process-quickstart-sentinel)))
|
||||
#'magit-blame-process-quickstart-sentinel)))
|
||||
|
||||
(defun magit-blame-run-process (revision file args &optional lines)
|
||||
(let ((process (magit-parse-git-async
|
||||
"blame" "--incremental" args
|
||||
(and lines (list "-L" (apply #'format "%s,%s" lines)))
|
||||
revision "--" file)))
|
||||
(set-process-filter process 'magit-blame-process-filter)
|
||||
(set-process-sentinel process 'magit-blame-process-sentinel)
|
||||
(set-process-filter process #'magit-blame-process-filter)
|
||||
(set-process-sentinel process #'magit-blame-process-sentinel)
|
||||
(process-put process 'arguments (list revision file args))
|
||||
(setq magit-blame-cache (make-hash-table :test 'equal))
|
||||
(setq magit-blame-cache (make-hash-table :test #'equal))
|
||||
(setq magit-blame-process process)))
|
||||
|
||||
(defun magit-blame-process-quickstart-sentinel (process event)
|
||||
@@ -476,7 +491,7 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
|
||||
(defun magit-blame--parse-chunk (type)
|
||||
(let (chunk revinfo)
|
||||
(unless (looking-at "^\\(.\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)")
|
||||
(unless (looking-at "^\\(.\\{40,\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)")
|
||||
(error "Blaming failed due to unexpected output: %s"
|
||||
(buffer-substring-no-properties (point) (line-end-position))))
|
||||
(with-slots (orig-rev orig-file prev-rev prev-file)
|
||||
@@ -491,7 +506,7 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
(cond ((looking-at "^filename \\(.+\\)")
|
||||
(setq done t)
|
||||
(setf orig-file (magit-decode-git-path (match-string 1))))
|
||||
((looking-at "^previous \\(.\\{40\\}\\) \\(.+\\)")
|
||||
((looking-at "^previous \\(.\\{40,\\}\\) \\(.+\\)")
|
||||
(setf prev-rev (match-string 1))
|
||||
(setf prev-file (magit-decode-git-path (match-string 2))))
|
||||
((looking-at "^\\([^ ]+\\) \\(.+\\)")
|
||||
@@ -520,25 +535,42 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
|
||||
;;; Display
|
||||
|
||||
(defsubst magit-blame--style-get (key)
|
||||
(cdr (assoc key (cdr magit-blame--style))))
|
||||
|
||||
(defun magit-blame--make-overlays (buf chunk revinfo)
|
||||
(with-current-buffer buf
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- (oref chunk final-line)))
|
||||
(let ((beg (point))
|
||||
(end (save-excursion
|
||||
(forward-line (oref chunk num-lines))
|
||||
(point))))
|
||||
(let* ((line (oref chunk final-line))
|
||||
(beg (magit-blame--line-beginning-position line))
|
||||
(end (magit-blame--line-beginning-position
|
||||
(+ line (oref chunk num-lines))))
|
||||
(before (magit-blame-chunk-at (1- beg))))
|
||||
(when (and before
|
||||
(equal (oref before orig-rev)
|
||||
(oref chunk orig-rev)))
|
||||
(setq beg (magit-blame--line-beginning-position
|
||||
(oset chunk final-line (oref before final-line))))
|
||||
(cl-incf (oref chunk num-lines)
|
||||
(oref before num-lines)))
|
||||
(magit-blame--remove-overlays beg end)
|
||||
(magit-blame--make-margin-overlays chunk revinfo beg end)
|
||||
(when magit-blame--make-margin-overlays
|
||||
(magit-blame--make-margin-overlays chunk revinfo beg end))
|
||||
(magit-blame--make-heading-overlay chunk revinfo beg end)
|
||||
(magit-blame--make-highlight-overlay chunk beg))))))
|
||||
(magit-blame--make-highlight-overlay chunk beg))))))
|
||||
|
||||
(defun magit-blame--make-margin-overlays (chunk revinfo _beg end)
|
||||
(defun magit-blame--line-beginning-position (line)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- line))
|
||||
(point)))
|
||||
|
||||
(defun magit-blame--make-margin-overlays (chunk revinfo beg end)
|
||||
(save-excursion
|
||||
(let ((line 0))
|
||||
(goto-char beg)
|
||||
(while (< (point) end)
|
||||
(magit-blame--make-margin-overlay chunk revinfo line)
|
||||
(forward-line)
|
||||
@@ -563,7 +595,9 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
(magit-blame--update-heading-overlay ov)))
|
||||
|
||||
(defun magit-blame--make-highlight-overlay (chunk beg)
|
||||
(let ((ov (make-overlay beg (1+ (line-end-position)))))
|
||||
(let ((ov (make-overlay beg (save-excursion
|
||||
(goto-char beg)
|
||||
(1+ (line-end-position))))))
|
||||
(overlay-put ov 'magit-blame-chunk chunk)
|
||||
(overlay-put ov 'magit-blame-highlight t)
|
||||
(magit-blame--update-highlight-overlay ov)))
|
||||
@@ -638,7 +672,7 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
|
||||
(defun magit-blame--format-string-1 (rev revinfo format face)
|
||||
(let ((str
|
||||
(if (equal rev "0000000000000000000000000000000000000000")
|
||||
(if (string-match-p "\\`0\\{40,\\}\\'" rev)
|
||||
(propertize (concat (if (string-prefix-p "\s" format) "\s" "")
|
||||
"Not Yet Committed"
|
||||
(if (string-suffix-p "\n" format) "\n" ""))
|
||||
@@ -646,19 +680,19 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
(magit--format-spec
|
||||
(propertize format 'font-lock-face face)
|
||||
(cl-flet* ((p0 (s f)
|
||||
(propertize s 'font-lock-face
|
||||
(if face
|
||||
(if (listp face)
|
||||
face
|
||||
(list f face))
|
||||
f)))
|
||||
(propertize s 'font-lock-face
|
||||
(if face
|
||||
(if (listp face)
|
||||
face
|
||||
(list f face))
|
||||
f)))
|
||||
(p1 (k f)
|
||||
(p0 (cdr (assoc k revinfo)) f))
|
||||
(p0 (cdr (assoc k revinfo)) f))
|
||||
(p2 (k1 k2 f)
|
||||
(p0 (magit-blame--format-time-string
|
||||
(cdr (assoc k1 revinfo))
|
||||
(cdr (assoc k2 revinfo)))
|
||||
f)))
|
||||
(p0 (magit-blame--format-time-string
|
||||
(cdr (assoc k1 revinfo))
|
||||
(cdr (assoc k2 revinfo)))
|
||||
f)))
|
||||
`((?H . ,(p0 rev 'magit-blame-hash))
|
||||
(?s . ,(p1 "summary" 'magit-blame-summary))
|
||||
(?a . ,(p1 "author" 'magit-blame-name))
|
||||
@@ -685,7 +719,7 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
(defun magit-blame--format-time-string (time tz)
|
||||
(let* ((time-format (or (magit-blame--style-get 'time-format)
|
||||
magit-blame-time-format))
|
||||
(tz-in-second (and (string-match "%z" time-format)
|
||||
(tz-in-second (and (string-search "%z" time-format)
|
||||
(car (last (parse-time-string tz))))))
|
||||
(format-time-string time-format
|
||||
(seconds-to-time (string-to-number time))
|
||||
@@ -850,8 +884,8 @@ then also kill the buffer."
|
||||
(not (= pos (if previous (point-min) (point-max))))
|
||||
(setq pos (funcall
|
||||
(if previous
|
||||
'previous-single-char-property-change
|
||||
'next-single-char-property-change)
|
||||
#'previous-single-char-property-change
|
||||
#'next-single-char-property-change)
|
||||
pos 'magit-blame-chunk)))
|
||||
(--when-let (magit-blame--overlay-at pos)
|
||||
(when (equal (oref (magit-blame-chunk-at pos) orig-rev) rev)
|
||||
@@ -864,7 +898,7 @@ then also kill the buffer."
|
||||
(defun magit-blame-previous-chunk-same-commit ()
|
||||
"Move to the previous chunk from the same commit."
|
||||
(interactive)
|
||||
(magit-blame-next-chunk-same-commit 'previous-single-char-property-change))
|
||||
(magit-blame-next-chunk-same-commit #'previous-single-char-property-change))
|
||||
|
||||
(defun magit-blame-cycle-style ()
|
||||
"Change how blame information is visualized.
|
||||
@@ -918,21 +952,21 @@ instead of the hash, like `kill-ring-save' would."
|
||||
:class 'transient-option
|
||||
:argument "-M"
|
||||
:allow-empty t
|
||||
:reader 'transient-read-number-N+)
|
||||
:reader #'transient-read-number-N+)
|
||||
|
||||
(transient-define-argument magit-blame:-C ()
|
||||
:description "Detect lines moved or copied between files"
|
||||
:class 'transient-option
|
||||
:argument "-C"
|
||||
:allow-empty t
|
||||
:reader 'transient-read-number-N+)
|
||||
:reader #'transient-read-number-N+)
|
||||
|
||||
;;; Utilities
|
||||
|
||||
(defun magit-blame-maybe-update-revision-buffer ()
|
||||
(when-let ((chunk (magit-current-blame-chunk))
|
||||
(commit (oref chunk orig-rev))
|
||||
(buffer (magit-get-mode-buffer 'magit-revision-mode nil t)))
|
||||
(when-let* ((chunk (magit-current-blame-chunk))
|
||||
(commit (oref chunk orig-rev))
|
||||
(buffer (magit-get-mode-buffer 'magit-revision-mode nil t)))
|
||||
(if magit--update-revision-buffer
|
||||
(setq magit--update-revision-buffer (list commit buffer))
|
||||
(setq magit--update-revision-buffer (list commit buffer))
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
;;; magit-bookmark.el --- bookmark support for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-bookmark.el --- Bookmark support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Inspired by an earlier implementation by Yuri Khan.
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; Inspired by an earlier implementation by Yuri Khan.
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -23,7 +20,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -32,81 +29,6 @@
|
||||
;;; Code:
|
||||
|
||||
(require 'magit)
|
||||
(require 'bookmark)
|
||||
|
||||
;;; Core
|
||||
|
||||
(defun magit--make-bookmark ()
|
||||
"Create a bookmark for the current Magit buffer.
|
||||
Input values are the major-mode's `magit-bookmark-name' method,
|
||||
and the buffer-local values of the variables referenced in its
|
||||
`magit-bookmark-variables' property."
|
||||
(if (plist-member (symbol-plist major-mode) 'magit-bookmark-variables)
|
||||
;; `bookmark-make-record-default's return value does not match
|
||||
;; (NAME . ALIST), even though it is used as the default value
|
||||
;; of `bookmark-make-record-function', which states that such
|
||||
;; functions must do that. See #4356.
|
||||
(let ((bookmark (cons nil (bookmark-make-record-default 'no-file))))
|
||||
(bookmark-prop-set bookmark 'handler 'magit--handle-bookmark)
|
||||
(bookmark-prop-set bookmark 'mode major-mode)
|
||||
(bookmark-prop-set bookmark 'filename (magit-toplevel))
|
||||
(bookmark-prop-set bookmark 'defaults (list (magit-bookmark-name)))
|
||||
(dolist (var (get major-mode 'magit-bookmark-variables))
|
||||
(bookmark-prop-set bookmark var (symbol-value var)))
|
||||
(bookmark-prop-set
|
||||
bookmark 'magit-hidden-sections
|
||||
(--keep (and (oref it hidden)
|
||||
(cons (oref it type)
|
||||
(if (derived-mode-p 'magit-stash-mode)
|
||||
(replace-regexp-in-string
|
||||
(regexp-quote magit-buffer-revision)
|
||||
magit-buffer-revision-hash
|
||||
(oref it value))
|
||||
(oref it value))))
|
||||
(oref magit-root-section children)))
|
||||
bookmark)
|
||||
(user-error "Bookmarking is not implemented for %s buffers" major-mode)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit--handle-bookmark (bookmark)
|
||||
"Open a bookmark created by `magit--make-bookmark'.
|
||||
Call the `magit-*-setup-buffer' function of the the major-mode
|
||||
with the variables' values as arguments, which were recorded by
|
||||
`magit--make-bookmark'. Ignore `magit-display-buffer-function'."
|
||||
(let ((buffer (let ((default-directory (bookmark-get-filename bookmark))
|
||||
(mode (bookmark-prop-get bookmark 'mode))
|
||||
(magit-display-buffer-function #'identity)
|
||||
(magit-display-buffer-noselect t))
|
||||
(apply (intern (format "%s-setup-buffer"
|
||||
(substring (symbol-name mode) 0 -5)))
|
||||
(--map (bookmark-prop-get bookmark it)
|
||||
(get mode 'magit-bookmark-variables))))))
|
||||
(set-buffer buffer) ; That is the interface we have to adhere to.
|
||||
(when-let ((hidden (bookmark-prop-get bookmark 'magit-hidden-sections)))
|
||||
(with-current-buffer buffer
|
||||
(dolist (child (oref magit-root-section children))
|
||||
(if (member (cons (oref child type)
|
||||
(oref child value))
|
||||
hidden)
|
||||
(magit-section-hide child)
|
||||
(magit-section-show child)))))
|
||||
;; Compatibility with `bookmark+' package. See #4356.
|
||||
(when (bound-and-true-p bmkp-jump-display-function)
|
||||
(funcall bmkp-jump-display-function (current-buffer)))
|
||||
nil))
|
||||
|
||||
(cl-defgeneric magit-bookmark-name ()
|
||||
"Return name for bookmark to current buffer."
|
||||
(format "%s%s"
|
||||
(substring (symbol-name major-mode) 0 -5)
|
||||
(if-let ((vars (get major-mode 'magit-bookmark-variables)))
|
||||
(cl-mapcan (lambda (var)
|
||||
(let ((val (symbol-value var)))
|
||||
(if (and val (atom val))
|
||||
(list val)
|
||||
val)))
|
||||
vars)
|
||||
"")))
|
||||
|
||||
;;; Diff
|
||||
;;;; Diff
|
||||
@@ -120,10 +42,10 @@ with the variables' values as arguments, which were recorded by
|
||||
(cl-defmethod magit-bookmark-name (&context (major-mode magit-diff-mode))
|
||||
(format "magit-diff(%s%s)"
|
||||
(pcase (magit-diff-type)
|
||||
(`staged "staged")
|
||||
(`unstaged "unstaged")
|
||||
(`committed magit-buffer-range)
|
||||
(`undefined
|
||||
('staged "staged")
|
||||
('unstaged "unstaged")
|
||||
('committed magit-buffer-range)
|
||||
('undefined
|
||||
(delq nil (list magit-buffer-typearg magit-buffer-range-hashed))))
|
||||
(if magit-buffer-diff-files
|
||||
(concat " -- " (mapconcat #'identity magit-buffer-diff-files " "))
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-branch.el --- branch support -*- lexical-binding: t -*-
|
||||
;;; magit-branch.el --- Branch support -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -554,7 +551,7 @@ defaulting to the branch at point."
|
||||
(interactive
|
||||
(let ((branches (magit-region-values 'branch t))
|
||||
(force current-prefix-arg))
|
||||
(if (> (length branches) 1)
|
||||
(if (length> branches 1)
|
||||
(magit-confirm t nil "Delete %i branches" nil branches)
|
||||
(setq branches
|
||||
(list (magit-read-branch-prefer-other
|
||||
@@ -605,22 +602,22 @@ defaulting to the branch at point."
|
||||
;; If that is not the case, then this deletes the tracking branches.
|
||||
(set-process-sentinel
|
||||
magit-this-process
|
||||
(apply-partially 'magit-delete-remote-branch-sentinel remote refs)))
|
||||
(apply-partially #'magit-delete-remote-branch-sentinel remote refs)))
|
||||
(t
|
||||
(dolist (ref refs)
|
||||
(message "Delete %s (was %s)" ref
|
||||
(magit-rev-parse "--short" ref))
|
||||
(magit-call-git "update-ref" "-d" ref))
|
||||
(magit-refresh)))))
|
||||
((> (length branches) 1)
|
||||
((length> branches 1)
|
||||
(setq branches (delete (magit-get-current-branch) branches))
|
||||
(mapc 'magit-branch-maybe-delete-pr-remote branches)
|
||||
(mapc 'magit-branch-unset-pushRemote branches)
|
||||
(mapc #'magit-branch-maybe-delete-pr-remote branches)
|
||||
(mapc #'magit-branch-unset-pushRemote branches)
|
||||
(magit-run-git "branch" (if force "-D" "-d") branches))
|
||||
(t ; And now for something completely different.
|
||||
(let* ((branch (car branches))
|
||||
(prompt (format "Branch %s is checked out. " branch))
|
||||
(target (magit-get-upstream-branch)))
|
||||
(target (magit-get-indirect-upstream-branch branch t)))
|
||||
(when (equal branch (magit-get-current-branch))
|
||||
(when (or (equal branch target)
|
||||
(not target))
|
||||
@@ -673,7 +670,7 @@ defaulting to the branch at point."
|
||||
(format "+refs/heads/%s:refs/remotes/%s/%s"
|
||||
merge remote merge))))))
|
||||
(when (member refspec refspecs)
|
||||
(if (and (= (length refspecs) 1)
|
||||
(if (and (length= refspecs 1)
|
||||
(magit-confirm 'delete-pr-remote
|
||||
(format "Also delete remote %s (%s)" remote
|
||||
"no pull-request branch remains")
|
||||
@@ -847,7 +844,7 @@ and also rename the respective reflog file."
|
||||
(interactive (list (oref transient-current-prefix scope)))
|
||||
(magit-run-git-with-editor "branch" "--edit-description" branch))
|
||||
|
||||
(add-hook 'find-file-hook 'magit-branch-description-check-buffers)
|
||||
(add-hook 'find-file-hook #'magit-branch-description-check-buffers)
|
||||
|
||||
(defun magit-branch-description-check-buffers ()
|
||||
(and buffer-file-name
|
||||
@@ -860,9 +857,9 @@ and also rename the respective reflog file."
|
||||
:class 'magit--git-branch:upstream)
|
||||
|
||||
(cl-defmethod transient-init-value ((obj magit--git-branch:upstream))
|
||||
(when-let ((branch (oref transient--prefix scope))
|
||||
(remote (magit-get "branch" branch "remote"))
|
||||
(merge (magit-get "branch" branch "merge")))
|
||||
(when-let* ((branch (oref transient--prefix scope))
|
||||
(remote (magit-get "branch" branch "remote"))
|
||||
(merge (magit-get "branch" branch "merge")))
|
||||
(oset obj value (list remote merge))))
|
||||
|
||||
(cl-defmethod transient-infix-read ((obj magit--git-branch:upstream))
|
||||
@@ -873,10 +870,10 @@ and also rename the respective reflog file."
|
||||
(cl-defmethod transient-infix-set ((obj magit--git-branch:upstream) refname)
|
||||
(magit-set-upstream-branch (oref transient--prefix scope) refname)
|
||||
(oset obj value
|
||||
(let ((branch (oref transient--prefix scope)))
|
||||
(when-let ((r (magit-get "branch" branch "remote"))
|
||||
(m (magit-get "branch" branch "merge")))
|
||||
(list r m))))
|
||||
(and-let* ((branch (oref transient--prefix scope))
|
||||
(r (magit-get "branch" branch "remote"))
|
||||
(m (magit-get "branch" branch "merge")))
|
||||
(list r m)))
|
||||
(magit-refresh))
|
||||
|
||||
(cl-defmethod transient-format ((obj magit--git-branch:upstream))
|
||||
@@ -896,7 +893,7 @@ and also rename the respective reflog file."
|
||||
|
||||
(transient-define-infix magit-branch.<branch>.rebase ()
|
||||
:class 'magit--git-variable:choices
|
||||
:scope 'magit--read-branch-scope
|
||||
:scope #'magit--read-branch-scope
|
||||
:variable "branch.%s.rebase"
|
||||
:fallback "pull.rebase"
|
||||
:choices '("true" "false")
|
||||
@@ -904,10 +901,10 @@ and also rename the respective reflog file."
|
||||
|
||||
(transient-define-infix magit-branch.<branch>.pushRemote ()
|
||||
:class 'magit--git-variable:choices
|
||||
:scope 'magit--read-branch-scope
|
||||
:scope #'magit--read-branch-scope
|
||||
:variable "branch.%s.pushRemote"
|
||||
:fallback "remote.pushDefault"
|
||||
:choices 'magit-list-remotes)
|
||||
:choices #'magit-list-remotes)
|
||||
|
||||
(transient-define-infix magit-pull.rebase ()
|
||||
:class 'magit--git-variable:choices
|
||||
@@ -918,7 +915,7 @@ and also rename the respective reflog file."
|
||||
(transient-define-infix magit-remote.pushDefault ()
|
||||
:class 'magit--git-variable:choices
|
||||
:variable "remote.pushDefault"
|
||||
:choices 'magit-list-remotes)
|
||||
:choices #'magit-list-remotes)
|
||||
|
||||
(transient-define-infix magit-branch.autoSetupMerge ()
|
||||
:class 'magit--git-variable:choices
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-bundle.el --- bundle support for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-bundle.el --- Bundle support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2011-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-clone.el --- clone a repository -*- lexical-binding: t -*-
|
||||
;;; magit-clone.el --- Clone a repository -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -72,7 +69,8 @@ directly."
|
||||
|
||||
(defcustom magit-clone-name-alist
|
||||
'(("\\`\\(?:github:\\|gh:\\)?\\([^:]+\\)\\'" "github.com" "github.user")
|
||||
("\\`\\(?:gitlab:\\|gl:\\)\\([^:]+\\)\\'" "gitlab.com" "gitlab.user"))
|
||||
("\\`\\(?:gitlab:\\|gl:\\)\\([^:]+\\)\\'" "gitlab.com" "gitlab.user")
|
||||
("\\`\\(?:sourcehut:\\|sh:\\)\\([^:]+\\)\\'" "git.sr.ht" "sourcehut.user"))
|
||||
"Alist mapping repository names to repository urls.
|
||||
|
||||
Each element has the form (REGEXP HOSTNAME USER). When the user
|
||||
@@ -89,19 +87,30 @@ default user specified in the matched entry is used.
|
||||
If USER contains a dot, then it is treated as a Git variable and
|
||||
the value of that is used as the username. Otherwise it is used
|
||||
as the username itself."
|
||||
:package-version '(magit . "3.0.0")
|
||||
:package-version '(magit . "3.4.0")
|
||||
:group 'magit-commands
|
||||
:type '(repeat (list regexp
|
||||
(string :tag "hostname")
|
||||
(string :tag "user name or git variable"))))
|
||||
(string :tag "Hostname")
|
||||
(string :tag "User name or git variable"))))
|
||||
|
||||
(defcustom magit-clone-url-format "git@%h:%n.git"
|
||||
"Format used when turning repository names into urls.
|
||||
%h is the hostname and %n is the repository name, including
|
||||
the name of the owner. Also see `magit-clone-name-alist'."
|
||||
:package-version '(magit . "3.0.0")
|
||||
(defcustom magit-clone-url-format
|
||||
'(("git.sr.ht" . "git@%h:%n")
|
||||
(t . "git@%h:%n.git"))
|
||||
"Format(s) used when turning repository names into urls.
|
||||
|
||||
In a format string, %h is the hostname and %n is the repository
|
||||
name, including the name of the owner.
|
||||
|
||||
The value can be a string (representing a single static format)
|
||||
or an alist with elements (HOSTNAME . FORMAT) mapping hostnames
|
||||
to formats. When an alist is used, the t key represents the
|
||||
default. Also see `magit-clone-name-alist'."
|
||||
:package-version '(magit . "3.4.0")
|
||||
:group 'magit-commands
|
||||
:type 'regexp)
|
||||
:type '(choice (string :tag "Format")
|
||||
(alist :key-type (choice (string :tag "Host")
|
||||
(const :tag "Default" t))
|
||||
:value-type (string :tag "Format"))))
|
||||
|
||||
;;; Commands
|
||||
|
||||
@@ -139,7 +148,7 @@ the name of the owner. Also see `magit-clone-name-alist'."
|
||||
("m" "mirror" magit-clone-mirror)]
|
||||
(interactive (list (or magit-clone-always-transient current-prefix-arg)))
|
||||
(if transient
|
||||
(transient-setup #'magit-clone)
|
||||
(transient-setup 'magit-clone)
|
||||
(call-interactively #'magit-clone-regular)))
|
||||
|
||||
(transient-define-argument magit-clone:--filter ()
|
||||
@@ -147,7 +156,7 @@ the name of the owner. Also see `magit-clone-name-alist'."
|
||||
:class 'transient-option
|
||||
:key "-f"
|
||||
:argument "--filter="
|
||||
:reader 'magit-clone-read-filter)
|
||||
:reader #'magit-clone-read-filter)
|
||||
|
||||
(defun magit-clone-read-filter (prompt initial-input history)
|
||||
(magit-completing-read prompt
|
||||
@@ -233,7 +242,7 @@ Then show the status buffer for the new repository."
|
||||
(setq directory (file-name-as-directory (expand-file-name directory)))
|
||||
(when (file-exists-p directory)
|
||||
(if (file-directory-p directory)
|
||||
(when (> (length (directory-files directory)) 2)
|
||||
(when (length> (directory-files directory) 2)
|
||||
(let ((name (magit-clone--url-to-name repository)))
|
||||
(unless (and name
|
||||
(setq directory (file-name-as-directory
|
||||
@@ -314,16 +323,24 @@ Then show the status buffer for the new repository."
|
||||
'magit-clone-name-alist)))
|
||||
|
||||
(defun magit-clone--format-url (host user repo)
|
||||
(format-spec
|
||||
magit-clone-url-format
|
||||
`((?h . ,host)
|
||||
(?n . ,(if (string-match-p "/" repo)
|
||||
repo
|
||||
(if (string-match-p "\\." user)
|
||||
(if-let ((user (magit-get user)))
|
||||
(concat user "/" repo)
|
||||
(user-error "Set %S or specify owner explicitly" user))
|
||||
(concat user "/" repo)))))))
|
||||
(if-let ((url-format
|
||||
(cond ((listp magit-clone-url-format)
|
||||
(cdr (or (assoc host magit-clone-url-format)
|
||||
(assoc t magit-clone-url-format))))
|
||||
((stringp magit-clone-url-format)
|
||||
magit-clone-url-format))))
|
||||
(format-spec
|
||||
url-format
|
||||
`((?h . ,host)
|
||||
(?n . ,(if (string-search "/" repo)
|
||||
repo
|
||||
(if (string-search "." user)
|
||||
(if-let ((user (magit-get user)))
|
||||
(concat user "/" repo)
|
||||
(user-error "Set %S or specify owner explicitly" user))
|
||||
(concat user "/" repo))))))
|
||||
(user-error
|
||||
"Bogus `magit-clone-url-format' (bad type or missing default)")))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-clone)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-commit.el --- create Git commits -*- lexical-binding: t -*-
|
||||
;;; magit-commit.el --- Create Git commits -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -34,9 +31,6 @@
|
||||
(require 'magit)
|
||||
(require 'magit-sequence)
|
||||
|
||||
(eval-when-compile (require 'epa)) ; for `epa-protocol'
|
||||
(eval-when-compile (require 'epg))
|
||||
|
||||
;;; Options
|
||||
|
||||
(defcustom magit-commit-ask-to-stage 'verbose
|
||||
@@ -81,7 +75,7 @@ an error while using those is harder to recover from."
|
||||
"Hook run after creating a commit without the user editing a message.
|
||||
|
||||
This hook is run by `magit-refresh' if `this-command' is a member
|
||||
of `magit-post-stage-hook-commands'. This only includes commands
|
||||
of `magit-post-commit-hook-commands'. This only includes commands
|
||||
named `magit-commit-*' that do *not* require that the user edits
|
||||
the commit message in a buffer and then finishes by pressing
|
||||
\\<with-editor-mode-map>\\[with-editor-finish].
|
||||
@@ -119,13 +113,6 @@ Also see https://github.com/magit/magit/issues/4132."
|
||||
:group 'magit-commands
|
||||
:type 'boolean)
|
||||
|
||||
(defvar magit-post-commit-hook-commands
|
||||
'(magit-commit-extend
|
||||
magit-commit-fixup
|
||||
magit-commit-augment
|
||||
magit-commit-instant-fixup
|
||||
magit-commit-instant-squash))
|
||||
|
||||
;;; Popup
|
||||
|
||||
;;;###autoload (autoload 'magit-commit "magit-commit" nil t)
|
||||
@@ -168,58 +155,12 @@ Also see https://github.com/magit/magit/issues/4132."
|
||||
(defun magit-commit-arguments nil
|
||||
(transient-args 'magit-commit))
|
||||
|
||||
(transient-define-argument magit:--gpg-sign ()
|
||||
:description "Sign using gpg"
|
||||
:class 'transient-option
|
||||
:shortarg "-S"
|
||||
:argument "--gpg-sign="
|
||||
:allow-empty t
|
||||
:reader 'magit-read-gpg-signing-key)
|
||||
|
||||
(defvar magit-gpg-secret-key-hist nil)
|
||||
|
||||
(defun magit-read-gpg-secret-key
|
||||
(prompt &optional initial-input history predicate)
|
||||
(require 'epa)
|
||||
(let* ((keys (cl-mapcan
|
||||
(lambda (cert)
|
||||
(and (or (not predicate)
|
||||
(funcall predicate cert))
|
||||
(let* ((key (car (epg-key-sub-key-list cert)))
|
||||
(fpr (epg-sub-key-fingerprint key))
|
||||
(id (epg-sub-key-id key))
|
||||
(author
|
||||
(when-let ((id-obj
|
||||
(car (epg-key-user-id-list cert))))
|
||||
(let ((id-str (epg-user-id-string id-obj)))
|
||||
(if (stringp id-str)
|
||||
id-str
|
||||
(epg-decode-dn id-obj))))))
|
||||
(list
|
||||
(propertize fpr 'display
|
||||
(concat (substring fpr 0 (- (length id)))
|
||||
(propertize id 'face 'highlight)
|
||||
" " author))))))
|
||||
(epg-list-keys (epg-make-context epa-protocol) nil t)))
|
||||
(choice (completing-read prompt keys nil nil nil
|
||||
history nil initial-input)))
|
||||
(set-text-properties 0 (length choice) nil choice)
|
||||
choice))
|
||||
|
||||
(defun magit-read-gpg-signing-key (prompt &optional initial-input history)
|
||||
(magit-read-gpg-secret-key
|
||||
prompt initial-input history
|
||||
(lambda (cert)
|
||||
(cl-some (lambda (key)
|
||||
(memq 'sign (epg-sub-key-capability key)))
|
||||
(epg-key-sub-key-list cert)))))
|
||||
|
||||
(transient-define-argument magit-commit:--reuse-message ()
|
||||
:description "Reuse commit message"
|
||||
:class 'transient-option
|
||||
:shortarg "-C"
|
||||
:argument "--reuse-message="
|
||||
:reader 'magit-read-reuse-message
|
||||
:reader #'magit-read-reuse-message
|
||||
:history-key 'magit-revision-history)
|
||||
|
||||
(defun magit-read-reuse-message (prompt &optional default history)
|
||||
@@ -240,7 +181,7 @@ With a prefix argument, amend to the commit at `HEAD' instead.
|
||||
(list (cons "--amend" (magit-commit-arguments)))
|
||||
(list (magit-commit-arguments))))
|
||||
(when (member "--all" args)
|
||||
(setq this-command 'magit-commit-all))
|
||||
(setq this-command 'magit-commit--all))
|
||||
(when (setq args (magit-commit-assert args))
|
||||
(let ((default-directory (magit-toplevel)))
|
||||
(magit-run-git-with-editor "commit" args))))
|
||||
@@ -267,10 +208,11 @@ to inverse the meaning of the prefix argument. \n(git commit
|
||||
magit-commit-extend-override-date)))
|
||||
(when (setq args (magit-commit-assert args))
|
||||
(magit-commit-amend-assert)
|
||||
(let ((process-environment process-environment))
|
||||
(unless override-date
|
||||
(push (magit-rev-format "GIT_COMMITTER_DATE=%cD") process-environment))
|
||||
(magit-run-git-with-editor "commit" "--amend" "--no-edit" args))))
|
||||
(if override-date
|
||||
(magit-run-git-with-editor "commit" "--amend" "--no-edit" args)
|
||||
(with-environment-variables
|
||||
(("GIT_COMMITTER_DATE" (magit-rev-format "%cD")))
|
||||
(magit-run-git-with-editor "commit" "--amend" "--no-edit" args)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-commit-reword (&optional args override-date)
|
||||
@@ -288,11 +230,12 @@ and ignore the option.
|
||||
(not magit-commit-reword-override-date)
|
||||
magit-commit-reword-override-date)))
|
||||
(magit-commit-amend-assert)
|
||||
(let ((process-environment process-environment))
|
||||
(unless override-date
|
||||
(push (magit-rev-format "GIT_COMMITTER_DATE=%cD") process-environment))
|
||||
(cl-pushnew "--allow-empty" args :test #'equal)
|
||||
(magit-run-git-with-editor "commit" "--amend" "--only" args)))
|
||||
(cl-pushnew "--allow-empty" args :test #'equal)
|
||||
(if override-date
|
||||
(magit-run-git-with-editor "commit" "--amend" "--only" args)
|
||||
(with-environment-variables
|
||||
(("GIT_COMMITTER_DATE" (magit-rev-format "%cD")))
|
||||
(magit-run-git-with-editor "commit" "--amend" "--only" args))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-commit-fixup (&optional commit args)
|
||||
@@ -370,22 +313,26 @@ depending on the value of option `magit-commit-squash-confirm'."
|
||||
(magit-call-git
|
||||
"commit" "--no-gpg-sign"
|
||||
(-remove-first
|
||||
(apply-partially #'string-match-p "\\`--gpg-sign=")
|
||||
(apply-partially #'string-prefix-p "--gpg-sign=")
|
||||
args)))
|
||||
(magit-run-git-with-editor "commit" args))
|
||||
t) ; The commit was created; used by below lambda.
|
||||
(magit-log-select
|
||||
(lambda (commit)
|
||||
(when (and (magit-commit-squash-internal option commit args
|
||||
rebase edit t)
|
||||
rebase)
|
||||
(magit-commit-amend-assert commit)
|
||||
(magit-rebase-interactive-1 commit
|
||||
(list "--autosquash" "--autostash" "--keep-empty")
|
||||
"" "true" nil t)))
|
||||
(format "Type %%p on a commit to %s into it,"
|
||||
(substring option 2))
|
||||
nil nil nil commit)
|
||||
(let ((winconf (and magit-commit-show-diff
|
||||
(current-window-configuration))))
|
||||
(magit-log-select
|
||||
(lambda (commit)
|
||||
(when (and (magit-commit-squash-internal option commit args
|
||||
rebase edit t)
|
||||
rebase)
|
||||
(magit-commit-amend-assert commit)
|
||||
(magit-rebase-interactive-1 commit
|
||||
(list "--autosquash" "--autostash" "--keep-empty")
|
||||
"" "true" nil t))
|
||||
(when winconf
|
||||
(set-window-configuration winconf)))
|
||||
(format "Type %%p on a commit to %s into it,"
|
||||
(substring option 2))
|
||||
nil nil nil commit))
|
||||
(when magit-commit-show-diff
|
||||
(let ((magit-display-buffer-noselect t))
|
||||
(apply #'magit-diff-staged nil (magit-diff-arguments)))))))
|
||||
@@ -417,7 +364,7 @@ depending on the value of option `magit-commit-squash-confirm'."
|
||||
((and (magit-rebase-in-progress-p)
|
||||
(not (magit-anything-unstaged-p))
|
||||
(y-or-n-p "Nothing staged. Continue in-progress rebase? "))
|
||||
(setq this-command 'magit-rebase-continue)
|
||||
(setq this-command #'magit-rebase-continue)
|
||||
(magit-run-git-sequencer "rebase" "--continue")
|
||||
nil)
|
||||
((and (file-exists-p (magit-git-dir "MERGE_MSG"))
|
||||
@@ -429,9 +376,10 @@ depending on the value of option `magit-commit-squash-confirm'."
|
||||
(when (eq magit-commit-ask-to-stage 'verbose)
|
||||
(magit-diff-unstaged))
|
||||
(prog1 (when (or (eq magit-commit-ask-to-stage 'stage)
|
||||
(y-or-n-p "Nothing staged. Stage and commit all unstaged changes? "))
|
||||
(magit-run-git "add" "-u" ".")
|
||||
(or args (list "--")))
|
||||
(y-or-n-p
|
||||
"Nothing staged. Commit all uncommitted changes? "))
|
||||
(setq this-command 'magit-commit--all)
|
||||
(cons "--all" (or args (list "--"))))
|
||||
(when (and (eq magit-commit-ask-to-stage 'verbose)
|
||||
(derived-mode-p 'magit-diff-mode))
|
||||
(magit-mode-bury-buffer))))
|
||||
@@ -467,8 +415,7 @@ is updated:
|
||||
'magit--reshelve-history)
|
||||
update-author
|
||||
(magit-commit-arguments))))
|
||||
(let ((process-environment process-environment))
|
||||
(push (concat "GIT_COMMITTER_DATE=" date) process-environment)
|
||||
(with-environment-variables (("GIT_COMMITTER_DATE" date))
|
||||
(magit-run-git "commit" "--amend" "--no-edit"
|
||||
(and update-author (concat "--date=" date))
|
||||
args)))
|
||||
@@ -516,7 +463,7 @@ See `magit-commit-autofixup' for an alternative implementation."
|
||||
(transient-args 'magit-commit-absorb))))
|
||||
(if (eq phase 'transient)
|
||||
(transient-setup 'magit-commit-absorb)
|
||||
(unless (executable-find "git-absorb")
|
||||
(unless (magit-git-executable-find "git-absorb")
|
||||
(user-error "This command requires the git-absorb executable, which %s"
|
||||
"is available from https://github.com/tummychow/git-absorb"))
|
||||
(unless (magit-anything-staged-p)
|
||||
@@ -559,7 +506,7 @@ See `magit-commit-absorb' for an alternative implementation."
|
||||
(transient-args 'magit-commit-autofixup))))
|
||||
(if (eq phase 'transient)
|
||||
(transient-setup 'magit-commit-autofixup)
|
||||
(unless (executable-find "git-autofixup")
|
||||
(unless (magit-git-executable-find "git-autofixup")
|
||||
(user-error "This command requires the git-autofixup script, which %s"
|
||||
"is available from https://github.com/torbiak/git-autofixup"))
|
||||
(unless (magit-anything-modified-p)
|
||||
@@ -579,56 +526,108 @@ See `magit-commit-absorb' for an alternative implementation."
|
||||
:class 'transient-option
|
||||
:shortarg "-c"
|
||||
:argument "--context="
|
||||
:reader 'transient-read-number-N0)
|
||||
:reader #'transient-read-number-N0)
|
||||
|
||||
(transient-define-argument magit-autofixup:--strict ()
|
||||
:description "Strictness"
|
||||
:class 'transient-option
|
||||
:shortarg "-s"
|
||||
:argument "--strict="
|
||||
:reader 'transient-read-number-N0)
|
||||
:reader #'transient-read-number-N0)
|
||||
|
||||
(defvar magit-post-commit-hook-commands
|
||||
'(magit-commit-extend
|
||||
magit-commit-fixup
|
||||
magit-commit-augment
|
||||
magit-commit-instant-fixup
|
||||
magit-commit-instant-squash))
|
||||
|
||||
(defun magit-run-post-commit-hook ()
|
||||
(when (and (not this-command)
|
||||
(memq last-command magit-post-commit-hook-commands))
|
||||
(run-hooks 'magit-post-commit-hook)))
|
||||
|
||||
;;; Pending Diff
|
||||
|
||||
(defun magit-commit-diff ()
|
||||
(magit-repository-local-set 'this-commit-command
|
||||
(if (eq this-command 'with-editor-finish)
|
||||
'magit-commit--rebase
|
||||
last-command))
|
||||
(when (and git-commit-mode magit-commit-show-diff)
|
||||
(when-let ((diff-buffer (magit-get-mode-buffer 'magit-diff-mode)))
|
||||
;; This window just started displaying the commit message
|
||||
;; buffer. Without this that buffer would immediately be
|
||||
;; replaced with the diff buffer. See #2632.
|
||||
(unrecord-window-buffer nil diff-buffer))
|
||||
(condition-case nil
|
||||
(let ((args (car (magit-diff-arguments)))
|
||||
(magit-inhibit-save-previous-winconf 'unset)
|
||||
(magit-display-buffer-noselect t)
|
||||
(inhibit-quit nil)
|
||||
(display-buffer-overriding-action
|
||||
display-buffer-overriding-action))
|
||||
(when magit-commit-diff-inhibit-same-window
|
||||
(setq display-buffer-overriding-action
|
||||
'(nil (inhibit-same-window t))))
|
||||
(message "Diffing changes to be committed (C-g to abort diffing)")
|
||||
(cl-case last-command
|
||||
(magit-commit
|
||||
(magit-diff-staged nil args))
|
||||
(magit-commit-all
|
||||
(magit-diff-working-tree nil args))
|
||||
((magit-commit-amend
|
||||
magit-commit-reword
|
||||
magit-rebase-reword-commit)
|
||||
(magit-diff-while-amending args))
|
||||
(t (if (magit-anything-staged-p)
|
||||
(magit-diff-staged nil args)
|
||||
(magit-diff-while-amending args)))))
|
||||
(quit))))
|
||||
(message "Diffing changes to be committed (C-g to abort diffing)")
|
||||
(let ((inhibit-quit nil))
|
||||
(condition-case nil
|
||||
(magit-commit-diff-1)
|
||||
(quit)))))
|
||||
|
||||
;; Mention `magit-diff-while-committing' because that's
|
||||
;; always what I search for when I try to find this line.
|
||||
(add-hook 'server-switch-hook 'magit-commit-diff)
|
||||
(add-hook 'with-editor-filter-visit-hook 'magit-commit-diff)
|
||||
(defun magit-commit-diff-1 ()
|
||||
(let ((rev nil)
|
||||
(arg "--cached")
|
||||
(command (magit-repository-local-get 'this-commit-command))
|
||||
(staged (magit-anything-staged-p))
|
||||
(unstaged
|
||||
;; Escape $GIT_DIR because `magit-anything-unstaged-p'
|
||||
;; requires a working tree.
|
||||
(magit-with-toplevel
|
||||
(magit-anything-unstaged-p)))
|
||||
(squash (let ((f (magit-git-dir "rebase-merge/rewritten-pending")))
|
||||
(and (file-exists-p f) (length (magit-file-lines f)))))
|
||||
(noalt nil))
|
||||
(pcase (list staged unstaged command)
|
||||
((and `(,_ ,_ magit-commit--rebase)
|
||||
(guard (integerp squash)))
|
||||
(setq rev (format "HEAD~%s" squash)))
|
||||
(`(,_ ,_ magit-commit-amend)
|
||||
(setq rev "HEAD^"))
|
||||
((or `(,_ ,_ magit-commit-reword)
|
||||
`(nil nil ,_))
|
||||
(setq rev "HEAD^..HEAD")
|
||||
(setq arg nil))
|
||||
(`(,_ t magit-commit--all)
|
||||
(setq rev "HEAD")
|
||||
(setq arg nil))
|
||||
(`(nil t handle-switch-frame)
|
||||
;; Either --all or --allow-empty. Assume it is the former.
|
||||
(setq rev "HEAD")
|
||||
(setq arg nil)))
|
||||
(cond
|
||||
((not
|
||||
(and (eq this-command 'magit-diff-while-committing)
|
||||
(and-let* ((buf (magit-get-mode-buffer
|
||||
'magit-diff-mode nil 'selected)))
|
||||
(and (equal rev (buffer-local-value 'magit-buffer-range buf))
|
||||
(equal arg (buffer-local-value 'magit-buffer-typearg buf)))))))
|
||||
((eq command 'magit-commit-amend)
|
||||
(setq rev nil))
|
||||
((or squash (file-exists-p (magit-git-dir "rebase-merge/amend")))
|
||||
(setq rev "HEAD^"))
|
||||
(t
|
||||
(message "No alternative diff while committing")
|
||||
(setq noalt t)))
|
||||
(unless noalt
|
||||
(let ((magit-inhibit-save-previous-winconf 'unset)
|
||||
(magit-display-buffer-noselect t)
|
||||
(display-buffer-overriding-action
|
||||
display-buffer-overriding-action))
|
||||
(when magit-commit-diff-inhibit-same-window
|
||||
(setq display-buffer-overriding-action
|
||||
'(nil (inhibit-same-window . t))))
|
||||
(magit-diff-setup-buffer rev arg (car (magit-diff-arguments)) nil)))))
|
||||
|
||||
(add-hook 'server-switch-hook #'magit-commit-diff)
|
||||
(add-hook 'with-editor-filter-visit-hook #'magit-commit-diff)
|
||||
|
||||
(add-to-list 'with-editor-server-window-alist
|
||||
(cons git-commit-filename-regexp 'switch-to-buffer))
|
||||
(cons git-commit-filename-regexp #'switch-to-buffer))
|
||||
|
||||
(defun magit-commit--reset-command ()
|
||||
(magit-repository-local-delete 'this-commit-command))
|
||||
|
||||
;;; Message Utilities
|
||||
|
||||
@@ -640,7 +639,7 @@ See `magit-commit-absorb' for an alternative implementation."
|
||||
(append (buffer-list (selected-frame))
|
||||
(buffer-list)))))
|
||||
|
||||
(defvar magit-commit-add-log-insert-function 'magit-commit-add-log-insert
|
||||
(defvar magit-commit-add-log-insert-function #'magit-commit-add-log-insert
|
||||
"Used by `magit-commit-add-log' to insert a single entry.")
|
||||
|
||||
(defun magit-commit-add-log ()
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-core.el --- core functionality -*- lexical-binding: t -*-
|
||||
;;; magit-core.el --- Core functionality -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -32,8 +29,7 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit-utils)
|
||||
(require 'magit-section)
|
||||
(require 'magit-base)
|
||||
(require 'magit-git)
|
||||
(require 'magit-mode)
|
||||
(require 'magit-margin)
|
||||
@@ -49,6 +45,8 @@
|
||||
(message "Error while loading `magit-libgit': %S" err)
|
||||
(message "That is not fatal. The `libegit2' module just won't be used."))))
|
||||
|
||||
;;; Options
|
||||
|
||||
(defgroup magit nil
|
||||
"Controlling Git from Emacs."
|
||||
:link '(url-link "https://magit.vc")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,16 @@
|
||||
;;; magit-ediff.el --- Ediff extension for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-ediff.el --- Ediff extension for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -55,10 +52,18 @@ invoked using Magit."
|
||||
:package-version '(magit . "2.2.0")
|
||||
:group 'magit-ediff
|
||||
:type 'hook
|
||||
:get 'magit-hook-custom-get
|
||||
:get #'magit-hook-custom-get
|
||||
:options '(magit-ediff-cleanup-auxiliary-buffers
|
||||
magit-ediff-restore-previous-winconf))
|
||||
|
||||
(defcustom magit-ediff-dwim-resolve-function #'magit-ediff-resolve-rest
|
||||
"The function `magit-ediff-dwim' uses to resolve conflicts."
|
||||
:package-version '(magit . "3.4.0")
|
||||
:group 'magit-ediff
|
||||
:type '(choice (const magit-ediff-resolve-rest)
|
||||
(const magit-ediff-resolve-all)
|
||||
(const magit-git-mergetool)))
|
||||
|
||||
(defcustom magit-ediff-dwim-show-on-hunks nil
|
||||
"Whether `magit-ediff-dwim' runs show variants on hunks.
|
||||
If non-nil, `magit-ediff-show-staged' or
|
||||
@@ -101,11 +106,10 @@ tree at the time of stashing."
|
||||
:group 'magit-ediff
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom magit-ediff-use-indirect-buffers nil
|
||||
"Whether to use indirect buffers."
|
||||
:package-version '(magit . "3.1.0")
|
||||
:group 'magit-ediff
|
||||
:type 'boolean)
|
||||
(defvar magit-ediff-use-indirect-buffers nil
|
||||
"Whether to use indirect buffers.
|
||||
Ediff already does a lot of buffer and file shuffling and I
|
||||
recommend you do not further complicate that by enabling this.")
|
||||
|
||||
;;; Commands
|
||||
|
||||
@@ -117,8 +121,10 @@ tree at the time of stashing."
|
||||
:info-manual "(ediff)"
|
||||
["Ediff"
|
||||
[("E" "Dwim" magit-ediff-dwim)
|
||||
("s" "Stage" magit-ediff-stage)
|
||||
("m" "Resolve" magit-ediff-resolve)]
|
||||
("s" "Stage" magit-ediff-stage)]
|
||||
[("m" "Resolve rest" magit-ediff-resolve-rest)
|
||||
("M" "Resolve all conflicts" magit-ediff-resolve-all)
|
||||
("t" "Resolve using mergetool" magit-git-mergetool)]
|
||||
[("u" "Show unstaged" magit-ediff-show-unstaged)
|
||||
("i" "Show staged" magit-ediff-show-staged)
|
||||
("w" "Show worktree" magit-ediff-show-working-tree)]
|
||||
@@ -126,21 +132,165 @@ tree at the time of stashing."
|
||||
("r" "Show range" magit-ediff-compare)
|
||||
("z" "Show stash" magit-ediff-show-stash)]])
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-resolve (file)
|
||||
"Resolve outstanding conflicts in FILE using Ediff.
|
||||
FILE has to be relative to the top directory of the repository.
|
||||
(defmacro magit-ediff-buffers (a b &optional c setup quit file)
|
||||
"Run Ediff on two or three buffers.
|
||||
This is a wrapper around `ediff-buffers-internal'.
|
||||
|
||||
In the rare event that you want to manually resolve all
|
||||
conflicts, including those already resolved by Git, use
|
||||
`ediff-merge-revisions-with-ancestor'."
|
||||
(interactive
|
||||
(let ((current (magit-current-file))
|
||||
(unmerged (magit-unmerged-files)))
|
||||
(unless unmerged
|
||||
(user-error "There are no unresolved conflicts"))
|
||||
(list (magit-completing-read "Resolve file" unmerged nil t nil nil
|
||||
(car (member current unmerged))))))
|
||||
A, B and C have the form (GET-BUFFER CREATE-BUFFER). If
|
||||
GET-BUFFER returns a non-nil value, then that buffer is used and
|
||||
it is not killed when exiting Ediff. Otherwise CREATE-BUFFER
|
||||
must return a buffer and that is killed when exiting Ediff.
|
||||
|
||||
If non-nil, SETUP must be a function. It is called without
|
||||
arguments after Ediff is done setting up buffers.
|
||||
|
||||
If non-nil, QUIT must be a function. It is added to
|
||||
`ediff-quit-hook' and is called without arguments.
|
||||
|
||||
If FILE is non-nil, then perform a merge. The merge result
|
||||
is put in FILE."
|
||||
(let (get make kill (char ?A))
|
||||
(dolist (spec (list a b c))
|
||||
(if (not spec)
|
||||
(push nil make)
|
||||
(pcase-let ((`(,g ,m) spec))
|
||||
(let ((b (intern (format "buf%c" char))))
|
||||
(push `(,b ,g) get)
|
||||
;; This is an unfortunate complication that I have added for
|
||||
;; the benefit of one user. Pretend we used this instead:
|
||||
;; (push `(or ,b ,m) make)
|
||||
(push `(if ,b
|
||||
(if magit-ediff-use-indirect-buffers
|
||||
(prog1 (make-indirect-buffer
|
||||
,b
|
||||
(generate-new-buffer-name (buffer-name ,b))
|
||||
t)
|
||||
(setq ,b nil))
|
||||
,b)
|
||||
,m)
|
||||
make)
|
||||
(push `(unless ,b
|
||||
;; For merge jobs Ediff switches buffer names around.
|
||||
;; See (if ediff-merge-job ...) in `ediff-setup'.
|
||||
(let ((var ,(if (and file (= char ?C))
|
||||
'ediff-ancestor-buffer
|
||||
(intern (format "ediff-buffer-%c" char)))))
|
||||
(ediff-kill-buffer-carefully var)))
|
||||
kill))
|
||||
(cl-incf char))))
|
||||
(setq get (nreverse get))
|
||||
(setq make (nreverse make))
|
||||
(setq kill (nreverse kill))
|
||||
(let ((mconf (cl-gensym "conf"))
|
||||
(mfile (cl-gensym "file")))
|
||||
`(magit-with-toplevel
|
||||
(let ((,mconf (current-window-configuration))
|
||||
(,mfile ,file)
|
||||
,@get)
|
||||
(ediff-buffers-internal
|
||||
,@make
|
||||
(list ,@(and setup (list setup))
|
||||
(lambda ()
|
||||
;; We do not want to kill buffers that existed before
|
||||
;; Ediff was invoked, so we cannot use Ediff's default
|
||||
;; quit functions. Ediff splits quitting across two
|
||||
;; hooks for merge jobs but we only ever use one.
|
||||
(setq-local ediff-quit-merge-hook nil)
|
||||
(setq-local ediff-quit-hook
|
||||
(list
|
||||
,@(and quit (list quit))
|
||||
(lambda ()
|
||||
,@kill
|
||||
(let ((magit-ediff-previous-winconf ,mconf))
|
||||
(run-hooks 'magit-ediff-quit-hook)))))))
|
||||
(pcase (list ,(and c t) (and ,mfile t))
|
||||
('(nil nil) 'ediff-buffers)
|
||||
('(nil t) 'ediff-merge-buffers)
|
||||
('(t nil) 'ediff-buffers3)
|
||||
('(t t) 'ediff-merge-buffers-with-ancestor))
|
||||
,mfile))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-resolve-all (file)
|
||||
"Resolve all conflicts in the FILE at point using Ediff.
|
||||
|
||||
If there is no file at point or if it doesn't have any unmerged
|
||||
changes, then prompt for a file.
|
||||
|
||||
See info node `(magit) Ediffing' for more information about this
|
||||
and alternative commands."
|
||||
(interactive (list (magit-read-unmerged-file)))
|
||||
(magit-with-toplevel
|
||||
(let* ((revA (or (magit-name-branch "HEAD")
|
||||
(magit-commit-p "HEAD")))
|
||||
(revB (cl-find-if (lambda (head) (file-exists-p (magit-git-dir head)))
|
||||
'("MERGE_HEAD" "CHERRY_PICK_HEAD" "REVERT_HEAD")))
|
||||
(revB (or (magit-name-branch revB)
|
||||
(magit-commit-p revB)))
|
||||
(revC (magit-commit-p (magit-git-string "merge-base" revA revB)))
|
||||
(fileA (magit--rev-file-name file revA revB))
|
||||
(fileB (magit--rev-file-name file revB revA))
|
||||
(fileC (or (magit--rev-file-name file revC revA)
|
||||
(magit--rev-file-name file revC revB))))
|
||||
;; Ediff assumes that the FILE where it is going to store the merge
|
||||
;; result does not exist yet, so move the existing file out of the
|
||||
;; way. If a buffer visits FILE, then we have to kill that upfront.
|
||||
(when-let ((buffer (find-buffer-visiting file)))
|
||||
(when (and (buffer-modified-p buffer)
|
||||
(not (y-or-n-p (format "Save buffer %s %s? "
|
||||
(buffer-name buffer)
|
||||
"(cannot continue otherwise)"))))
|
||||
(user-error "Abort"))
|
||||
(kill-buffer buffer))
|
||||
(let ((orig (concat file ".ORIG")))
|
||||
(when (file-exists-p orig)
|
||||
(rename-file orig (make-temp-name (concat orig "_"))))
|
||||
(rename-file file orig))
|
||||
(let ((setup (lambda ()
|
||||
;; Use the same conflict marker style as Git uses.
|
||||
(setq-local ediff-combination-pattern
|
||||
'("<<<<<<< HEAD" A
|
||||
,(format "||||||| %s" revC) Ancestor
|
||||
"=======" B
|
||||
,(format ">>>>>>> %s" revB)))))
|
||||
(quit (lambda ()
|
||||
;; For merge jobs Ediff switches buffer names around.
|
||||
;; At this point `ediff-buffer-C' no longer refer to
|
||||
;; the ancestor buffer but to the merge result buffer.
|
||||
;; See (if ediff-merge-job ...) in `ediff-setup'.
|
||||
(when (buffer-live-p ediff-buffer-C)
|
||||
(with-current-buffer ediff-buffer-C
|
||||
(save-buffer)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(unless (re-search-forward "^<<<<<<< " nil t)
|
||||
(magit-stage-file file))))))))
|
||||
(if fileC
|
||||
(magit-ediff-buffers
|
||||
((magit-get-revision-buffer revA fileA)
|
||||
(magit-find-file-noselect revA fileA))
|
||||
((magit-get-revision-buffer revB fileB)
|
||||
(magit-find-file-noselect revB fileB))
|
||||
((magit-get-revision-buffer revC fileC)
|
||||
(magit-find-file-noselect revC fileC))
|
||||
setup quit file)
|
||||
(magit-ediff-buffers
|
||||
((magit-get-revision-buffer revA fileA)
|
||||
(magit-find-file-noselect revA fileA))
|
||||
((magit-get-revision-buffer revB fileB)
|
||||
(magit-find-file-noselect revB fileB))
|
||||
nil setup quit file))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-resolve-rest (file)
|
||||
"Resolve outstanding conflicts in the FILE at point using Ediff.
|
||||
|
||||
If there is no file at point or if it doesn't have any unmerged
|
||||
changes, then prompt for a file.
|
||||
|
||||
See info node `(magit) Ediffing' for more information about this
|
||||
and alternative commands."
|
||||
(interactive (list (magit-read-unmerged-file)))
|
||||
(magit-with-toplevel
|
||||
(with-current-buffer (find-file-noselect file)
|
||||
(smerge-ediff)
|
||||
@@ -163,45 +313,6 @@ conflicts, including those already resolved by Git, use
|
||||
(let ((magit-ediff-previous-winconf smerge-ediff-windows))
|
||||
(run-hooks 'magit-ediff-quit-hook)))))))
|
||||
|
||||
(defmacro magit-ediff-buffers (quit &rest spec)
|
||||
(declare (indent 1))
|
||||
(let ((fn (if (= (length spec) 3) 'ediff-buffers3 'ediff-buffers))
|
||||
(char ?@)
|
||||
get make kill)
|
||||
(pcase-dolist (`(,g ,m) spec)
|
||||
(let ((b (intern (format "buf%c" (cl-incf char)))))
|
||||
(push `(,b ,g) get)
|
||||
(push `(if ,b
|
||||
(if magit-ediff-use-indirect-buffers
|
||||
(prog1
|
||||
(make-indirect-buffer
|
||||
,b (generate-new-buffer-name (buffer-name ,b)) t)
|
||||
(setq ,b nil))
|
||||
,b)
|
||||
,m)
|
||||
make)
|
||||
(push `(unless ,b
|
||||
(ediff-kill-buffer-carefully
|
||||
,(intern (format "ediff-buffer-%c" char))))
|
||||
kill)))
|
||||
(setq get (nreverse get))
|
||||
(setq make (nreverse make))
|
||||
(setq kill (nreverse kill))
|
||||
`(magit-with-toplevel
|
||||
(let ((conf (current-window-configuration))
|
||||
,@get)
|
||||
(,fn
|
||||
,@make
|
||||
(list (lambda ()
|
||||
(setq-local
|
||||
ediff-quit-hook
|
||||
(list ,@(and quit (list quit))
|
||||
(lambda ()
|
||||
,@kill
|
||||
(let ((magit-ediff-previous-winconf conf))
|
||||
(run-hooks 'magit-ediff-quit-hook)))))))
|
||||
',fn)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-stage (file)
|
||||
"Stage and unstage changes to FILE using Ediff.
|
||||
@@ -222,23 +333,24 @@ FILE has to be relative to the top directory of the repository."
|
||||
(buffer-local-value 'buffer-file-coding-system bufC*))
|
||||
(bufA* (magit-find-file-noselect-1 "HEAD" file t))
|
||||
(bufB* (magit-find-file-index-noselect file t)))
|
||||
(setf (buffer-local-value 'buffer-read-only bufB*) nil)
|
||||
(with-current-buffer bufB* (setq buffer-read-only nil))
|
||||
(magit-ediff-buffers
|
||||
(lambda ()
|
||||
(when (buffer-live-p ediff-buffer-B)
|
||||
(when lockB
|
||||
(setf (buffer-local-value 'buffer-read-only bufB) t))
|
||||
(when (buffer-modified-p ediff-buffer-B)
|
||||
(with-current-buffer ediff-buffer-B
|
||||
(magit-update-index))))
|
||||
(when (and (buffer-live-p ediff-buffer-C)
|
||||
(buffer-modified-p ediff-buffer-C))
|
||||
(with-current-buffer ediff-buffer-C
|
||||
(when (y-or-n-p (format "Save file %s? " buffer-file-name))
|
||||
(save-buffer)))))
|
||||
(bufA bufA*)
|
||||
(bufB bufB*)
|
||||
(bufC bufC*)))))
|
||||
(bufA bufA*)
|
||||
(bufB bufB*)
|
||||
(bufC bufC*)
|
||||
nil
|
||||
(lambda ()
|
||||
(when (buffer-live-p ediff-buffer-B)
|
||||
(when lockB
|
||||
(with-current-buffer bufB (setq buffer-read-only t)))
|
||||
(when (buffer-modified-p ediff-buffer-B)
|
||||
(with-current-buffer ediff-buffer-B
|
||||
(magit-update-index))))
|
||||
(when (and (buffer-live-p ediff-buffer-C)
|
||||
(buffer-modified-p ediff-buffer-C))
|
||||
(with-current-buffer ediff-buffer-C
|
||||
(when (y-or-n-p (format "Save file %s? " buffer-file-name))
|
||||
(save-buffer)))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-compare (revA revB fileA fileB)
|
||||
@@ -258,11 +370,11 @@ range)."
|
||||
nil current-prefix-arg)))
|
||||
(nconc (list revA revB)
|
||||
(magit-ediff-read-files revA revB))))
|
||||
(magit-ediff-buffers nil
|
||||
((if revA (magit-get-revision-buffer revA fileA) (get-file-buffer fileA))
|
||||
(if revA (magit-find-file-noselect revA fileA) (find-file-noselect fileA)))
|
||||
((if revB (magit-get-revision-buffer revB fileB) (get-file-buffer fileB))
|
||||
(if revB (magit-find-file-noselect revB fileB) (find-file-noselect fileB)))))
|
||||
(magit-ediff-buffers
|
||||
((if revA (magit-get-revision-buffer revA fileA) (get-file-buffer fileA))
|
||||
(if revA (magit-find-file-noselect revA fileA) (find-file-noselect fileA)))
|
||||
((if revB (magit-get-revision-buffer revB fileB) (get-file-buffer fileB))
|
||||
(if revB (magit-find-file-noselect revB fileB) (find-file-noselect fileB)))))
|
||||
|
||||
(defun magit-ediff-compare--read-revisions (&optional arg mbase)
|
||||
(let ((input (or arg (magit-diff-read-range-or-commit
|
||||
@@ -276,13 +388,23 @@ range)."
|
||||
"Read file in REVB, return it and the corresponding file in REVA.
|
||||
When FILEB is non-nil, use this as REVB's file instead of
|
||||
prompting for it."
|
||||
(unless fileB
|
||||
(setq fileB (magit-read-file-choice
|
||||
(format "File to compare between %s and %s"
|
||||
revA (or revB "the working tree"))
|
||||
(magit-changed-files revA revB)
|
||||
(format "No changed files between %s and %s"
|
||||
revA (or revB "the working tree")))))
|
||||
(unless (and fileB (member fileB (magit-revision-files revB)))
|
||||
(setq fileB
|
||||
(or (and fileB
|
||||
magit-buffer-log-files
|
||||
(derived-mode-p 'magit-log-mode)
|
||||
(member "--follow" magit-buffer-log-args)
|
||||
(cdr (assoc fileB
|
||||
(magit-renamed-files
|
||||
revB
|
||||
(oref (car (oref magit-root-section children))
|
||||
value)))))
|
||||
(magit-read-file-choice
|
||||
(format "File to compare between %s and %s"
|
||||
revA (or revB "the working tree"))
|
||||
(magit-changed-files revA revB)
|
||||
(format "No changed files between %s and %s"
|
||||
revA (or revB "the working tree"))))))
|
||||
(list (or (car (member fileB (magit-revision-files revA)))
|
||||
(cdr (assoc fileB (magit-renamed-files revB revA)))
|
||||
(magit-read-file-choice
|
||||
@@ -314,12 +436,12 @@ mind at all, then it asks the user for a command to run."
|
||||
command revA revB)
|
||||
(pcase range
|
||||
((and (guard (not magit-ediff-dwim-show-on-hunks))
|
||||
(or `unstaged `staged))
|
||||
(or 'unstaged 'staged))
|
||||
(setq command (if (magit-anything-unmerged-p)
|
||||
#'magit-ediff-resolve
|
||||
magit-ediff-dwim-resolve-function
|
||||
#'magit-ediff-stage)))
|
||||
(`unstaged (setq command #'magit-ediff-show-unstaged))
|
||||
(`staged (setq command #'magit-ediff-show-staged))
|
||||
('unstaged (setq command #'magit-ediff-show-unstaged))
|
||||
('staged (setq command #'magit-ediff-show-staged))
|
||||
(`(commit . ,value)
|
||||
(setq command #'magit-ediff-show-commit)
|
||||
(setq revB value))
|
||||
@@ -334,31 +456,34 @@ mind at all, then it asks the user for a command to run."
|
||||
(_
|
||||
(when (derived-mode-p 'magit-diff-mode)
|
||||
(pcase (magit-diff-type)
|
||||
(`committed (pcase-let ((`(,a ,b)
|
||||
('committed (pcase-let ((`(,a ,b)
|
||||
(magit-ediff-compare--read-revisions
|
||||
magit-buffer-range)))
|
||||
(setq revA a)
|
||||
(setq revB b)))
|
||||
((guard (not magit-ediff-dwim-show-on-hunks))
|
||||
(setq command #'magit-ediff-stage))
|
||||
(`unstaged (setq command #'magit-ediff-show-unstaged))
|
||||
(`staged (setq command #'magit-ediff-show-staged))
|
||||
(`undefined (setq command nil))
|
||||
('unstaged (setq command #'magit-ediff-show-unstaged))
|
||||
('staged (setq command #'magit-ediff-show-staged))
|
||||
('undefined (setq command nil))
|
||||
(_ (setq command nil))))))
|
||||
(cond ((not command)
|
||||
(call-interactively
|
||||
(magit-read-char-case
|
||||
"Failed to read your mind; do you want to " t
|
||||
(?c "[c]ommit" 'magit-ediff-show-commit)
|
||||
(?r "[r]ange" 'magit-ediff-compare)
|
||||
(?s "[s]tage" 'magit-ediff-stage)
|
||||
(?v "resol[v]e" 'magit-ediff-resolve))))
|
||||
((eq command 'magit-ediff-compare)
|
||||
(apply 'magit-ediff-compare revA revB
|
||||
(?c "[c]ommit" #'magit-ediff-show-commit)
|
||||
(?r "[r]ange" #'magit-ediff-compare)
|
||||
(?s "[s]tage" #'magit-ediff-stage)
|
||||
(?m "[m] resolve remaining conflicts"
|
||||
#'magit-ediff-resolve-rest)
|
||||
(?M "[M] resolve all conflicts"
|
||||
#'magit-ediff-resolve-all))))
|
||||
((eq command #'magit-ediff-compare)
|
||||
(apply #'magit-ediff-compare revA revB
|
||||
(magit-ediff-read-files revA revB file)))
|
||||
((eq command 'magit-ediff-show-commit)
|
||||
((eq command #'magit-ediff-show-commit)
|
||||
(magit-ediff-show-commit revB))
|
||||
((eq command 'magit-ediff-show-stash)
|
||||
((eq command #'magit-ediff-show-stash)
|
||||
(magit-ediff-show-stash revB))
|
||||
(file
|
||||
(funcall command file))
|
||||
@@ -377,11 +502,10 @@ FILE must be relative to the top directory of the repository."
|
||||
(list (magit-read-file-choice "Show staged changes for file"
|
||||
(magit-staged-files)
|
||||
"No staged files")))
|
||||
(magit-ediff-buffers nil
|
||||
((magit-get-revision-buffer "HEAD" file)
|
||||
(magit-find-file-noselect "HEAD" file))
|
||||
((get-buffer (concat file ".~{index}~"))
|
||||
(magit-find-file-index-noselect file t))))
|
||||
(magit-ediff-buffers ((magit-get-revision-buffer "HEAD" file)
|
||||
(magit-find-file-noselect "HEAD" file))
|
||||
((get-buffer (concat file ".~{index}~"))
|
||||
(magit-find-file-index-noselect file t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-show-unstaged (file)
|
||||
@@ -395,11 +519,10 @@ FILE must be relative to the top directory of the repository."
|
||||
(list (magit-read-file-choice "Show unstaged changes for file"
|
||||
(magit-unstaged-files)
|
||||
"No unstaged files")))
|
||||
(magit-ediff-buffers nil
|
||||
((get-buffer (concat file ".~{index}~"))
|
||||
(magit-find-file-index-noselect file t))
|
||||
((get-file-buffer file)
|
||||
(find-file-noselect file))))
|
||||
(magit-ediff-buffers ((get-buffer (concat file ".~{index}~"))
|
||||
(magit-find-file-index-noselect file t))
|
||||
((get-file-buffer file)
|
||||
(find-file-noselect file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-show-working-tree (file)
|
||||
@@ -409,11 +532,10 @@ FILE must be relative to the top directory of the repository."
|
||||
(list (magit-read-file-choice "Show changes in file"
|
||||
(magit-changed-files "HEAD")
|
||||
"No changed files")))
|
||||
(magit-ediff-buffers nil
|
||||
((magit-get-revision-buffer "HEAD" file)
|
||||
(magit-find-file-noselect "HEAD" file))
|
||||
((get-file-buffer file)
|
||||
(find-file-noselect file))))
|
||||
(magit-ediff-buffers ((magit-get-revision-buffer "HEAD" file)
|
||||
(magit-find-file-noselect "HEAD" file))
|
||||
((get-file-buffer file)
|
||||
(find-file-noselect file))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-show-commit (commit)
|
||||
@@ -439,13 +561,13 @@ stash that were staged."
|
||||
(fileB fileC))
|
||||
(if (and magit-ediff-show-stash-with-index
|
||||
(member fileA (magit-changed-files revB revA)))
|
||||
(magit-ediff-buffers nil
|
||||
((magit-get-revision-buffer revA fileA)
|
||||
(magit-find-file-noselect revA fileA))
|
||||
((magit-get-revision-buffer revB fileB)
|
||||
(magit-find-file-noselect revB fileB))
|
||||
((magit-get-revision-buffer revC fileC)
|
||||
(magit-find-file-noselect revC fileC)))
|
||||
(magit-ediff-buffers
|
||||
((magit-get-revision-buffer revA fileA)
|
||||
(magit-find-file-noselect revA fileA))
|
||||
((magit-get-revision-buffer revB fileB)
|
||||
(magit-find-file-noselect revB fileB))
|
||||
((magit-get-revision-buffer revC fileC)
|
||||
(magit-find-file-noselect revC fileC)))
|
||||
(magit-ediff-compare revA revC fileA fileC))))
|
||||
|
||||
(defun magit-ediff-cleanup-auxiliary-buffers ()
|
||||
@@ -465,7 +587,7 @@ stash that were staged."
|
||||
(ediff-kill-buffer-carefully ediff-debug-buffer)
|
||||
(when (boundp 'ediff-patch-diagnostics)
|
||||
(ediff-kill-buffer-carefully ediff-patch-diagnostics))
|
||||
(cond ((and (ediff-window-display-p)
|
||||
(cond ((and (display-graphic-p)
|
||||
(frame-live-p ctl-frm))
|
||||
(delete-frame ctl-frm))
|
||||
((window-live-p ctl-win)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-extras.el --- additional functionality for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-extras.el --- Additional functionality for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -31,12 +28,11 @@
|
||||
|
||||
(require 'magit)
|
||||
|
||||
(declare-function change-log-insert-entries "add-log" (changelogs))
|
||||
(declare-function diff-add-log-current-defuns "diff-mode" ())
|
||||
;; For `magit-do-async-shell-command'.
|
||||
(declare-function dired-read-shell-command "dired-aux" (prompt arg files))
|
||||
;; For `magit-project-status'.
|
||||
(declare-function project-root "project" (project))
|
||||
(declare-function vc-git-command "vc-git" (buffer okstatus file-or-list &rest flags))
|
||||
(declare-function vc-git-command "vc-git"
|
||||
(buffer okstatus file-or-list &rest flags))
|
||||
|
||||
(defvar ido-exit)
|
||||
(defvar ido-fallback)
|
||||
@@ -47,25 +43,89 @@
|
||||
"Additional functionality for Magit."
|
||||
:group 'magit-extensions)
|
||||
|
||||
;;; External Tools
|
||||
;;; Git Tools
|
||||
;;;; Git-Mergetool
|
||||
|
||||
(defcustom magit-gitk-executable
|
||||
(or (and (eq system-type 'windows-nt)
|
||||
(let ((exe (magit-git-string
|
||||
"-c" "alias.X=!x() { which \"$1\" | cygpath -mf -; }; x"
|
||||
"X" "gitk.exe")))
|
||||
(and exe (file-executable-p exe) exe)))
|
||||
(executable-find "gitk") "gitk")
|
||||
"The Gitk executable."
|
||||
:group 'magit-extras
|
||||
:set-after '(magit-git-executable)
|
||||
:type 'string)
|
||||
;;;###autoload (autoload 'magit-git-mergetool "magit-extras" nil t)
|
||||
(transient-define-prefix magit-git-mergetool (file args &optional transient)
|
||||
"Resolve conflicts in FILE using \"git mergetool --gui\".
|
||||
With a prefix argument allow changing ARGS using a transient
|
||||
popup. See info node `(magit) Ediffing' for information about
|
||||
alternative commands."
|
||||
:man-page "git-mergetool"
|
||||
["Settings"
|
||||
("-t" magit-git-mergetool:--tool)
|
||||
("=t" magit-merge.guitool)
|
||||
("=T" magit-merge.tool)
|
||||
("-r" magit-mergetool.hideResolved)
|
||||
("-b" magit-mergetool.keepBackup)
|
||||
("-k" magit-mergetool.keepTemporaries)
|
||||
("-w" magit-mergetool.writeToTemp)]
|
||||
["Actions"
|
||||
(" m" "Invoke mergetool" magit-git-mergetool)]
|
||||
(interactive
|
||||
(if (and (not (eq transient-current-prefix 'magit-git-mergetool))
|
||||
current-prefix-arg)
|
||||
(list nil nil t)
|
||||
(list (magit-read-unmerged-file "Resolve")
|
||||
(transient-args 'magit-git-mergetool))))
|
||||
(if transient
|
||||
(transient-setup 'magit-git-mergetool)
|
||||
(magit-run-git-async "mergetool" "--gui" args "--" file)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-run-git-gui ()
|
||||
"Run `git gui' for the current git repository."
|
||||
(interactive)
|
||||
(magit-with-toplevel (magit-process-git 0 "gui")))
|
||||
(transient-define-infix magit-git-mergetool:--tool ()
|
||||
:description "Override mergetool"
|
||||
:class 'transient-option
|
||||
:shortarg "-t"
|
||||
:argument "--tool="
|
||||
:reader #'magit--read-mergetool)
|
||||
|
||||
(transient-define-infix magit-merge.guitool ()
|
||||
:class 'magit--git-variable
|
||||
:variable "merge.guitool"
|
||||
:global t
|
||||
:reader #'magit--read-mergetool)
|
||||
|
||||
(transient-define-infix magit-merge.tool ()
|
||||
:class 'magit--git-variable
|
||||
:variable "merge.tool"
|
||||
:global t
|
||||
:reader #'magit--read-mergetool)
|
||||
|
||||
(defun magit--read-mergetool (prompt _initial-input history)
|
||||
(let ((choices nil)
|
||||
(lines (cdr (magit-git-lines "mergetool" "--tool-help"))))
|
||||
(while (string-prefix-p "\t\t" (car lines))
|
||||
(push (substring (pop lines) 2) choices))
|
||||
(setq choices (nreverse choices))
|
||||
(magit-completing-read (or prompt "Select mergetool")
|
||||
choices nil t nil history)))
|
||||
|
||||
(transient-define-infix magit-mergetool.hideResolved ()
|
||||
:class 'magit--git-variable:boolean
|
||||
:variable "mergetool.hideResolved"
|
||||
:default "false"
|
||||
:global t)
|
||||
|
||||
(transient-define-infix magit-mergetool.keepBackup ()
|
||||
:class 'magit--git-variable:boolean
|
||||
:variable "mergetool.keepBackup"
|
||||
:default "true"
|
||||
:global t)
|
||||
|
||||
(transient-define-infix magit-mergetool.keepTemporaries ()
|
||||
:class 'magit--git-variable:boolean
|
||||
:variable "mergetool.keepTemporaries"
|
||||
:default "false"
|
||||
:global t)
|
||||
|
||||
(transient-define-infix magit-mergetool.writeToTemp ()
|
||||
:class 'magit--git-variable:boolean
|
||||
:variable "mergetool.writeToTemp"
|
||||
:default "false"
|
||||
:global t)
|
||||
|
||||
;;;; Git-Gui
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-run-git-gui-blame (commit filename &optional linenum)
|
||||
@@ -92,6 +152,26 @@ blame to center around the line point is on."
|
||||
commit
|
||||
filename)))
|
||||
|
||||
;;;; Gitk
|
||||
|
||||
(defcustom magit-gitk-executable
|
||||
(or (and (eq system-type 'windows-nt)
|
||||
(let ((exe (magit-git-string
|
||||
"-c" "alias.X=!x() { which \"$1\" | cygpath -mf -; }; x"
|
||||
"X" "gitk.exe")))
|
||||
(and exe (file-executable-p exe) exe)))
|
||||
(executable-find "gitk") "gitk")
|
||||
"The Gitk executable."
|
||||
:group 'magit-extras
|
||||
:set-after '(magit-git-executable)
|
||||
:type 'string)
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-run-git-gui ()
|
||||
"Run `git gui' for the current git repository."
|
||||
(interactive)
|
||||
(magit-with-toplevel (magit-process-git 0 "gui")))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-run-gitk ()
|
||||
"Run `gitk' in the current repository."
|
||||
@@ -135,15 +215,17 @@ like pretty much every other keymap:
|
||||
(kbd \"C-x g\") \\='ido-enter-magit-status)"
|
||||
(interactive)
|
||||
(setq ido-exit 'fallback)
|
||||
(setq ido-fallback 'magit-status) ; for Emacs >= 26.2
|
||||
(with-no-warnings (setq fallback 'magit-status)) ; for Emacs 25
|
||||
(setq ido-fallback #'magit-status) ; for Emacs >= 26.2
|
||||
(with-no-warnings (setq fallback #'magit-status)) ; for Emacs 25
|
||||
(exit-minibuffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-project-status ()
|
||||
"Run `magit-status' in the current project's root."
|
||||
(interactive)
|
||||
(magit-status-setup-buffer (project-root (project-current t))))
|
||||
(if (fboundp 'project-root)
|
||||
(magit-status-setup-buffer (project-root (project-current t)))
|
||||
(user-error "`magit-project-status' requires `project' 0.3.0 or greater")))
|
||||
|
||||
(defvar magit-bind-magit-project-status t
|
||||
"Whether to bind \"m\" to `magit-project-status' in `project-prefix-map'.
|
||||
@@ -170,7 +252,7 @@ With a prefix argument, visit in another window. If there
|
||||
is no file at point, then instead visit `default-directory'."
|
||||
(interactive "P")
|
||||
(dired-jump other-window
|
||||
(when-let ((file (magit-file-at-point)))
|
||||
(and-let* ((file (magit-file-at-point)))
|
||||
(expand-file-name (if (file-directory-p file)
|
||||
(file-name-as-directory file)
|
||||
file)))))
|
||||
@@ -181,9 +263,9 @@ is no file at point, then instead visit `default-directory'."
|
||||
(interactive "P")
|
||||
(if-let ((topdir (magit-toplevel default-directory)))
|
||||
(let ((args (car (magit-log-arguments)))
|
||||
(files (dired-get-marked-files nil nil #'magit-file-tracked-p)))
|
||||
(unless files
|
||||
(user-error "No marked file is being tracked by Git"))
|
||||
(files (compat-dired-get-marked-files
|
||||
nil nil #'magit-file-tracked-p nil
|
||||
"No marked file is being tracked by Git")))
|
||||
(when (and follow
|
||||
(not (member "--follow" args))
|
||||
(not (cdr files)))
|
||||
@@ -204,10 +286,7 @@ for a repository."
|
||||
(interactive (list (or (magit-toplevel)
|
||||
(magit-read-repository t))
|
||||
current-prefix-arg))
|
||||
;; Note: The ERROR argument of `dired-get-marked-files' isn't
|
||||
;; available until Emacs 27.
|
||||
(let ((files (or (dired-get-marked-files nil arg)
|
||||
(user-error "No files specified"))))
|
||||
(let ((files (compat-dired-get-marked-files nil arg nil nil t)))
|
||||
(magit-status-setup-buffer repo)
|
||||
(magit-am-apply-patches files)))
|
||||
|
||||
@@ -310,31 +389,32 @@ in HEAD as well as staged changes in the diff to check."
|
||||
(require 'diff-mode) ; `diff-add-log-current-defuns'.
|
||||
(require 'vc-git) ; `vc-git-diff'.
|
||||
(require 'add-log) ; `change-log-insert-entries'.
|
||||
(unless (and (fboundp 'change-log-insert-entries)
|
||||
(fboundp 'diff-add-log-current-defuns))
|
||||
(user-error "`magit-generate-changelog' requires Emacs 27 or better"))
|
||||
(setq default-directory
|
||||
(if (and (file-regular-p "gitdir")
|
||||
(not (magit-git-true "rev-parse" "--is-inside-work-tree"))
|
||||
(magit-git-true "rev-parse" "--is-inside-git-dir"))
|
||||
(file-name-directory (magit-file-line "gitdir"))
|
||||
(magit-toplevel)))
|
||||
(let ((rev1 (if amending "HEAD^1" "HEAD"))
|
||||
(rev2 nil))
|
||||
;; Magit may have updated the files without notifying vc, but
|
||||
;; `diff-add-log-current-defuns' relies on vc being up-to-date.
|
||||
(mapc #'vc-file-clearprops (magit-staged-files))
|
||||
(change-log-insert-entries
|
||||
(with-temp-buffer
|
||||
(vc-git-command (current-buffer) 1 nil
|
||||
"diff-index" "--exit-code" "--patch"
|
||||
(and (magit-anything-staged-p) "--cached")
|
||||
rev1 "--")
|
||||
;; `diff-find-source-location' consults these vars.
|
||||
(defvar diff-vc-revisions)
|
||||
(setq-local diff-vc-revisions (list rev1 rev2))
|
||||
(setq-local diff-vc-backend 'Git)
|
||||
(diff-add-log-current-defuns)))))
|
||||
(cond
|
||||
((and (fboundp 'change-log-insert-entries)
|
||||
(fboundp 'diff-add-log-current-defuns))
|
||||
(setq default-directory
|
||||
(if (and (file-regular-p "gitdir")
|
||||
(not (magit-git-true "rev-parse" "--is-inside-work-tree"))
|
||||
(magit-git-true "rev-parse" "--is-inside-git-dir"))
|
||||
(file-name-directory (magit-file-line "gitdir"))
|
||||
(magit-toplevel)))
|
||||
(let ((rev1 (if amending "HEAD^1" "HEAD"))
|
||||
(rev2 nil))
|
||||
;; Magit may have updated the files without notifying vc, but
|
||||
;; `diff-add-log-current-defuns' relies on vc being up-to-date.
|
||||
(mapc #'vc-file-clearprops (magit-staged-files))
|
||||
(change-log-insert-entries
|
||||
(with-temp-buffer
|
||||
(vc-git-command (current-buffer) 1 nil
|
||||
"diff-index" "--exit-code" "--patch"
|
||||
(and (magit-anything-staged-p) "--cached")
|
||||
rev1 "--")
|
||||
;; `diff-find-source-location' consults these vars.
|
||||
(defvar diff-vc-revisions)
|
||||
(setq-local diff-vc-revisions (list rev1 rev2))
|
||||
(setq-local diff-vc-backend 'Git)
|
||||
(diff-add-log-current-defuns)))))
|
||||
(t (user-error "`magit-generate-changelog' requires Emacs 27 or greater"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-add-change-log-entry (&optional whoami file-name other-window)
|
||||
@@ -377,7 +457,7 @@ points at it) otherwise."
|
||||
(interactive (list (and current-prefix-arg 'removal)))
|
||||
(let* ((chunk (magit-current-blame-chunk (or type 'addition)))
|
||||
(rev (oref chunk orig-rev)))
|
||||
(if (equal rev "0000000000000000000000000000000000000000")
|
||||
(if (string-match-p "\\`0\\{40,\\}\\'" rev)
|
||||
(message "This line has not been committed yet")
|
||||
(let ((rebase (magit-rev-ancestor-p rev "HEAD"))
|
||||
(file (expand-file-name (oref chunk orig-file)
|
||||
@@ -475,11 +555,11 @@ list returned by `magit-rebase-arguments'."
|
||||
"Type %p on a commit to reshelve it and the commits above it,"))
|
||||
(t
|
||||
(cl-flet ((adjust (time offset)
|
||||
(format-time-string
|
||||
"%F %T %z"
|
||||
(+ (floor time)
|
||||
(* offset 60)
|
||||
(- (car (decode-time time)))))))
|
||||
(format-time-string
|
||||
"%F %T %z"
|
||||
(+ (floor time)
|
||||
(* offset 60)
|
||||
(- (car (decode-time time)))))))
|
||||
(let* ((start (concat rev "^"))
|
||||
(range (concat start ".." current))
|
||||
(time-rev (adjust (float-time (string-to-number
|
||||
@@ -494,38 +574,38 @@ list returned by `magit-rebase-arguments'."
|
||||
(float-time
|
||||
(date-to-time
|
||||
(read-string "Date for first commit: "
|
||||
time-now 'magit--reshelve-history)))))
|
||||
(process-environment process-environment))
|
||||
(push "FILTER_BRANCH_SQUELCH_WARNING=1" process-environment)
|
||||
(magit-with-toplevel
|
||||
(magit-run-git-async
|
||||
"filter-branch" "--force" "--env-filter"
|
||||
(format
|
||||
"case $GIT_COMMIT in %s\nesac"
|
||||
(mapconcat
|
||||
(lambda (rev)
|
||||
(prog1 (concat
|
||||
(format "%s) " rev)
|
||||
(and (not magit-reshelve-since-committer-only)
|
||||
(format "export GIT_AUTHOR_DATE=\"%s\"; " date))
|
||||
(format "export GIT_COMMITTER_DATE=\"%s\";;" date))
|
||||
(cl-incf date 60)))
|
||||
(magit-git-lines "rev-list" "--reverse" range)
|
||||
" "))
|
||||
(and keyid
|
||||
(list "--commit-filter"
|
||||
(format "git commit-tree --gpg-sign=%s \"$@\";"
|
||||
keyid)))
|
||||
range "--"))
|
||||
(set-process-sentinel
|
||||
magit-this-process
|
||||
(lambda (process event)
|
||||
(when (memq (process-status process) '(exit signal))
|
||||
(if (> (process-exit-status process) 0)
|
||||
time-now 'magit--reshelve-history))))))
|
||||
(with-environment-variables (("FILTER_BRANCH_SQUELCH_WARNING" "1"))
|
||||
(magit-with-toplevel
|
||||
(magit-run-git-async
|
||||
"filter-branch" "--force" "--env-filter"
|
||||
(format
|
||||
"case $GIT_COMMIT in %s\nesac"
|
||||
(mapconcat
|
||||
(lambda (rev)
|
||||
(prog1
|
||||
(concat
|
||||
(format "%s) " rev)
|
||||
(and (not magit-reshelve-since-committer-only)
|
||||
(format "export GIT_AUTHOR_DATE=\"%s\"; " date))
|
||||
(format "export GIT_COMMITTER_DATE=\"%s\";;" date))
|
||||
(cl-incf date 60)))
|
||||
(magit-git-lines "rev-list" "--reverse" range)
|
||||
" "))
|
||||
(and keyid
|
||||
(list "--commit-filter"
|
||||
(format "git commit-tree --gpg-sign=%s \"$@\";"
|
||||
keyid)))
|
||||
range "--"))
|
||||
(set-process-sentinel
|
||||
magit-this-process
|
||||
(lambda (process event)
|
||||
(when (memq (process-status process) '(exit signal))
|
||||
(if (> (process-exit-status process) 0)
|
||||
(magit-process-sentinel process event)
|
||||
(process-put process 'inhibit-refresh t)
|
||||
(magit-process-sentinel process event)
|
||||
(process-put process 'inhibit-refresh t)
|
||||
(magit-process-sentinel process event)
|
||||
(magit-run-git "update-ref" "-d" backup))))))))))))
|
||||
(magit-run-git "update-ref" "-d" backup)))))))))))))
|
||||
|
||||
;;; Revision Stack
|
||||
|
||||
@@ -611,10 +691,10 @@ the minibuffer too."
|
||||
(interactive
|
||||
(if (or current-prefix-arg (not magit-revision-stack))
|
||||
(let ((default-directory
|
||||
(or (and (not (= (prefix-numeric-value current-prefix-arg) 16))
|
||||
(or (magit-toplevel)
|
||||
(cadr (car magit-revision-stack))))
|
||||
(magit-read-repository))))
|
||||
(or (and (not (= (prefix-numeric-value current-prefix-arg) 16))
|
||||
(or (magit-toplevel)
|
||||
(cadr (car magit-revision-stack))))
|
||||
(magit-read-repository))))
|
||||
(list (magit-read-branch-or-commit "Insert revision")
|
||||
default-directory))
|
||||
(push (caar magit-revision-stack) magit-revision-history)
|
||||
@@ -639,13 +719,13 @@ the minibuffer too."
|
||||
(when pnt-format
|
||||
(when idx-format
|
||||
(setq pnt-format
|
||||
(replace-regexp-in-string "%N" idx pnt-format t t)))
|
||||
(string-replace "%N" idx pnt-format)))
|
||||
(magit-rev-insert-format pnt-format rev pnt-args)
|
||||
(backward-delete-char 1))
|
||||
(when eob-format
|
||||
(when idx-format
|
||||
(setq eob-format
|
||||
(replace-regexp-in-string "%N" idx eob-format t t)))
|
||||
(string-replace "%N" idx eob-format)))
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(skip-syntax-backward ">s-")
|
||||
@@ -662,7 +742,7 @@ the minibuffer too."
|
||||
(user-error "Revision stack is empty")))
|
||||
|
||||
(define-key git-commit-mode-map
|
||||
(kbd "C-c C-w") 'magit-pop-revision-stack)
|
||||
(kbd "C-c C-w") #'magit-pop-revision-stack)
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-copy-section-value (arg)
|
||||
@@ -704,8 +784,8 @@ argument."
|
||||
((use-region-p)
|
||||
(call-interactively #'copy-region-as-kill))
|
||||
(t
|
||||
(when-let ((section (magit-current-section))
|
||||
(value (oref section value)))
|
||||
(when-let* ((section (magit-current-section))
|
||||
(value (oref section value)))
|
||||
(magit-section-case
|
||||
((branch commit module-commit tag)
|
||||
(let ((default-directory default-directory) ref)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-fetch.el --- download objects and refs -*- lexical-binding: t -*-
|
||||
;;; magit-fetch.el --- Download objects and refs -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -73,7 +70,7 @@
|
||||
With a prefix argument or when the push-remote is either not
|
||||
configured or unusable, then let the user first configure the
|
||||
push-remote."
|
||||
:description 'magit-fetch--pushremote-description
|
||||
:description #'magit-fetch--pushremote-description
|
||||
(interactive (list (magit-fetch-arguments)))
|
||||
(let ((remote (magit-get-push-remote)))
|
||||
(when (or current-prefix-arg
|
||||
@@ -181,7 +178,6 @@ with a prefix argument."
|
||||
(t "--jobs=4")))
|
||||
["Arguments"
|
||||
("-v" "verbose" "--verbose")
|
||||
("-a" "all remotes" "--all")
|
||||
("-j" "number of jobs" "--jobs=" :reader transient-read-number-N+)]
|
||||
["Action"
|
||||
("m" "fetch modules" magit-fetch-modules)]
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-files.el --- finding files -*- lexical-binding: t -*-
|
||||
;;; magit-files.el --- Finding files -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -154,7 +151,7 @@ then only after asking. A non-nil value for REVERT is ignored if REV is
|
||||
(magit-get-revision-buffer rev file t))
|
||||
|
||||
(defun magit-get-revision-buffer (rev file &optional create)
|
||||
(funcall (if create 'get-buffer-create 'get-buffer)
|
||||
(funcall (if create #'get-buffer-create #'get-buffer)
|
||||
(format "%s.~%s~" file (subst-char-in-string ?/ ?_ rev))))
|
||||
|
||||
(defun magit-revert-rev-file-buffer (_ignore-auto noconfirm)
|
||||
@@ -182,7 +179,8 @@ then only after asking. A non-nil value for REVERT is ignored if REV is
|
||||
(after-change-major-mode-hook
|
||||
(remq 'global-diff-hl-mode-enable-in-buffers
|
||||
after-change-major-mode-hook)))
|
||||
(normal-mode t))
|
||||
(delay-mode-hooks
|
||||
(normal-mode t)))
|
||||
(setq buffer-read-only t)
|
||||
(set-buffer-modified-p nil)
|
||||
(goto-char (point-min))))
|
||||
@@ -326,12 +324,12 @@ to `magit-dispatch'."
|
||||
|
||||
(defvar magit-blob-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "p" 'magit-blob-previous)
|
||||
(define-key map "n" 'magit-blob-next)
|
||||
(define-key map "b" 'magit-blame-addition)
|
||||
(define-key map "r" 'magit-blame-removal)
|
||||
(define-key map "f" 'magit-blame-reverse)
|
||||
(define-key map "q" 'magit-kill-this-buffer)
|
||||
(define-key map "p" #'magit-blob-previous)
|
||||
(define-key map "n" #'magit-blob-next)
|
||||
(define-key map "b" #'magit-blame-addition)
|
||||
(define-key map "r" #'magit-blame-removal)
|
||||
(define-key map "f" #'magit-blame-reverse)
|
||||
(define-key map "q" #'magit-kill-this-buffer)
|
||||
map)
|
||||
"Keymap for `magit-blob-mode'.")
|
||||
|
||||
@@ -406,11 +404,10 @@ NEWNAME may be a file or directory name. If FILE isn't tracked in
|
||||
Git, fallback to using `rename-file'."
|
||||
(interactive
|
||||
(let* ((file (magit-read-file "Rename file"))
|
||||
(dir (file-name-directory file))
|
||||
(newname (read-file-name (format "Move %s to destination: " file)
|
||||
(and dir (expand-file-name dir)))))
|
||||
(list (expand-file-name file (magit-toplevel))
|
||||
(expand-file-name newname))))
|
||||
(path (expand-file-name file (magit-toplevel))))
|
||||
(list path (expand-file-name
|
||||
(read-file-name (format "Move %s to destination: " file)
|
||||
(file-name-directory path))))))
|
||||
(let ((oldbuf (get-file-buffer file))
|
||||
(dstdir (file-name-directory newname))
|
||||
(dstfile (if (directory-name-p newname)
|
||||
@@ -501,6 +498,15 @@ Git, then fallback to using `delete-file'."
|
||||
(defun magit-read-tracked-file (prompt)
|
||||
(magit-read-file prompt t))
|
||||
|
||||
(defun magit-read-unmerged-file (&optional prompt)
|
||||
(let ((current (magit-current-file))
|
||||
(unmerged (magit-unmerged-files)))
|
||||
(unless unmerged
|
||||
(user-error "There are no unresolved conflicts"))
|
||||
(magit-completing-read (or prompt "Resolve file")
|
||||
unmerged nil t nil nil
|
||||
(car (member current unmerged)))))
|
||||
|
||||
(defun magit-read-file-choice (prompt files &optional error default)
|
||||
"Read file from FILES.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,16 @@
|
||||
;;; magit-gitignore.el --- intentionally untracked files -*- lexical-binding: t -*-
|
||||
;;; magit-gitignore.el --- Intentionally untracked files -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -121,7 +118,7 @@ Rules that are defined in that file affect all local repositories."
|
||||
(delete-dups
|
||||
(--mapcat
|
||||
(cons (concat "/" it)
|
||||
(when-let ((ext (file-name-extension it)))
|
||||
(and-let* ((ext (file-name-extension it)))
|
||||
(list (concat "/" (file-name-directory it) "*." ext)
|
||||
(concat "*." ext))))
|
||||
(sort (nconc
|
||||
|
||||
@@ -1,253 +0,0 @@
|
||||
;;; magit-imenu.el --- Integrate Imenu in magit major modes -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
|
||||
;; Author: Damien Cassou <damien@cassou.me>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Emacs' major modes can facilitate navigation in their buffers by
|
||||
;; supporting Imenu. In such major modes, launching Imenu (M-x imenu)
|
||||
;; makes Emacs display a list of items (e.g., function definitions in
|
||||
;; a programming major mode). Selecting an item from this list moves
|
||||
;; point to this item.
|
||||
|
||||
;; magit-imenu.el adds Imenu support to every major mode in Magit.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit)
|
||||
(require 'git-rebase)
|
||||
|
||||
;;; Core
|
||||
|
||||
(defun magit-imenu--index-function (entry-types menu-types)
|
||||
"Return an alist of imenu entries in current buffer.
|
||||
|
||||
ENTRY-TYPES is a list of section types to be selected through
|
||||
`imenu'.
|
||||
|
||||
MENU-TYPES is a list of section types containing elements of
|
||||
ENTRY-TYPES. Elements of MENU-TYPES are used to categorize
|
||||
elements of ENTRY-TYPES.
|
||||
|
||||
This function is used as a helper for functions set as
|
||||
`imenu-create-index-function'."
|
||||
;; If `which-function-mode' is active, then the create-index
|
||||
;; function is called at the time the major-mode is being enabled.
|
||||
;; Modes that derive from `magit-mode' have not populated the buffer
|
||||
;; at that time yet, so we have to abort.
|
||||
(when-let ((section (magit-current-section))
|
||||
(entries (make-hash-table :test 'equal)))
|
||||
(goto-char (point-max))
|
||||
(unless (oref section parent)
|
||||
(forward-line -1))
|
||||
(while (magit-section--backward-find
|
||||
(lambda ()
|
||||
(let* ((section (magit-current-section))
|
||||
(type (oref section type))
|
||||
(parent (oref section parent))
|
||||
(parent-type (oref parent type)))
|
||||
(and (memq type entry-types)
|
||||
(memq parent-type menu-types)))))
|
||||
(let* ((section (magit-current-section))
|
||||
(name (buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
(line-end-position)))
|
||||
(parent (oref section parent))
|
||||
(parent-title (buffer-substring-no-properties
|
||||
(oref parent start)
|
||||
(1- (oref parent content)))))
|
||||
(when (string-match " ([0-9]*)\\'" parent-title)
|
||||
(setq parent-title (substring parent-title 0 (match-beginning 0))))
|
||||
(puthash parent-title
|
||||
(cons (cons name (point))
|
||||
(gethash parent-title entries (list)))
|
||||
entries)))
|
||||
(mapcar (lambda (menu-title)
|
||||
(cons menu-title (gethash menu-title entries)))
|
||||
(hash-table-keys entries))))
|
||||
|
||||
;;; Log mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--log-prev-index-position-function ()
|
||||
"Move point to previous line in current buffer.
|
||||
This function is used as a value for
|
||||
`imenu-prev-index-position-function'."
|
||||
(magit-section--backward-find
|
||||
(lambda ()
|
||||
(-contains-p '(commit stash)
|
||||
(oref (magit-current-section) type)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--log-extract-index-name-function ()
|
||||
"Return imenu name for line at point.
|
||||
This function is used as a value for
|
||||
`imenu-extract-index-name-function'. Point should be at the
|
||||
beginning of the line."
|
||||
(save-match-data
|
||||
(looking-at "\\([^ ]+\\)[ *|]+\\(.+\\)$")
|
||||
(format "%s: %s"
|
||||
(match-string-no-properties 1)
|
||||
(match-string-no-properties 2))))
|
||||
|
||||
;;; Diff mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--diff-prev-index-position-function ()
|
||||
"Move point to previous file line in current buffer.
|
||||
This function is used as a value for
|
||||
`imenu-prev-index-position-function'."
|
||||
(magit-section--backward-find
|
||||
(lambda ()
|
||||
(let ((section (magit-current-section)))
|
||||
(and (magit-file-section-p section)
|
||||
(not (equal (oref (oref section parent) type)
|
||||
'diffstat)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--diff-extract-index-name-function ()
|
||||
"Return imenu name for line at point.
|
||||
This function is used as a value for
|
||||
`imenu-extract-index-name-function'. Point should be at the
|
||||
beginning of the line."
|
||||
(buffer-substring-no-properties (line-beginning-position)
|
||||
(line-end-position)))
|
||||
|
||||
;;; Status mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--status-create-index-function ()
|
||||
"Return an alist of all imenu entries in current buffer.
|
||||
This function is used as a value for
|
||||
`imenu-create-index-function'."
|
||||
(magit-imenu--index-function
|
||||
'(file commit stash pullreq issue)
|
||||
'(unpushed unstaged unpulled untracked staged stashes pullreqs issues)))
|
||||
|
||||
;;; Refs mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--refs-create-index-function ()
|
||||
"Return an alist of all imenu entries in current buffer.
|
||||
This function is used as a value for
|
||||
`imenu-create-index-function'."
|
||||
(magit-imenu--index-function
|
||||
'(branch commit tag)
|
||||
'(local remote tags)))
|
||||
|
||||
;;; Cherry mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--cherry-create-index-function ()
|
||||
"Return an alist of all imenu entries in current buffer.
|
||||
This function is used as a value for
|
||||
`imenu-create-index-function'."
|
||||
(magit-imenu--index-function
|
||||
'(commit)
|
||||
'(cherries)))
|
||||
|
||||
;;; Submodule list mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--submodule-prev-index-position-function ()
|
||||
"Move point to previous line in magit-submodule-list buffer.
|
||||
This function is used as a value for
|
||||
`imenu-prev-index-position-function'."
|
||||
(unless (bobp)
|
||||
(forward-line -1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--submodule-extract-index-name-function ()
|
||||
"Return imenu name for line at point.
|
||||
This function is used as a value for
|
||||
`imenu-extract-index-name-function'. Point should be at the
|
||||
beginning of the line."
|
||||
(elt (tabulated-list-get-entry) 0))
|
||||
|
||||
;;; Repolist mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--repolist-prev-index-position-function ()
|
||||
"Move point to previous line in magit-repolist buffer.
|
||||
This function is used as a value for
|
||||
`imenu-prev-index-position-function'."
|
||||
(unless (bobp)
|
||||
(forward-line -1)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--repolist-extract-index-name-function ()
|
||||
"Return imenu name for line at point.
|
||||
This function is used as a value for
|
||||
`imenu-extract-index-name-function'. Point should be at the
|
||||
beginning of the line."
|
||||
(let ((entry (tabulated-list-get-entry)))
|
||||
(format "%s (%s)"
|
||||
(elt entry 0)
|
||||
(elt entry (1- (length entry))))))
|
||||
|
||||
;;; Process mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--process-prev-index-position-function ()
|
||||
"Move point to previous process in magit-process buffer.
|
||||
This function is used as a value for
|
||||
`imenu-prev-index-position-function'."
|
||||
(magit-section--backward-find
|
||||
(lambda ()
|
||||
(eq (oref (magit-current-section) type) 'process))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--process-extract-index-name-function ()
|
||||
"Return imenu name for line at point.
|
||||
This function is used as a value for
|
||||
`imenu-extract-index-name-function'. Point should be at the
|
||||
beginning of the line."
|
||||
(buffer-substring-no-properties (line-beginning-position)
|
||||
(line-end-position)))
|
||||
|
||||
;;; Rebase mode
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--rebase-prev-index-position-function ()
|
||||
"Move point to previous commit in git-rebase buffer.
|
||||
This function is used as a value for
|
||||
`imenu-prev-index-position-function'."
|
||||
(catch 'found
|
||||
(while (not (bobp))
|
||||
(git-rebase-backward-line)
|
||||
(when (git-rebase-line-p)
|
||||
(throw 'found t)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-imenu--rebase-extract-index-name-function ()
|
||||
"Return imenu name for line at point.
|
||||
This function is used as a value for
|
||||
`imenu-extract-index-name-function'. Point should be at the
|
||||
beginning of the line."
|
||||
(buffer-substring-no-properties (line-beginning-position)
|
||||
(line-end-position)))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-imenu)
|
||||
;;; magit-imenu.el ends here
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-log.el --- inspect Git history -*- lexical-binding: t -*-
|
||||
;;; magit-log.el --- Inspect Git history -*- lexical-binding:t; coding:utf-8 -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -35,6 +32,7 @@
|
||||
(require 'magit-diff)
|
||||
|
||||
(declare-function magit-blob-visit "magit-files" (blob-or-file))
|
||||
(declare-function magit-cherry-apply "magit-sequence" (commit &optional args))
|
||||
(declare-function magit-insert-head-branch-header "magit-status"
|
||||
(&optional branch))
|
||||
(declare-function magit-insert-upstream-branch-header "magit-status"
|
||||
@@ -116,7 +114,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
|
||||
:group 'magit-log
|
||||
:group 'magit-margin
|
||||
:type magit-log-margin--custom-type
|
||||
:initialize 'magit-custom-initialize-reset
|
||||
:initialize #'magit-custom-initialize-reset
|
||||
:set (apply-partially #'magit-margin-set-variable 'magit-log-mode))
|
||||
|
||||
(defcustom magit-log-margin-show-committer-date nil
|
||||
@@ -144,7 +142,7 @@ This is useful if you use really long branch names."
|
||||
:group 'magit-log
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom magit-log-header-line-function 'magit-log-header-line-sentence
|
||||
(defcustom magit-log-header-line-function #'magit-log-header-line-sentence
|
||||
"Function used to generate text shown in header line of log buffers."
|
||||
:package-version '(magit . "2.12.0")
|
||||
:group 'magit-log
|
||||
@@ -152,7 +150,7 @@ This is useful if you use really long branch names."
|
||||
(function-item magit-log-header-line-sentence)
|
||||
function))
|
||||
|
||||
(defcustom magit-log-trace-definition-function 'magit-which-function
|
||||
(defcustom magit-log-trace-definition-function #'magit-which-function
|
||||
"Function used to determine the function at point.
|
||||
This is used by the command `magit-log-trace-definition'.
|
||||
You should prefer `magit-which-function' over `which-function'
|
||||
@@ -248,7 +246,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
|
||||
:group 'magit-log
|
||||
:group 'magit-margin
|
||||
:type magit-log-margin--custom-type
|
||||
:initialize 'magit-custom-initialize-reset
|
||||
:initialize #'magit-custom-initialize-reset
|
||||
:set-after '(magit-log-margin)
|
||||
:set (apply-partially #'magit-margin-set-variable 'magit-log-select-mode))
|
||||
|
||||
@@ -288,7 +286,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
|
||||
:group 'magit-log
|
||||
:group 'magit-margin
|
||||
:type magit-log-margin--custom-type
|
||||
:initialize 'magit-custom-initialize-reset
|
||||
:initialize #'magit-custom-initialize-reset
|
||||
:set-after '(magit-log-margin)
|
||||
:set (apply-partially #'magit-margin-set-variable 'magit-cherry-mode))
|
||||
|
||||
@@ -303,6 +301,14 @@ the upstream isn't ahead of the current branch) show."
|
||||
:group 'magit-status
|
||||
:type 'number)
|
||||
|
||||
(defcustom magit-log-merged-commit-count 20
|
||||
"How many surrounding commits to show for `magit-log-merged'.
|
||||
`magit-log-merged' will shows approximately half of this number
|
||||
commits before and half after."
|
||||
:package-version '(magit . "3.3.0")
|
||||
:group 'magit-log
|
||||
:type 'integer)
|
||||
|
||||
;;; Arguments
|
||||
;;;; Prefix Classes
|
||||
|
||||
@@ -455,8 +461,8 @@ the upstream isn't ahead of the current branch) show."
|
||||
("H" "HEAD" magit-reflog-head)
|
||||
("O" "other" magit-reflog-other)]
|
||||
[:if (lambda ()
|
||||
(require 'magit-wip)
|
||||
(magit--any-wip-mode-enabled-p))
|
||||
(and (fboundp 'magit--any-wip-mode-enabled-p)
|
||||
(magit--any-wip-mode-enabled-p)))
|
||||
:description "Wiplog"
|
||||
("i" "index" magit-wip-log-index)
|
||||
("w" "worktree" magit-wip-log-worktree)]
|
||||
@@ -511,8 +517,8 @@ the upstream isn't ahead of the current branch) show."
|
||||
("s" "buffer and set defaults" transient-set :transient nil)
|
||||
("w" "buffer and save defaults" transient-save :transient nil)]
|
||||
["Margin"
|
||||
("L" "toggle visibility" magit-toggle-margin)
|
||||
("l" "cycle style" magit-cycle-margin-style)
|
||||
("L" "toggle visibility" magit-toggle-margin :transient t)
|
||||
("l" "cycle style" magit-cycle-margin-style :transient t)
|
||||
("d" "toggle details" magit-toggle-margin-details)
|
||||
("x" "toggle shortstat" magit-toggle-log-margin-style)]
|
||||
[:if-mode magit-log-mode
|
||||
@@ -522,9 +528,9 @@ the upstream isn't ahead of the current branch) show."
|
||||
(cond
|
||||
((not (eq transient-current-command 'magit-log-refresh))
|
||||
(pcase major-mode
|
||||
(`magit-reflog-mode
|
||||
('magit-reflog-mode
|
||||
(user-error "Cannot change log arguments in reflog buffers"))
|
||||
(`magit-cherry-mode
|
||||
('magit-cherry-mode
|
||||
(user-error "Cannot change log arguments in cherry buffers")))
|
||||
(transient-setup 'magit-log-refresh))
|
||||
(t
|
||||
@@ -544,28 +550,28 @@ the upstream isn't ahead of the current branch) show."
|
||||
;; long argument ("--max-count").
|
||||
:shortarg "-n"
|
||||
:argument "-n"
|
||||
:reader 'transient-read-number-N+)
|
||||
:reader #'transient-read-number-N+)
|
||||
|
||||
(transient-define-argument magit:--author ()
|
||||
:description "Limit to author"
|
||||
:class 'transient-option
|
||||
:key "-A"
|
||||
:argument "--author="
|
||||
:reader 'magit-transient-read-person)
|
||||
:reader #'magit-transient-read-person)
|
||||
|
||||
(transient-define-argument magit-log:--since ()
|
||||
:description "Limit to commits since"
|
||||
:class 'transient-option
|
||||
:key "=s"
|
||||
:argument "--since="
|
||||
:reader 'transient-read-date)
|
||||
:reader #'transient-read-date)
|
||||
|
||||
(transient-define-argument magit-log:--until ()
|
||||
:description "Limit to commits until"
|
||||
:class 'transient-option
|
||||
:key "=u"
|
||||
:argument "--until="
|
||||
:reader 'transient-read-date)
|
||||
:reader #'transient-read-date)
|
||||
|
||||
(transient-define-argument magit-log:--*-order ()
|
||||
:description "Order commits by"
|
||||
@@ -595,7 +601,7 @@ the upstream isn't ahead of the current branch) show."
|
||||
:description "Trace line evolution"
|
||||
:class 'transient-option
|
||||
:argument "-L"
|
||||
:reader 'magit-read-file-trace)
|
||||
:reader #'magit-read-file-trace)
|
||||
|
||||
(defun magit-read-file-trace (&rest _ignored)
|
||||
(let ((file (magit-read-file-from-rev "HEAD" "File"))
|
||||
@@ -607,11 +613,11 @@ the upstream isn't ahead of the current branch) show."
|
||||
(defvar magit-log-read-revs-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map crm-local-completion-map)
|
||||
(define-key map "\s" 'self-insert-command)
|
||||
(define-key map "\s" #'self-insert-command)
|
||||
map))
|
||||
|
||||
(defun magit-log-read-revs (&optional use-current)
|
||||
(or (and use-current (--when-let (magit-get-current-branch) (list it)))
|
||||
(or (and use-current (and-let* ((buf (magit-get-current-branch))) (list buf)))
|
||||
(let ((crm-separator "\\(\\.\\.\\.?\\|[, ]\\)")
|
||||
(crm-local-completion-map magit-log-read-revs-map))
|
||||
(split-string (magit-completing-read-multiple*
|
||||
@@ -760,7 +766,7 @@ restrict the log to the lines that the region touches."
|
||||
beg end)
|
||||
(setq args (cons (format "-L%s,%s:%s" beg end file)
|
||||
(cl-delete "-L" args :test
|
||||
'string-prefix-p)))
|
||||
#'string-prefix-p)))
|
||||
(setq file nil))
|
||||
args)
|
||||
(and file (list file))
|
||||
@@ -781,7 +787,7 @@ restrict the log to the lines that the region touches."
|
||||
(magit-log-setup-buffer
|
||||
(list rev)
|
||||
(cons (format "-L:%s%s:%s"
|
||||
(replace-regexp-in-string ":" "\\:" (regexp-quote fn) nil t)
|
||||
(string-replace ":" "\\:" (regexp-quote fn))
|
||||
(if (derived-mode-p 'lisp-mode 'emacs-lisp-mode)
|
||||
;; Git doesn't treat "-" the same way as
|
||||
;; "_", leading to false-positives such as
|
||||
@@ -794,7 +800,7 @@ restrict the log to the lines that the region touches."
|
||||
"")
|
||||
file)
|
||||
(cl-delete "-L" (car (magit-log-arguments))
|
||||
:test 'string-prefix-p))
|
||||
:test #'string-prefix-p))
|
||||
nil magit-log-buffer-file-locked))
|
||||
|
||||
(defun magit-diff-trace-definition ()
|
||||
@@ -809,9 +815,9 @@ restrict the log to the lines that the region touches."
|
||||
"Show log for the merge of COMMIT into BRANCH.
|
||||
|
||||
More precisely, find merge commit M that brought COMMIT into
|
||||
BRANCH, and show the log of the range \"M^1..M\". If COMMIT is
|
||||
directly on BRANCH, then show approximately twenty surrounding
|
||||
commits instead.
|
||||
BRANCH, and show the log of the range \"M^1..M\". If COMMIT is
|
||||
directly on BRANCH, then show approximately
|
||||
`magit-log-merged-commit-count' surrounding commits instead.
|
||||
|
||||
This command requires git-when-merged, which is available from
|
||||
https://github.com/mhagger/git-when-merged."
|
||||
@@ -820,7 +826,7 @@ https://github.com/mhagger/git-when-merged."
|
||||
(list commit
|
||||
(magit-read-other-branch "Merged into" commit)))
|
||||
(magit-log-arguments)))
|
||||
(unless (executable-find "git-when-merged")
|
||||
(unless (magit-git-executable-find "git-when-merged")
|
||||
(user-error "This command requires git-when-merged (%s)"
|
||||
"https://github.com/mhagger/git-when-merged"))
|
||||
(let (exit m)
|
||||
@@ -833,10 +839,14 @@ https://github.com/mhagger/git-when-merged."
|
||||
(if (zerop exit)
|
||||
(magit-log-setup-buffer (list (format "%s^1..%s" m m))
|
||||
args files nil commit)
|
||||
;; Output: "<ref><lots of spaces><message>".
|
||||
;; This is not the same as `string-trim'.
|
||||
(setq m (string-trim-left (substring m (string-match " " m))))
|
||||
(if (equal m "Commit is directly on this branch.")
|
||||
(let* ((from (concat commit "~10"))
|
||||
(to (- (car (magit-rev-diff-count branch commit)) 10))
|
||||
(let* ((from (format "%s~%d" commit
|
||||
(/ magit-log-merged-commit-count 2)))
|
||||
(to (- (car (magit-rev-diff-count branch commit))
|
||||
(/ magit-log-merged-commit-count 2)))
|
||||
(to (if (<= to 0)
|
||||
branch
|
||||
(format "%s~%s" branch to))))
|
||||
@@ -881,9 +891,9 @@ limit. Otherwise set it to 256."
|
||||
(magit-refresh))
|
||||
|
||||
(defun magit-log-get-commit-limit ()
|
||||
(--when-let (--first (string-match "^-n\\([0-9]+\\)?$" it)
|
||||
magit-buffer-log-args)
|
||||
(string-to-number (match-string 1 it))))
|
||||
(and-let* ((str (--first (string-match "^-n\\([0-9]+\\)?$" it)
|
||||
magit-buffer-log-args)))
|
||||
(string-to-number (match-string 1 str))))
|
||||
|
||||
;;;; Mode Commands
|
||||
|
||||
@@ -935,7 +945,7 @@ of the current repository first; creating it if necessary."
|
||||
(with-current-buffer
|
||||
(cond ((derived-mode-p 'magit-log-mode)
|
||||
(current-buffer))
|
||||
((when-let ((buf (magit-get-mode-buffer 'magit-log-mode)))
|
||||
((and-let* ((buf (magit-get-mode-buffer 'magit-log-mode)))
|
||||
(pop-to-buffer-same-window buf)))
|
||||
(t
|
||||
(apply #'magit-log-all-branches (magit-log-arguments))))
|
||||
@@ -997,14 +1007,14 @@ of the current repository first; creating it if necessary."
|
||||
(defvar magit-log-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map magit-mode-map)
|
||||
(define-key map (kbd "C-c C-b") 'magit-go-backward)
|
||||
(define-key map (kbd "C-c C-f") 'magit-go-forward)
|
||||
(define-key map (kbd "C-c C-n") 'magit-log-move-to-parent)
|
||||
(define-key map "j" 'magit-log-move-to-revision)
|
||||
(define-key map "=" 'magit-log-toggle-commit-limit)
|
||||
(define-key map "+" 'magit-log-double-commit-limit)
|
||||
(define-key map "-" 'magit-log-half-commit-limit)
|
||||
(define-key map "q" 'magit-log-bury-buffer)
|
||||
(define-key map (kbd "C-c C-b") #'magit-go-backward)
|
||||
(define-key map (kbd "C-c C-f") #'magit-go-forward)
|
||||
(define-key map (kbd "C-c C-n") #'magit-log-move-to-parent)
|
||||
(define-key map "j" #'magit-log-move-to-revision)
|
||||
(define-key map "=" #'magit-log-toggle-commit-limit)
|
||||
(define-key map "+" #'magit-log-double-commit-limit)
|
||||
(define-key map "-" #'magit-log-half-commit-limit)
|
||||
(define-key map "q" #'magit-log-bury-buffer)
|
||||
map)
|
||||
"Keymap for `magit-log-mode'.")
|
||||
|
||||
@@ -1026,10 +1036,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
\\{magit-log-mode-map}"
|
||||
:group 'magit-log
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(setq imenu-prev-index-position-function
|
||||
'magit-imenu--log-prev-index-position-function)
|
||||
(setq imenu-extract-index-name-function
|
||||
'magit-imenu--log-extract-index-name-function))
|
||||
(setq magit--imenu-item-types 'commit))
|
||||
|
||||
(put 'magit-log-mode 'magit-log-default-arguments
|
||||
'("--graph" "-n256" "--decorate"))
|
||||
@@ -1053,7 +1060,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
(files magit-buffer-log-files))
|
||||
(magit-set-header-line-format
|
||||
(funcall magit-log-header-line-function revs args files))
|
||||
(unless (= (length files) 1)
|
||||
(unless (length= files 1)
|
||||
(setq args (remove "--follow" args)))
|
||||
(when (and (car magit-log-remove-graph-args)
|
||||
(--any-p (string-match-p
|
||||
@@ -1062,19 +1069,20 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
(setq args (remove "--graph" args)))
|
||||
(unless (member "--graph" args)
|
||||
(setq args (remove "--color" args)))
|
||||
(when-let ((limit (magit-log-get-commit-limit))
|
||||
(limit (* 2 limit)) ; increase odds for complete graph
|
||||
(count (and (= (length revs) 1)
|
||||
(> limit 1024) ; otherwise it's fast enough
|
||||
(setq revs (car revs))
|
||||
(not (string-match-p "\\.\\." revs))
|
||||
(not (member revs '("--all" "--branches")))
|
||||
(-none-p (lambda (arg)
|
||||
(--any-p (string-prefix-p it arg)
|
||||
magit-log-disable-graph-hack-args))
|
||||
args)
|
||||
(magit-git-string "rev-list" "--count"
|
||||
"--first-parent" args revs))))
|
||||
(when-let* ((limit (magit-log-get-commit-limit))
|
||||
(limit (* 2 limit)) ; increase odds for complete graph
|
||||
(count (and (length= revs 1)
|
||||
(> limit 1024) ; otherwise it's fast enough
|
||||
(setq revs (car revs))
|
||||
(not (string-search ".." revs))
|
||||
(not (member revs '("--all" "--branches")))
|
||||
(-none-p (lambda (arg)
|
||||
(--any-p
|
||||
(string-prefix-p it arg)
|
||||
magit-log-disable-graph-hack-args))
|
||||
args)
|
||||
(magit-git-string "rev-list" "--count"
|
||||
"--first-parent" args revs))))
|
||||
(setq revs (if (< (string-to-number count) limit)
|
||||
revs
|
||||
(format "%s~%s..%s" revs limit revs))))
|
||||
@@ -1090,7 +1098,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
(defun magit-log-header-line-arguments (revs args files)
|
||||
"Return string describing some of the used arguments."
|
||||
(mapconcat (lambda (arg)
|
||||
(if (string-match-p " " arg)
|
||||
(if (string-search " " arg)
|
||||
(prin1 arg)
|
||||
arg))
|
||||
`("git" "log" ,@args ,@revs "--" ,@files)
|
||||
@@ -1103,7 +1111,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
(and (member "--reverse" args)
|
||||
" in reverse")
|
||||
(and files (concat " touching "
|
||||
(mapconcat 'identity files " ")))
|
||||
(mapconcat #'identity files " ")))
|
||||
(--some (and (string-prefix-p "-L" it)
|
||||
(concat " " it))
|
||||
args)))
|
||||
@@ -1142,16 +1150,28 @@ Do not add this to a hook variable."
|
||||
args)
|
||||
"--use-mailmap" "--no-prefix" revs "--" files)))
|
||||
|
||||
(cl-defmethod magit-menu-common-value ((_section magit-commit-section))
|
||||
(or (magit-diff--region-range)
|
||||
(oref (magit-current-section) value)))
|
||||
|
||||
(defvar magit-commit-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-show-commit)
|
||||
(define-key map "a" 'magit-cherry-apply)
|
||||
;; The second remapping overrides the first but we still get two menu
|
||||
;; items, though only one of them will be available at any given time.
|
||||
(magit-menu-set map [magit-visit-thing]
|
||||
#'magit-diff-range "Diff %x"
|
||||
'(:visible (region-active-p)))
|
||||
(magit-menu-set map [magit-visit-thing]
|
||||
#'magit-show-commit "Show commit %x"
|
||||
'(:visible (not (region-active-p))))
|
||||
(magit-menu-set map [magit-cherry-apply]
|
||||
#'magit-cherry-apply "Apply %x")
|
||||
map)
|
||||
"Keymap for `commit' sections.")
|
||||
|
||||
(defvar magit-module-commit-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-show-commit)
|
||||
(set-keymap-parent map magit-commit-section-map)
|
||||
map)
|
||||
"Keymap for `module-commit' sections.")
|
||||
|
||||
@@ -1161,7 +1181,7 @@ Do not add this to a hook variable."
|
||||
;; ++header is used.
|
||||
(concat "^"
|
||||
"\\(?4:[-_/|\\*o<>. ]*\\)" ; graph
|
||||
"\\(?1:[0-9a-fA-F]+\\)?" ; sha1
|
||||
"\\(?1:[0-9a-fA-F]+\\)?" ; hash
|
||||
"\\(?3:[^\n]+\\)?" ; refs
|
||||
"\\(?7:[BGUXYREN]\\)?" ; gpg
|
||||
"\\(?5:[^\n]*\\)" ; author
|
||||
@@ -1173,34 +1193,35 @@ Do not add this to a hook variable."
|
||||
(defconst magit-log-cherry-re
|
||||
(concat "^"
|
||||
"\\(?8:[-+]\\) " ; cherry
|
||||
"\\(?1:[0-9a-fA-F]+\\) " ; sha1
|
||||
"\\(?1:[0-9a-fA-F]+\\) " ; hash
|
||||
"\\(?2:.*\\)$")) ; msg
|
||||
|
||||
(defconst magit-log-module-re
|
||||
(concat "^"
|
||||
"\\(?:\\(?11:[<>]\\) \\)?" ; side
|
||||
"\\(?1:[0-9a-fA-F]+\\) " ; sha1
|
||||
"\\(?1:[0-9a-fA-F]+\\) " ; hash
|
||||
"\\(?2:.*\\)$")) ; msg
|
||||
|
||||
(defconst magit-log-bisect-vis-re
|
||||
(concat "^"
|
||||
"\\(?4:[-_/|\\*o<>. ]*\\)" ; graph
|
||||
"\\(?1:[0-9a-fA-F]+\\)?\0" ; sha1
|
||||
"\\(?1:[0-9a-fA-F]+\\)?\0" ; hash
|
||||
"\\(?3:[^\0\n]+\\)?\0" ; refs
|
||||
"\\(?2:.*\\)$")) ; msg
|
||||
|
||||
(defconst magit-log-bisect-log-re
|
||||
(concat "^# "
|
||||
"\\(?3:[^: \n]+:\\) " ; "refs"
|
||||
"\\[\\(?1:[^]\n]+\\)\\] " ; sha1
|
||||
"\\[\\(?1:[^]\n]+\\)\\] " ; hash
|
||||
"\\(?2:.*\\)$")) ; msg
|
||||
|
||||
(defconst magit-log-reflog-re
|
||||
(concat "^"
|
||||
"\\(?1:[^\0\n]+\\)\0" ; sha1
|
||||
"\\(?1:[^\0\n]+\\)\0" ; hash
|
||||
"\\(?5:[^\0\n]*\\)\0" ; author
|
||||
"\\(?:\\(?:[^@\n]+@{\\(?6:[^}\n]+\\)}\0" ; date
|
||||
"\\(?10:merge \\|autosave \\|restart \\|[^:\n]+: \\)?" ; refsub
|
||||
;;; refsub
|
||||
"\\(?10:merge \\|autosave \\|restart \\|rewritten \\|[^:\n]+: \\)?"
|
||||
"\\(?2:.*\\)?\\)\\|\0\\)$")) ; msg
|
||||
|
||||
(defconst magit-reflog-subject-re
|
||||
@@ -1210,17 +1231,17 @@ Do not add this to a hook variable."
|
||||
|
||||
(defconst magit-log-stash-re
|
||||
(concat "^"
|
||||
"\\(?1:[^\0\n]+\\)\0" ; "sha1"
|
||||
"\\(?1:[^\0\n]+\\)\0" ; "hash"
|
||||
"\\(?5:[^\0\n]*\\)\0" ; author
|
||||
"\\(?6:[^\0\n]+\\)\0" ; date
|
||||
"\\(?2:.*\\)$")) ; msg
|
||||
|
||||
(defvar magit-log-count nil)
|
||||
|
||||
(defvar magit-log-format-message-function 'magit-log-propertize-keywords)
|
||||
(defvar magit-log-format-message-function #'magit-log-propertize-keywords)
|
||||
|
||||
(defun magit-log-wash-log (style args)
|
||||
(setq args (-flatten args))
|
||||
(setq args (flatten-tree args))
|
||||
(when (and (member "--graph" args)
|
||||
(member "--color" args))
|
||||
(let ((ansi-color-apply-face-function
|
||||
@@ -1233,7 +1254,7 @@ Do not add this to a hook variable."
|
||||
(let ((magit-log-count 0))
|
||||
(when (looking-at "^\\.\\.\\.")
|
||||
(magit-delete-line))
|
||||
(magit-wash-sequence (apply-partially 'magit-log-wash-rev style
|
||||
(magit-wash-sequence (apply-partially #'magit-log-wash-rev style
|
||||
(magit-abbrev-length)))
|
||||
(if (derived-mode-p 'magit-log-mode 'magit-reflog-mode)
|
||||
(when (eq magit-log-count (magit-log-get-commit-limit))
|
||||
@@ -1253,13 +1274,13 @@ Do not add this to a hook variable."
|
||||
(when (derived-mode-p 'magit-log-mode 'magit-reflog-mode)
|
||||
(cl-incf magit-log-count))
|
||||
(looking-at (pcase style
|
||||
(`log magit-log-heading-re)
|
||||
(`cherry magit-log-cherry-re)
|
||||
(`module magit-log-module-re)
|
||||
(`reflog magit-log-reflog-re)
|
||||
(`stash magit-log-stash-re)
|
||||
(`bisect-vis magit-log-bisect-vis-re)
|
||||
(`bisect-log magit-log-bisect-log-re)))
|
||||
('log magit-log-heading-re)
|
||||
('cherry magit-log-cherry-re)
|
||||
('module magit-log-module-re)
|
||||
('reflog magit-log-reflog-re)
|
||||
('stash magit-log-stash-re)
|
||||
('bisect-vis magit-log-bisect-vis-re)
|
||||
('bisect-log magit-log-bisect-log-re)))
|
||||
(magit-bind-match-strings
|
||||
(hash msg refs graph author date gpg cherry _ refsub side) nil
|
||||
(setq msg (substring-no-properties msg))
|
||||
@@ -1278,9 +1299,9 @@ Do not add this to a hook variable."
|
||||
(cl-return-from magit-log-wash-rev t))
|
||||
(magit-insert-section section (commit hash)
|
||||
(pcase style
|
||||
(`stash (oset section type 'stash))
|
||||
(`module (oset section type 'module-commit))
|
||||
(`bisect-log (setq hash (magit-rev-parse "--short" hash))))
|
||||
('stash (oset section type 'stash))
|
||||
('module (oset section type 'module-commit))
|
||||
('bisect-log (setq hash (magit-rev-parse "--short" hash))))
|
||||
(setq hash (propertize hash 'font-lock-face
|
||||
(pcase (and gpg (aref gpg 0))
|
||||
(?G 'magit-signature-good)
|
||||
@@ -1319,7 +1340,8 @@ Do not add this to a hook variable."
|
||||
(insert (format "%-2s " (1- magit-log-count)))
|
||||
(when refsub
|
||||
(insert (magit-reflog-format-subject
|
||||
(substring refsub 0 (if (string-match-p ":" refsub) -2 -1))))))
|
||||
(substring refsub 0
|
||||
(if (string-search ":" refsub) -2 -1))))))
|
||||
(when msg
|
||||
(insert (funcall magit-log-format-message-function hash msg)))
|
||||
(when (and refs magit-log-show-refname-after-summary)
|
||||
@@ -1427,8 +1449,8 @@ If there is no revision buffer in the same frame, then do nothing."
|
||||
(add-hook 'magit-section-movement-hook #'magit-log-maybe-update-revision-buffer)
|
||||
|
||||
(defun magit--maybe-update-revision-buffer ()
|
||||
(when-let ((commit (magit-section-value-if 'commit))
|
||||
(buffer (magit-get-mode-buffer 'magit-revision-mode nil t)))
|
||||
(when-let* ((commit (magit-section-value-if 'commit))
|
||||
(buffer (magit-get-mode-buffer 'magit-revision-mode nil t)))
|
||||
(if magit--update-revision-buffer
|
||||
(setq magit--update-revision-buffer (list commit buffer))
|
||||
(setq magit--update-revision-buffer (list commit buffer))
|
||||
@@ -1453,11 +1475,11 @@ If there is no blob buffer in the same frame, then do nothing."
|
||||
(magit--maybe-update-blob-buffer)))
|
||||
|
||||
(defun magit--maybe-update-blob-buffer ()
|
||||
(when-let ((commit (magit-section-value-if 'commit))
|
||||
(buffer (--first (with-current-buffer it
|
||||
(eq revert-buffer-function
|
||||
'magit-revert-rev-file-buffer))
|
||||
(mapcar #'window-buffer (window-list)))))
|
||||
(when-let* ((commit (magit-section-value-if 'commit))
|
||||
(buffer (--first (with-current-buffer it
|
||||
(eq revert-buffer-function
|
||||
'magit-revert-rev-file-buffer))
|
||||
(mapcar #'window-buffer (window-list)))))
|
||||
(if magit--update-blob-buffer
|
||||
(setq magit--update-blob-buffer (list commit buffer))
|
||||
(setq magit--update-blob-buffer (list commit buffer))
|
||||
@@ -1574,13 +1596,13 @@ The shortstat style is experimental and rather slow."
|
||||
(defvar magit-log-select-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map magit-log-mode-map)
|
||||
(define-key map (kbd "C-c C-b") 'undefined)
|
||||
(define-key map (kbd "C-c C-f") 'undefined)
|
||||
(define-key map (kbd ".") 'magit-log-select-pick)
|
||||
(define-key map (kbd "e") 'magit-log-select-pick)
|
||||
(define-key map (kbd "C-c C-c") 'magit-log-select-pick)
|
||||
(define-key map (kbd "q") 'magit-log-select-quit)
|
||||
(define-key map (kbd "C-c C-k") 'magit-log-select-quit)
|
||||
(define-key map (kbd "C-c C-b") #'undefined)
|
||||
(define-key map (kbd "C-c C-f") #'undefined)
|
||||
(define-key map (kbd ".") #'magit-log-select-pick)
|
||||
(define-key map (kbd "e") #'magit-log-select-pick)
|
||||
(define-key map (kbd "C-c C-c") #'magit-log-select-pick)
|
||||
(define-key map (kbd "q") #'magit-log-select-quit)
|
||||
(define-key map (kbd "C-c C-k") #'magit-log-select-quit)
|
||||
map)
|
||||
"Keymap for `magit-log-select-mode'.")
|
||||
|
||||
@@ -1682,8 +1704,8 @@ Call `magit-log-select-quit-function' if set."
|
||||
(defvar magit-cherry-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map magit-mode-map)
|
||||
(define-key map "q" 'magit-log-bury-buffer)
|
||||
(define-key map "L" 'magit-margin-settings)
|
||||
(define-key map "q" #'magit-log-bury-buffer)
|
||||
(define-key map "L" #'magit-margin-settings)
|
||||
map)
|
||||
"Keymap for `magit-cherry-mode'.")
|
||||
|
||||
@@ -1700,8 +1722,7 @@ Type \\[magit-cherry-pick] to apply the commit at point.
|
||||
\\{magit-cherry-mode-map}"
|
||||
:group 'magit-log
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(setq imenu-create-index-function
|
||||
'magit-imenu--cherry-create-index-function))
|
||||
(setq magit--imenu-group-types 'cherries))
|
||||
|
||||
(defun magit-cherry-setup-buffer (head upstream)
|
||||
(magit-setup-buffer #'magit-cherry-mode nil
|
||||
@@ -1742,7 +1763,7 @@ Type \\[magit-cherry-pick] to apply the commit at point.
|
||||
"Insert commit sections into a `magit-cherry-mode' buffer."
|
||||
(magit-insert-section (cherries)
|
||||
(magit-insert-heading "Cherry commits:")
|
||||
(magit-git-wash (apply-partially 'magit-log-wash-log 'cherry)
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'cherry)
|
||||
"cherry" "-v" "--abbrev"
|
||||
magit-buffer-upstream
|
||||
magit-buffer-refname)))
|
||||
@@ -1750,12 +1771,30 @@ Type \\[magit-cherry-pick] to apply the commit at point.
|
||||
;;; Log Sections
|
||||
;;;; Standard Log Sections
|
||||
|
||||
(defvar magit-log-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(magit-menu-set map [magit-visit-thing] #'magit-diff-dwim "Visit diff")
|
||||
map)
|
||||
"Keymap for log sections.
|
||||
The classes `magit-{unpulled,unpushed,unmerged}-section' derive
|
||||
from the abstract `magit-log-section' class. Accordingly this
|
||||
keymap is the parent of their keymaps.")
|
||||
|
||||
(defvar magit-unpulled-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-diff-dwim)
|
||||
(set-keymap-parent map magit-log-section-map)
|
||||
map)
|
||||
"Keymap for `unpulled' sections.")
|
||||
|
||||
(cl-defmethod magit-section-ident-value ((section magit-unpulled-section))
|
||||
"\"..@{push}\" cannot be used as the value because that is
|
||||
ambiguous if `push.default' does not allow a 1:1 mapping, and
|
||||
many commands would fail because of that. But here that does
|
||||
not matter and we need an unique value so we use that string
|
||||
in the pushremote case."
|
||||
(let ((value (oref section value)))
|
||||
(if (equal value "..@{upstream}") value "..@{push}")))
|
||||
|
||||
(magit-define-section-jumper magit-jump-to-unpulled-from-upstream
|
||||
"Unpulled from @{upstream}" unpulled "..@{upstream}")
|
||||
|
||||
@@ -1788,10 +1827,19 @@ Type \\[magit-cherry-pick] to apply the commit at point.
|
||||
|
||||
(defvar magit-unpushed-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-diff-dwim)
|
||||
(set-keymap-parent map magit-log-section-map)
|
||||
map)
|
||||
"Keymap for `unpushed' sections.")
|
||||
|
||||
(cl-defmethod magit-section-ident-value ((section magit-unpushed-section))
|
||||
"\"..@{push}\" cannot be used as the value because that is
|
||||
ambiguous if `push.default' does not allow a 1:1 mapping, and
|
||||
many commands would fail because of that. But here that does
|
||||
not matter and we need an unique value so we use that string
|
||||
in the pushremote case."
|
||||
(let ((value (oref section value)))
|
||||
(if (equal value "@{upstream}..") value "@{push}..")))
|
||||
|
||||
(magit-define-section-jumper magit-jump-to-unpushed-to-upstream
|
||||
"Unpushed to @{upstream}" unpushed "@{upstream}..")
|
||||
|
||||
@@ -1851,7 +1899,8 @@ Show the last `magit-log-section-commit-count' commits."
|
||||
(magit-log-insert-child-count)))))
|
||||
|
||||
(defun magit--insert-pushremote-log-p ()
|
||||
(magit--with-refresh-cache 'magit--insert-pushremote-log-p
|
||||
(magit--with-refresh-cache
|
||||
(cons default-directory 'magit--insert-pushremote-log-p)
|
||||
(not (and (equal (magit-get-push-branch)
|
||||
(magit-get-upstream-branch))
|
||||
(or (memq 'magit-insert-unpulled-from-upstream
|
||||
@@ -1863,7 +1912,7 @@ Show the last `magit-log-section-commit-count' commits."
|
||||
(when magit-section-show-child-count
|
||||
(let ((count (length (oref magit-insert-section--current children))))
|
||||
(when (> count 0)
|
||||
(when (= count (magit-log-get-commit-limit))
|
||||
(when (eq count (magit-log-get-commit-limit))
|
||||
(setq count (format "%s+" count)))
|
||||
(save-excursion
|
||||
(goto-char (- (oref magit-insert-section--current content) 2))
|
||||
@@ -1881,7 +1930,7 @@ not shared with any local commit) with \"+\", and all others with
|
||||
(when (magit-git-success "rev-parse" "@{upstream}")
|
||||
(magit-insert-section (unpulled "..@{upstream}")
|
||||
(magit-insert-heading "Unpulled commits:")
|
||||
(magit-git-wash (apply-partially 'magit-log-wash-log 'cherry)
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'cherry)
|
||||
"cherry" "-v" (magit-abbrev-arg)
|
||||
(magit-get-current-branch) "@{upstream}"))))
|
||||
|
||||
@@ -1894,7 +1943,7 @@ all others with \"-\"."
|
||||
(when (magit-git-success "rev-parse" "@{upstream}")
|
||||
(magit-insert-section (unpushed "@{upstream}..")
|
||||
(magit-insert-heading "Unpushed commits:")
|
||||
(magit-git-wash (apply-partially 'magit-log-wash-log 'cherry)
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'cherry)
|
||||
"cherry" "-v" (magit-abbrev-arg) "@{upstream}"))))
|
||||
|
||||
;;; _
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-margin.el --- margins in Magit buffers -*- lexical-binding: t -*-
|
||||
;;; magit-margin.el --- Margins in Magit buffers -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -32,10 +29,12 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit-section)
|
||||
(require 'magit-base)
|
||||
(require 'magit-transient)
|
||||
(require 'magit-mode)
|
||||
|
||||
;;; Options
|
||||
|
||||
(defgroup magit-margin nil
|
||||
"Information Magit displays in the margin.
|
||||
|
||||
@@ -63,8 +62,8 @@ does not carry to other options."
|
||||
"Change what information is displayed in the margin."
|
||||
:info-manual "(magit) Log Margin"
|
||||
["Margin"
|
||||
("L" "Toggle visibility" magit-toggle-margin)
|
||||
("l" "Cycle style" magit-cycle-margin-style)
|
||||
("L" "Toggle visibility" magit-toggle-margin :transient t)
|
||||
("l" "Cycle style" magit-cycle-margin-style :transient t)
|
||||
("d" "Toggle details" magit-toggle-margin-details)
|
||||
("v" "Change verbosity" magit-refs-set-show-commit-count
|
||||
:if-derived magit-refs-mode)])
|
||||
@@ -77,6 +76,9 @@ does not carry to other options."
|
||||
(setcar magit-buffer-margin (not (magit-buffer-margin-p)))
|
||||
(magit-set-buffer-margin))
|
||||
|
||||
(defvar magit-margin-default-time-format nil
|
||||
"See https://github.com/magit/magit/pull/4605.")
|
||||
|
||||
(defun magit-cycle-margin-style ()
|
||||
"Cycle style used for the Magit margin."
|
||||
(interactive)
|
||||
@@ -85,9 +87,10 @@ does not carry to other options."
|
||||
;; This is only suitable for commit margins (there are not others).
|
||||
(setf (cadr magit-buffer-margin)
|
||||
(pcase (cadr magit-buffer-margin)
|
||||
(`age 'age-abbreviated)
|
||||
(`age-abbreviated
|
||||
(let ((default (cadr (symbol-value (magit-margin-option)))))
|
||||
('age 'age-abbreviated)
|
||||
('age-abbreviated
|
||||
(let ((default (or magit-margin-default-time-format
|
||||
(cadr (symbol-value (magit-margin-option))))))
|
||||
(if (stringp default) default "%Y-%m-%d %H:%M ")))
|
||||
(_ 'age)))
|
||||
(magit-set-buffer-margin nil t))
|
||||
@@ -108,14 +111,14 @@ does not carry to other options."
|
||||
|
||||
(defun magit-margin-option ()
|
||||
(pcase major-mode
|
||||
(`magit-cherry-mode 'magit-cherry-margin)
|
||||
(`magit-log-mode 'magit-log-margin)
|
||||
(`magit-log-select-mode 'magit-log-select-margin)
|
||||
(`magit-reflog-mode 'magit-reflog-margin)
|
||||
(`magit-refs-mode 'magit-refs-margin)
|
||||
(`magit-stashes-mode 'magit-stashes-margin)
|
||||
(`magit-status-mode 'magit-status-margin)
|
||||
(`forge-notifications-mode 'magit-status-margin)))
|
||||
('magit-cherry-mode 'magit-cherry-margin)
|
||||
('magit-log-mode 'magit-log-margin)
|
||||
('magit-log-select-mode 'magit-log-select-margin)
|
||||
('magit-reflog-mode 'magit-reflog-margin)
|
||||
('magit-refs-mode 'magit-refs-margin)
|
||||
('magit-stashes-mode 'magit-stashes-margin)
|
||||
('magit-status-mode 'magit-status-margin)
|
||||
('forge-notifications-mode 'magit-status-margin)))
|
||||
|
||||
(defun magit-set-buffer-margin (&optional reset refresh)
|
||||
(when-let ((option (magit-margin-option)))
|
||||
@@ -133,9 +136,9 @@ does not carry to other options."
|
||||
(magit-set-window-margin window)
|
||||
(if enable
|
||||
(add-hook 'window-configuration-change-hook
|
||||
'magit-set-window-margin nil t)
|
||||
#'magit-set-window-margin nil t)
|
||||
(remove-hook 'window-configuration-change-hook
|
||||
'magit-set-window-margin t))))
|
||||
#'magit-set-window-margin t))))
|
||||
(when (and enable (or refresh magit-set-buffer-margin-refresh))
|
||||
(magit-refresh-buffer))))))
|
||||
|
||||
@@ -219,14 +222,14 @@ English.")
|
||||
|
||||
(defun magit--age (date &optional abbreviate)
|
||||
(cl-labels ((fn (age spec)
|
||||
(pcase-let ((`(,char ,unit ,units ,weight) (car spec)))
|
||||
(let ((cnt (round (/ age weight 1.0))))
|
||||
(if (or (not (cdr spec))
|
||||
(>= (/ age weight) 1))
|
||||
(list cnt (cond (abbreviate char)
|
||||
((= cnt 1) unit)
|
||||
(t units)))
|
||||
(fn age (cdr spec)))))))
|
||||
(pcase-let ((`(,char ,unit ,units ,weight) (car spec)))
|
||||
(let ((cnt (round (/ age weight 1.0))))
|
||||
(if (or (not (cdr spec))
|
||||
(>= (/ age weight) 1))
|
||||
(list cnt (cond (abbreviate char)
|
||||
((= cnt 1) unit)
|
||||
(t units)))
|
||||
(fn age (cdr spec)))))))
|
||||
(fn (abs (- (float-time)
|
||||
(if (stringp date)
|
||||
(string-to-number date)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-merge.el --- merge functionality -*- lexical-binding: t -*-
|
||||
;;; magit-merge.el --- Merge functionality -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -146,7 +143,7 @@ then also remove the respective remote branch."
|
||||
(or (magit-get-current-branch)
|
||||
(magit-rev-parse "HEAD")))
|
||||
nil
|
||||
(when-let ((upstream (magit-get-upstream-branch))
|
||||
(and-let* ((upstream (magit-get-upstream-branch))
|
||||
(upstream (cdr (magit-split-branch-name upstream))))
|
||||
(and (magit-branch-p upstream) upstream)))
|
||||
(magit-merge-arguments)))
|
||||
@@ -255,7 +252,9 @@ then also remove the respective remote branch."
|
||||
(user-error "Quit")))))
|
||||
(pcase (cons arg (cddr (car (magit-file-status file))))
|
||||
((or `("--ours" ?D ,_)
|
||||
`("--theirs" ,_ ?D))
|
||||
'("--ours" ?U ?A)
|
||||
`("--theirs" ,_ ?D)
|
||||
'("--theirs" ?A ?U))
|
||||
(magit-run-git "rm" "--" file))
|
||||
(_ (if (equal arg "--merge")
|
||||
;; This fails if the file was deleted on one
|
||||
@@ -292,7 +291,7 @@ then also remove the respective remote branch."
|
||||
|
||||
(defvar magit-unmerged-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-diff-dwim)
|
||||
(set-keymap-parent map magit-log-section-map)
|
||||
map)
|
||||
"Keymap for `unmerged' sections.")
|
||||
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-mode.el --- create and refresh Magit buffers -*- lexical-binding: t -*-
|
||||
;;; magit-mode.el --- Create and refresh Magit buffers -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -31,30 +28,13 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit-section)
|
||||
(require 'magit-base)
|
||||
(require 'magit-git)
|
||||
|
||||
(require 'format-spec)
|
||||
(require 'help-mode)
|
||||
(require 'transient)
|
||||
|
||||
;; For `magit-display-buffer-fullcolumn-most-v1' from `git-commit'
|
||||
(defvar git-commit-mode)
|
||||
;; For `magit-refresh'
|
||||
(defvar magit-post-commit-hook-commands)
|
||||
(defvar magit-post-stage-hook-commands)
|
||||
(defvar magit-post-unstage-hook-commands)
|
||||
;; For `magit-refresh' and `magit-refresh-all'
|
||||
(declare-function magit-auto-revert-buffers "magit-autorevert" ())
|
||||
;; For `magit-refresh-buffer'
|
||||
(declare-function magit-process-unset-mode-line-error-status "magit-process" ())
|
||||
;; For `magit-refresh-get-relative-position'
|
||||
(declare-function magit-hunk-section-p "magit-diff" (section) t)
|
||||
;; For `magit-mode-setup-internal'
|
||||
(declare-function magit-status-goto-initial-section "magit-status" ())
|
||||
;; For `magit-mode' from `bookmark'
|
||||
(defvar bookmark-make-record-function)
|
||||
|
||||
;;; Options
|
||||
|
||||
(defcustom magit-mode-hook
|
||||
@@ -96,7 +76,11 @@ inside your function."
|
||||
:type 'hook
|
||||
:options '(magit-maybe-save-repository-buffers))
|
||||
|
||||
(defcustom magit-post-refresh-hook nil
|
||||
(defcustom magit-post-refresh-hook
|
||||
'(magit-auto-revert-buffers
|
||||
magit-run-post-commit-hook
|
||||
magit-run-post-stage-hook
|
||||
magit-run-post-unstage-hook)
|
||||
"Hook run after refreshing in `magit-refresh'.
|
||||
|
||||
This hook, or `magit-pre-refresh-hook', should be used
|
||||
@@ -107,9 +91,13 @@ To run a function with a particular buffer current, use
|
||||
inside your function."
|
||||
:package-version '(magit . "2.4.0")
|
||||
:group 'magit-refresh
|
||||
:type 'hook)
|
||||
:type 'hook
|
||||
:options '(magit-auto-revert-buffers
|
||||
magit-run-post-commit-hook
|
||||
magit-run-post-stage-hook
|
||||
magit-run-post-unstage-hook))
|
||||
|
||||
(defcustom magit-display-buffer-function 'magit-display-buffer-traditional
|
||||
(defcustom magit-display-buffer-function #'magit-display-buffer-traditional
|
||||
"The function used to display a Magit buffer.
|
||||
|
||||
All Magit buffers (buffers whose major-modes derive from
|
||||
@@ -130,7 +118,7 @@ which in turn uses the function specified here."
|
||||
:package-version '(magit . "2.3.0")
|
||||
:group 'magit-buffers
|
||||
:type 'hook
|
||||
:get 'magit-hook-custom-get
|
||||
:get #'magit-hook-custom-get
|
||||
:options '(magit-save-window-configuration))
|
||||
|
||||
(defcustom magit-post-display-buffer-hook '(magit-maybe-set-dedicated)
|
||||
@@ -138,11 +126,11 @@ which in turn uses the function specified here."
|
||||
:package-version '(magit . "2.3.0")
|
||||
:group 'magit-buffers
|
||||
:type 'hook
|
||||
:get 'magit-hook-custom-get
|
||||
:get #'magit-hook-custom-get
|
||||
:options '(magit-maybe-set-dedicated))
|
||||
|
||||
(defcustom magit-generate-buffer-name-function
|
||||
'magit-generate-buffer-name-default-function
|
||||
#'magit-generate-buffer-name-default-function
|
||||
"The function used to generate the name for a Magit buffer."
|
||||
:package-version '(magit . "2.3.0")
|
||||
:group 'magit-buffers
|
||||
@@ -197,7 +185,7 @@ support additional %-sequences."
|
||||
:group 'magit-buffers
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom magit-bury-buffer-function 'magit-mode-quit-window
|
||||
(defcustom magit-bury-buffer-function #'magit-mode-quit-window
|
||||
"The function used to bury or kill the current Magit buffer."
|
||||
:package-version '(magit . "3.2.0")
|
||||
:group 'magit-buffers
|
||||
@@ -336,6 +324,7 @@ recommended value."
|
||||
(defvar magit-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map magit-section-mode-map)
|
||||
;; Don't function-quote but make sure all commands are autoloaded.
|
||||
(define-key map [C-return] 'magit-visit-thing)
|
||||
(define-key map (kbd "RET") 'magit-visit-thing)
|
||||
(define-key map (kbd "M-TAB") 'magit-dired-jump)
|
||||
@@ -449,7 +438,8 @@ which visits the thing at point using `browse-url'."
|
||||
(interactive)
|
||||
(user-error "There is no thing at point that could be browsed"))
|
||||
|
||||
(defun magit-help ()
|
||||
;;;###autoload
|
||||
(defun magit-info ()
|
||||
"Visit the Magit manual."
|
||||
(interactive)
|
||||
(info "magit"))
|
||||
@@ -461,53 +451,62 @@ which visits the thing at point using `browse-url'."
|
||||
|
||||
(easy-menu-define magit-mode-menu magit-mode-map
|
||||
"Magit menu"
|
||||
;; Similar to `magit-dispatch' but exclude:
|
||||
;; - commands that are available from context menus:
|
||||
;; apply, reverse, discard, stage, unstage,
|
||||
;; cherry-pick, revert, reset,
|
||||
;; describe-section
|
||||
;; - commands that are available from submenus:
|
||||
;; git-command, ediff-dwim
|
||||
;; - and: refresh-all, status-jump, status-quick.
|
||||
'("Magit"
|
||||
["Refresh" magit-refresh t]
|
||||
["Refresh all" magit-refresh-all t]
|
||||
"---" "Inspect"
|
||||
[" Bisect..." magit-bisect t]
|
||||
[" Cherries..." magit-cherry t]
|
||||
[" Diff..." magit-diff t]
|
||||
[" Ediff..." magit-ediff t]
|
||||
[" Log..." magit-log t]
|
||||
[" References..." magit-show-refs t]
|
||||
"---" "Manipulate"
|
||||
[" Commit..." magit-commit t]
|
||||
[" Stash..." magit-stash t]
|
||||
[" Tag..." magit-tag t]
|
||||
"---"
|
||||
["Stage" magit-stage t]
|
||||
["Stage modified" magit-stage-modified t]
|
||||
["Unstage" magit-unstage t]
|
||||
["Reset index" magit-reset-index t]
|
||||
["Commit" magit-commit t]
|
||||
["Add log entry" magit-commit-add-log t]
|
||||
["Tag" magit-tag-create t]
|
||||
[" Branch..." magit-branch t]
|
||||
[" Remote..." magit-remote t]
|
||||
"---"
|
||||
["Diff working tree" magit-diff-working-tree t]
|
||||
["Diff" magit-diff t]
|
||||
("Log"
|
||||
["Log" magit-log-other t]
|
||||
["Reflog" magit-reflog-other t]
|
||||
["Extended..." magit-log t])
|
||||
[" Merge..." magit-merge t]
|
||||
[" Rebase..." magit-rebase t]
|
||||
"---" "Transfer"
|
||||
[" Fetch..." magit-fetch t]
|
||||
[" Pull..." magit-pull t]
|
||||
[" Push..." magit-push t]
|
||||
"---" "Setup"
|
||||
[" Clone..." magit-clone t]
|
||||
[" Ignore..." magit-gitignore t]
|
||||
[" Init..." magit-init t]
|
||||
"---"
|
||||
["Cherry pick" magit-cherry-pick t]
|
||||
["Revert commit" magit-revert t]
|
||||
("Advanced"
|
||||
["Run..." magit-run t]
|
||||
"---"
|
||||
["Apply patches..." magit-am t]
|
||||
["Format patches..." magit-patch t]
|
||||
"---"
|
||||
["Note..." magit-notes t]
|
||||
"---"
|
||||
["Submodule..." magit-submodule t]
|
||||
["Subtree..." magit-subtree t]
|
||||
["Worktree..." magit-worktree t])
|
||||
"---"
|
||||
["Ignore at toplevel" magit-gitignore-in-topdir t]
|
||||
["Ignore in subdirectory" magit-gitignore-in-subdir t]
|
||||
["Discard" magit-discard t]
|
||||
["Reset head and index" magit-reset-mixed t]
|
||||
["Stash" magit-stash-both t]
|
||||
["Snapshot" magit-snapshot-both t]
|
||||
["Show command dispatcher..." magit-dispatch t]
|
||||
["Show manual" magit-info t]
|
||||
["Show another buffer" magit-display-repository-buffer t]
|
||||
"---"
|
||||
["Branch..." magit-checkout t]
|
||||
["Merge" magit-merge t]
|
||||
["Ediff resolve" magit-ediff-resolve t]
|
||||
["Rebase..." magit-rebase t]
|
||||
"---"
|
||||
["Push" magit-push t]
|
||||
["Pull" magit-pull-branch t]
|
||||
["Remote update" magit-fetch-all t]
|
||||
("Submodule"
|
||||
["Submodule update" magit-submodule-update t]
|
||||
["Submodule update and init" magit-submodule-setup t]
|
||||
["Submodule init" magit-submodule-init t]
|
||||
["Submodule sync" magit-submodule-sync t])
|
||||
"---"
|
||||
("Extensions")
|
||||
"---"
|
||||
["Display Git output" magit-process-buffer t]
|
||||
["Quit Magit" magit-mode-bury-buffer t]))
|
||||
("Change buffer arguments"
|
||||
["Diff arguments" magit-diff-refresh t]
|
||||
["Log arguments" magit-log-refresh t])
|
||||
["Refresh buffer" magit-refresh t]
|
||||
["Bury buffer" magit-mode-bury-buffer t]))
|
||||
|
||||
;;; Mode
|
||||
|
||||
@@ -526,9 +525,10 @@ Magit is documented in info node `(magit)'."
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(face-remap-add-relative 'header-line 'magit-header-line)
|
||||
(setq mode-line-process (magit-repository-local-get 'mode-line-process))
|
||||
(setq-local revert-buffer-function 'magit-refresh-buffer)
|
||||
(setq-local bookmark-make-record-function 'magit--make-bookmark)
|
||||
(setq-local isearch-filter-predicate 'magit-section--open-temporarily))
|
||||
(setq-local revert-buffer-function #'magit-refresh-buffer)
|
||||
(setq-local bookmark-make-record-function #'magit--make-bookmark)
|
||||
(setq-local imenu-create-index-function #'magit--imenu-create-index)
|
||||
(setq-local isearch-filter-predicate #'magit-section--open-temporarily))
|
||||
|
||||
;;; Local Variables
|
||||
|
||||
@@ -574,12 +574,15 @@ your mode instead of adding an entry to this variable.")
|
||||
(make-obsolete-variable 'magit-buffer-lock-functions nil "Magit 3.0.0")
|
||||
|
||||
(cl-defgeneric magit-buffer-value ()
|
||||
(when-let ((fn (cdr (assq major-mode magit-buffer-lock-functions))))
|
||||
(and-let* ((fn (cdr (assq major-mode magit-buffer-lock-functions))))
|
||||
(funcall fn (with-no-warnings magit-refresh-args))))
|
||||
|
||||
(defvar-local magit-previous-section nil)
|
||||
(put 'magit-previous-section 'permanent-local t)
|
||||
|
||||
(defvar-local magit--imenu-group-types nil)
|
||||
(defvar-local magit--imenu-item-types nil)
|
||||
|
||||
;;; Setup Buffer
|
||||
|
||||
(defmacro magit-setup-buffer (mode &optional locked &rest bindings)
|
||||
@@ -601,16 +604,14 @@ your mode instead of adding an entry to this variable.")
|
||||
(section (and buffer (magit-current-section)))
|
||||
(created (not buffer)))
|
||||
(unless buffer
|
||||
(setq buffer (magit-with-toplevel
|
||||
(magit-generate-new-buffer mode value))))
|
||||
(setq buffer (magit-generate-new-buffer mode value)))
|
||||
(with-current-buffer buffer
|
||||
(setq magit-previous-section section)
|
||||
(funcall mode)
|
||||
(magit-xref-setup 'magit-setup-buffer-internal bindings)
|
||||
(magit-xref-setup #'magit-setup-buffer-internal bindings)
|
||||
(pcase-dolist (`(,var ,val) bindings)
|
||||
(set (make-local-variable var) val))
|
||||
(when created
|
||||
(magit-status-goto-initial-section)
|
||||
(run-hooks 'magit-create-buffer-hook)))
|
||||
(magit-display-buffer buffer)
|
||||
(with-current-buffer buffer
|
||||
@@ -639,8 +640,7 @@ locked to its value, which is derived from MODE and ARGS."
|
||||
(section (and buffer (magit-current-section)))
|
||||
(created (not buffer)))
|
||||
(unless buffer
|
||||
(setq buffer (magit-with-toplevel
|
||||
(magit-generate-new-buffer mode value))))
|
||||
(setq buffer (magit-generate-new-buffer mode value)))
|
||||
(with-current-buffer buffer
|
||||
(setq magit-previous-section section)
|
||||
(with-no-warnings
|
||||
@@ -648,7 +648,6 @@ locked to its value, which is derived from MODE and ARGS."
|
||||
(funcall mode)
|
||||
(magit-xref-setup 'magit-mode-setup-internal args)
|
||||
(when created
|
||||
(magit-status-goto-initial-section)
|
||||
(run-hooks 'magit-create-buffer-hook)))
|
||||
(magit-display-buffer buffer)
|
||||
(with-current-buffer buffer
|
||||
@@ -787,7 +786,7 @@ the mode of the current buffer derives from `magit-log-mode' or
|
||||
`magit-cherry-mode'."
|
||||
(display-buffer
|
||||
buffer
|
||||
(cond ((and (or git-commit-mode
|
||||
(cond ((and (or (bound-and-true-p git-commit-mode)
|
||||
(derived-mode-p 'magit-log-mode
|
||||
'magit-cherry-mode
|
||||
'magit-reflog-mode))
|
||||
@@ -848,48 +847,47 @@ If `visible', then only consider buffers on all visible frames.
|
||||
If `selected' or t, then only consider buffers on the selected
|
||||
frame.
|
||||
If a frame, then only consider buffers on that frame."
|
||||
(if-let ((topdir (magit-toplevel)))
|
||||
(cl-flet* ((b (buffer)
|
||||
(with-current-buffer buffer
|
||||
(and (eq major-mode mode)
|
||||
(equal magit--default-directory topdir)
|
||||
(if value
|
||||
(and magit-buffer-locked-p
|
||||
(equal (magit-buffer-value) value))
|
||||
(not magit-buffer-locked-p))
|
||||
buffer)))
|
||||
(w (window)
|
||||
(b (window-buffer window)))
|
||||
(f (frame)
|
||||
(seq-some #'w (window-list frame 'no-minibuf))))
|
||||
(pcase-exhaustive frame
|
||||
(`nil (seq-some #'b (buffer-list)))
|
||||
(`all (seq-some #'f (frame-list)))
|
||||
(`visible (seq-some #'f (visible-frame-list)))
|
||||
((or `selected `t) (seq-some #'w (window-list (selected-frame))))
|
||||
((guard (framep frame)) (seq-some #'w (window-list frame)))))
|
||||
(magit--not-inside-repository-error)))
|
||||
(let ((topdir (magit--toplevel-safe)))
|
||||
(cl-flet* ((b (buffer)
|
||||
(with-current-buffer buffer
|
||||
(and (eq major-mode mode)
|
||||
(equal magit--default-directory topdir)
|
||||
(if value
|
||||
(and magit-buffer-locked-p
|
||||
(equal (magit-buffer-value) value))
|
||||
(not magit-buffer-locked-p))
|
||||
buffer)))
|
||||
(w (window)
|
||||
(b (window-buffer window)))
|
||||
(f (frame)
|
||||
(seq-some #'w (window-list frame 'no-minibuf))))
|
||||
(pcase-exhaustive frame
|
||||
('nil (seq-some #'b (buffer-list)))
|
||||
('all (seq-some #'f (frame-list)))
|
||||
('visible (seq-some #'f (visible-frame-list)))
|
||||
((or 'selected 't) (seq-some #'w (window-list (selected-frame))))
|
||||
((guard (framep frame)) (seq-some #'w (window-list frame)))))))
|
||||
|
||||
(defun magit-mode-get-buffer (mode &optional create frame value)
|
||||
(declare (obsolete magit-get-mode-buffer "Magit 3.0.0"))
|
||||
(when create
|
||||
(error "`magit-mode-get-buffer's CREATE argument is obsolete"))
|
||||
(if-let ((topdir (magit-toplevel)))
|
||||
(--first (with-current-buffer it
|
||||
(and (eq major-mode mode)
|
||||
(equal magit--default-directory topdir)
|
||||
(if value
|
||||
(and magit-buffer-locked-p
|
||||
(equal (magit-buffer-value) value))
|
||||
(not magit-buffer-locked-p))))
|
||||
(if frame
|
||||
(mapcar #'window-buffer
|
||||
(window-list (unless (eq frame t) frame)))
|
||||
(buffer-list)))
|
||||
(magit--not-inside-repository-error)))
|
||||
(let ((topdir (magit--toplevel-safe)))
|
||||
(--first (with-current-buffer it
|
||||
(and (eq major-mode mode)
|
||||
(equal magit--default-directory topdir)
|
||||
(if value
|
||||
(and magit-buffer-locked-p
|
||||
(equal (magit-buffer-value) value))
|
||||
(not magit-buffer-locked-p))))
|
||||
(if frame
|
||||
(mapcar #'window-buffer
|
||||
(window-list (unless (eq frame t) frame)))
|
||||
(buffer-list)))))
|
||||
|
||||
(defun magit-generate-new-buffer (mode &optional value)
|
||||
(let* ((name (funcall magit-generate-buffer-name-function mode value))
|
||||
(defun magit-generate-new-buffer (mode &optional value directory)
|
||||
(let* ((default-directory (or directory (magit--toplevel-safe)))
|
||||
(name (funcall magit-generate-buffer-name-function mode value))
|
||||
(buffer (generate-new-buffer name)))
|
||||
(with-current-buffer buffer
|
||||
(setq magit--default-directory default-directory)
|
||||
@@ -1035,15 +1033,6 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(magit-get-mode-buffer 'magit-status-mode))
|
||||
(with-current-buffer it
|
||||
(magit-refresh-buffer)))
|
||||
(magit-auto-revert-buffers)
|
||||
(cond
|
||||
((and (not this-command)
|
||||
(memq last-command magit-post-commit-hook-commands))
|
||||
(magit-run-hook-with-benchmark 'magit-post-commit-hook))
|
||||
((memq this-command magit-post-stage-hook-commands)
|
||||
(magit-run-hook-with-benchmark 'magit-post-stage-hook))
|
||||
((memq this-command magit-post-unstage-hook-commands)
|
||||
(magit-run-hook-with-benchmark 'magit-post-unstage-hook)))
|
||||
(magit-run-hook-with-benchmark 'magit-post-refresh-hook)
|
||||
(when magit-refresh-verbose
|
||||
(let* ((c (caar magit--refresh-cache))
|
||||
@@ -1065,7 +1054,6 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(magit-run-hook-with-benchmark 'magit-pre-refresh-hook)
|
||||
(dolist (buffer (magit-mode-get-buffers))
|
||||
(with-current-buffer buffer (magit-refresh-buffer)))
|
||||
(magit-auto-revert-buffers)
|
||||
(magit-run-hook-with-benchmark 'magit-post-refresh-hook))
|
||||
|
||||
(defvar-local magit-refresh-start-time nil)
|
||||
@@ -1084,10 +1072,11 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(lambda (window)
|
||||
(with-selected-window window
|
||||
(with-current-buffer buffer
|
||||
(when-let ((section (magit-current-section)))
|
||||
(and-let* ((section (magit-section-at)))
|
||||
`(( ,window
|
||||
,section
|
||||
,@(magit-refresh-get-relative-position)))))))
|
||||
,@(magit-section-get-relative-position
|
||||
section)))))))
|
||||
;; If it qualifies, then the selected window
|
||||
;; comes first, but we want to handle it last
|
||||
;; so that its `magit-section-movement-hook'
|
||||
@@ -1099,7 +1088,6 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(setq magit-section-highlight-overlays nil)
|
||||
(setq magit-section-highlighted-sections nil)
|
||||
(setq magit-section-unhighlight-sections nil)
|
||||
(magit-process-unset-mode-line-error-status)
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(save-excursion
|
||||
@@ -1119,33 +1107,12 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(float-time (time-subtract (current-time)
|
||||
magit-refresh-start-time)))))))
|
||||
|
||||
(defun magit-refresh-get-relative-position ()
|
||||
(when-let ((section (magit-current-section)))
|
||||
(let ((start (oref section start)))
|
||||
(list (- (line-number-at-pos (point))
|
||||
(line-number-at-pos start))
|
||||
(- (point) (line-beginning-position))
|
||||
(and (magit-hunk-section-p section)
|
||||
(region-active-p)
|
||||
(progn (goto-char (line-beginning-position))
|
||||
(when (looking-at "^[-+]") (forward-line))
|
||||
(while (looking-at "^[ @]") (forward-line))
|
||||
(let ((beg (point)))
|
||||
(cond ((looking-at "^[-+]")
|
||||
(forward-line)
|
||||
(while (looking-at "^[-+]") (forward-line))
|
||||
(while (looking-at "^ ") (forward-line))
|
||||
(forward-line -1)
|
||||
(regexp-quote (buffer-substring-no-properties
|
||||
beg (line-end-position))))
|
||||
(t t)))))))))
|
||||
|
||||
;;; Save File-Visiting Buffers
|
||||
|
||||
(defvar disable-magit-save-buffers nil)
|
||||
(defvar magit--disable-save-buffers nil)
|
||||
|
||||
(defun magit-pre-command-hook ()
|
||||
(setq disable-magit-save-buffers nil))
|
||||
(setq magit--disable-save-buffers nil))
|
||||
(add-hook 'pre-command-hook #'magit-pre-command-hook)
|
||||
|
||||
(defvar magit-after-save-refresh-buffers nil)
|
||||
@@ -1156,7 +1123,7 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(with-current-buffer buffer
|
||||
(magit-refresh-buffer))))
|
||||
(setq magit-after-save-refresh-buffers nil)
|
||||
(remove-hook 'post-command-hook 'magit-after-save-refresh-buffers))
|
||||
(remove-hook 'post-command-hook #'magit-after-save-refresh-buffers))
|
||||
|
||||
(defun magit-after-save-refresh-status ()
|
||||
"Refresh the status buffer of the current repository.
|
||||
@@ -1171,11 +1138,11 @@ Note that refreshing a Magit buffer is done by re-creating its
|
||||
contents from scratch, which can be slow in large repositories.
|
||||
If you are not satisfied with Magit's performance, then you
|
||||
should obviously not add this function to that hook."
|
||||
(when (and (not disable-magit-save-buffers)
|
||||
(when (and (not magit--disable-save-buffers)
|
||||
(magit-inside-worktree-p t))
|
||||
(--when-let (ignore-errors (magit-get-mode-buffer 'magit-status-mode))
|
||||
(add-to-list 'magit-after-save-refresh-buffers it)
|
||||
(add-hook 'post-command-hook 'magit-after-save-refresh-buffers))))
|
||||
(add-hook 'post-command-hook #'magit-after-save-refresh-buffers))))
|
||||
|
||||
(defun magit-maybe-save-repository-buffers ()
|
||||
"Maybe save file-visiting buffers belonging to the current repository.
|
||||
@@ -1183,8 +1150,8 @@ Do so if `magit-save-repository-buffers' is non-nil. You should
|
||||
not remove this from any hooks, instead set that variable to nil
|
||||
if you so desire."
|
||||
(when (and magit-save-repository-buffers
|
||||
(not disable-magit-save-buffers))
|
||||
(setq disable-magit-save-buffers t)
|
||||
(not magit--disable-save-buffers))
|
||||
(setq magit--disable-save-buffers t)
|
||||
(let ((msg (current-message)))
|
||||
(magit-save-repository-buffers
|
||||
(eq magit-save-repository-buffers 'dontask))
|
||||
@@ -1222,18 +1189,26 @@ argument (the prefix) non-nil means save all with no questions."
|
||||
(save-some-buffers
|
||||
arg (lambda ()
|
||||
(and buffer-file-name
|
||||
;; - Check whether refreshing is disabled.
|
||||
(not magit-inhibit-refresh-save)
|
||||
;; - Check whether the visited file is either on the
|
||||
;; same remote as the repository, or both are on
|
||||
;; the local system.
|
||||
(equal (file-remote-p buffer-file-name) remote)
|
||||
;; Delayed checks that are more expensive for remote
|
||||
;; repositories, due to the required network access.
|
||||
;; - Check whether the file is inside the repository.
|
||||
(equal (magit-rev-parse-safe "--show-toplevel") topdir)
|
||||
;; - Check whether the file is actually writable.
|
||||
(file-writable-p buffer-file-name)))))))
|
||||
;; If the current file is modified and resides inside
|
||||
;; a repository, and a let-binding is in effect, which
|
||||
;; places us in another repository, then the below
|
||||
;; let-binding is needed to prevent that file from
|
||||
;; being saved.
|
||||
(let ((default-directory
|
||||
(file-name-directory buffer-file-name)))
|
||||
(and
|
||||
;; - Check whether refreshing is disabled.
|
||||
(not magit-inhibit-refresh-save)
|
||||
;; - Check whether the visited file is either on the
|
||||
;; same remote as the repository, or both are on
|
||||
;; the local system.
|
||||
(equal (file-remote-p buffer-file-name) remote)
|
||||
;; Delayed checks that are more expensive for remote
|
||||
;; repositories, due to the required network access.
|
||||
;; - Check whether the file is inside the repository.
|
||||
(equal (magit-rev-parse-safe "--show-toplevel") topdir)
|
||||
;; - Check whether the file is actually writable.
|
||||
(file-writable-p buffer-file-name)))))))))
|
||||
|
||||
;;; Restore Window Configuration
|
||||
|
||||
@@ -1372,7 +1347,7 @@ Return a (KEY . VALUE) cons cell.
|
||||
The KEY is matched using `equal'.
|
||||
|
||||
Unless specified, REPOSITORY is the current buffer's repository."
|
||||
(when-let ((cache (assoc (or repository
|
||||
(and-let* ((cache (assoc (or repository
|
||||
(magit-repository-local-repository))
|
||||
magit-repository-local-cache)))
|
||||
(assoc key (cdr cache))))
|
||||
@@ -1396,9 +1371,7 @@ Unless specified, REPOSITORY is the current buffer's repository."
|
||||
(when-let ((cache (assoc (or repository
|
||||
(magit-repository-local-repository))
|
||||
magit-repository-local-cache)))
|
||||
;; There is no `assoc-delete-all'.
|
||||
(setf (cdr cache)
|
||||
(cl-delete key (cdr cache) :key #'car :test #'equal))))
|
||||
(setf cache (compat-assoc-delete-all key cache))))
|
||||
|
||||
(defmacro magit--with-repository-local-cache (key &rest body)
|
||||
(declare (indent 1) (debug (form body)))
|
||||
@@ -1421,22 +1394,175 @@ Unless specified, REPOSITORY is the current buffer's repository."
|
||||
(magit-repository-local-get
|
||||
(cons mode 'magit-section-visibility-cache))))
|
||||
|
||||
(defun magit-zap-caches ()
|
||||
(defun magit-zap-caches (&optional all)
|
||||
"Zap caches for the current repository.
|
||||
Remove the repository's entry from `magit-repository-local-cache'
|
||||
and set `magit-section-visibility-cache' to nil in all of the
|
||||
repository's Magit buffers."
|
||||
|
||||
Remove the repository's entry from `magit-repository-local-cache',
|
||||
remove the host's entry from `magit--host-git-version-cache', set
|
||||
`magit-section-visibility-cache' to nil for all Magit buffers of
|
||||
the repository and set `magit--libgit-available-p' to `unknown'.
|
||||
|
||||
With a prefix argument or if optional ALL is non-nil, discard the
|
||||
mentioned caches completely."
|
||||
(interactive)
|
||||
(magit-with-toplevel
|
||||
(setq magit-repository-local-cache
|
||||
(cl-delete default-directory
|
||||
magit-repository-local-cache
|
||||
:key #'car :test #'equal)))
|
||||
(dolist (buffer (magit-mode-get-buffers))
|
||||
(with-current-buffer buffer
|
||||
(setq magit-section-visibility-cache nil)))
|
||||
(cond (all
|
||||
(setq magit-repository-local-cache nil)
|
||||
(setq magit--host-git-version-cache nil)
|
||||
(dolist (buffer (buffer-list))
|
||||
(with-current-buffer buffer
|
||||
(when (derived-mode-p 'magit-mode)
|
||||
(setq magit-section-visibility-cache nil)))))
|
||||
(t
|
||||
(magit-with-toplevel
|
||||
(setq magit-repository-local-cache
|
||||
(cl-delete default-directory
|
||||
magit-repository-local-cache
|
||||
:key #'car :test #'equal))
|
||||
(setq magit--host-git-version-cache
|
||||
(cl-delete (file-remote-p default-directory)
|
||||
magit--host-git-version-cache
|
||||
:key #'car :test #'equal)))
|
||||
(dolist (buffer (magit-mode-get-buffers))
|
||||
(with-current-buffer buffer
|
||||
(setq magit-section-visibility-cache nil)))))
|
||||
(setq magit--libgit-available-p 'unknown))
|
||||
|
||||
;;; Imenu Support
|
||||
|
||||
(defun magit--imenu-create-index ()
|
||||
;; If `which-function-mode' is active, then the create-index
|
||||
;; function is called at the time the major-mode is being enabled.
|
||||
;; Modes that derive from `magit-mode' have not populated the buffer
|
||||
;; at that time yet, so we have to abort.
|
||||
(and magit-root-section
|
||||
(or magit--imenu-group-types
|
||||
magit--imenu-item-types)
|
||||
(let ((index
|
||||
(cl-mapcan
|
||||
(lambda (section)
|
||||
(cond
|
||||
(magit--imenu-group-types
|
||||
(and (if (eq (car-safe magit--imenu-group-types) 'not)
|
||||
(not (magit-section-match
|
||||
(cdr magit--imenu-group-types)
|
||||
section))
|
||||
(magit-section-match magit--imenu-group-types section))
|
||||
(and-let* ((children (oref section children)))
|
||||
`((,(magit--imenu-index-name section)
|
||||
,@(mapcar (lambda (s)
|
||||
(cons (magit--imenu-index-name s)
|
||||
(oref s start)))
|
||||
children))))))
|
||||
(magit--imenu-item-types
|
||||
(and (magit-section-match magit--imenu-item-types section)
|
||||
`((,(magit--imenu-index-name section)
|
||||
. ,(oref section start)))))))
|
||||
(oref magit-root-section children))))
|
||||
(if (and magit--imenu-group-types (symbolp magit--imenu-group-types))
|
||||
(cdar index)
|
||||
index))))
|
||||
|
||||
(defun magit--imenu-index-name (section)
|
||||
(let ((heading (buffer-substring-no-properties
|
||||
(oref section start)
|
||||
(1- (or (oref section content)
|
||||
(oref section end))))))
|
||||
(save-match-data
|
||||
(cond
|
||||
((and (magit-section-match [commit logbuf] section)
|
||||
(string-match "[^ ]+\\([ *|]*\\).+" heading))
|
||||
(replace-match " " t t heading 1))
|
||||
((magit-section-match
|
||||
'([branch local branchbuf] [tag tags branchbuf]) section)
|
||||
(oref section value))
|
||||
((magit-section-match [branch remote branchbuf] section)
|
||||
(concat (oref (oref section parent) value) "/"
|
||||
(oref section value)))
|
||||
((string-match " ([0-9]+)\\'" heading)
|
||||
(substring heading 0 (match-beginning 0)))
|
||||
(t heading)))))
|
||||
|
||||
;;; Bookmark support
|
||||
|
||||
(declare-function bookmark-get-filename "bookmark" (bookmark-name-or-record))
|
||||
(declare-function bookmark-make-record-default "bookmark"
|
||||
(&optional no-file no-context posn))
|
||||
(declare-function bookmark-prop-get "bookmark" (bookmark-name-or-record prop))
|
||||
(declare-function bookmark-prop-set "bookmark" (bookmark-name-or-record prop val))
|
||||
|
||||
(defun magit--make-bookmark ()
|
||||
"Create a bookmark for the current Magit buffer.
|
||||
Input values are the major-mode's `magit-bookmark-name' method,
|
||||
and the buffer-local values of the variables referenced in its
|
||||
`magit-bookmark-variables' property."
|
||||
(require 'bookmark)
|
||||
(if (plist-member (symbol-plist major-mode) 'magit-bookmark-variables)
|
||||
;; `bookmark-make-record-default's return value does not match
|
||||
;; (NAME . ALIST), even though it is used as the default value
|
||||
;; of `bookmark-make-record-function', which states that such
|
||||
;; functions must do that. See #4356.
|
||||
(let ((bookmark (cons nil (bookmark-make-record-default 'no-file))))
|
||||
(bookmark-prop-set bookmark 'handler #'magit--handle-bookmark)
|
||||
(bookmark-prop-set bookmark 'mode major-mode)
|
||||
(bookmark-prop-set bookmark 'filename (magit-toplevel))
|
||||
(bookmark-prop-set bookmark 'defaults (list (magit-bookmark-name)))
|
||||
(dolist (var (get major-mode 'magit-bookmark-variables))
|
||||
(bookmark-prop-set bookmark var (symbol-value var)))
|
||||
(bookmark-prop-set
|
||||
bookmark 'magit-hidden-sections
|
||||
(--keep (and (oref it hidden)
|
||||
(cons (oref it type)
|
||||
(if (derived-mode-p 'magit-stash-mode)
|
||||
(string-replace magit-buffer-revision
|
||||
magit-buffer-revision-hash
|
||||
(oref it value))
|
||||
(oref it value))))
|
||||
(oref magit-root-section children)))
|
||||
bookmark)
|
||||
(user-error "Bookmarking is not implemented for %s buffers" major-mode)))
|
||||
|
||||
(defun magit--handle-bookmark (bookmark)
|
||||
"Open a bookmark created by `magit--make-bookmark'.
|
||||
Call the `magit-*-setup-buffer' function of the the major-mode
|
||||
with the variables' values as arguments, which were recorded by
|
||||
`magit--make-bookmark'. Ignore `magit-display-buffer-function'."
|
||||
(let ((buffer (let ((default-directory (bookmark-get-filename bookmark))
|
||||
(mode (bookmark-prop-get bookmark 'mode))
|
||||
(magit-display-buffer-function #'identity)
|
||||
(magit-display-buffer-noselect t))
|
||||
(apply (intern (format "%s-setup-buffer"
|
||||
(substring (symbol-name mode) 0 -5)))
|
||||
(--map (bookmark-prop-get bookmark it)
|
||||
(get mode 'magit-bookmark-variables))))))
|
||||
(set-buffer buffer) ; That is the interface we have to adhere to.
|
||||
(when-let ((hidden (bookmark-prop-get bookmark 'magit-hidden-sections)))
|
||||
(with-current-buffer buffer
|
||||
(dolist (child (oref magit-root-section children))
|
||||
(if (member (cons (oref child type)
|
||||
(oref child value))
|
||||
hidden)
|
||||
(magit-section-hide child)
|
||||
(magit-section-show child)))))
|
||||
;; Compatibility with `bookmark+' package. See #4356.
|
||||
(when (bound-and-true-p bmkp-jump-display-function)
|
||||
(funcall bmkp-jump-display-function (current-buffer)))
|
||||
nil))
|
||||
|
||||
(put 'magit--handle-bookmark 'bookmark-handler-type "Magit")
|
||||
|
||||
(cl-defgeneric magit-bookmark-name ()
|
||||
"Return name for bookmark to current buffer."
|
||||
(format "%s%s"
|
||||
(substring (symbol-name major-mode) 0 -5)
|
||||
(if-let ((vars (get major-mode 'magit-bookmark-variables)))
|
||||
(cl-mapcan (lambda (var)
|
||||
(let ((val (symbol-value var)))
|
||||
(if (and val (atom val))
|
||||
(list val)
|
||||
val)))
|
||||
vars)
|
||||
"")))
|
||||
|
||||
;;; Utilities
|
||||
|
||||
(defun magit-toggle-verbose-refresh ()
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-notes.el --- notes support -*- lexical-binding: t -*-
|
||||
;;; magit-notes.el --- Notes support -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -71,27 +68,29 @@
|
||||
(transient-define-infix magit-core.notesRef ()
|
||||
:class 'magit--git-variable
|
||||
:variable "core.notesRef"
|
||||
:reader 'magit-notes-read-ref
|
||||
:reader #'magit-notes-read-ref
|
||||
:prompt "Set local core.notesRef")
|
||||
|
||||
(transient-define-infix magit-notes.displayRef ()
|
||||
:class 'magit--git-variable
|
||||
:variable "notes.displayRef"
|
||||
:multi-value t
|
||||
:reader 'magit-notes-read-refs
|
||||
:reader #'magit-notes-read-refs
|
||||
:prompt "Set local notes.displayRef")
|
||||
|
||||
(transient-define-infix magit-global-core.notesRef ()
|
||||
:class 'magit--git-variable
|
||||
:variable "core.notesRef"
|
||||
:reader 'magit-notes-read-ref
|
||||
:global t
|
||||
:reader #'magit-notes-read-ref
|
||||
:prompt "Set global core.notesRef")
|
||||
|
||||
(transient-define-infix magit-global-notes.displayRef ()
|
||||
:class 'magit--git-variable
|
||||
:variable "notes.displayRef"
|
||||
:global t
|
||||
:multi-value t
|
||||
:reader 'magit-notes-read-refs
|
||||
:reader #'magit-notes-read-refs
|
||||
:prompt "Set global notes.displayRef")
|
||||
|
||||
(transient-define-argument magit-notes:--ref ()
|
||||
@@ -99,7 +98,7 @@
|
||||
:class 'transient-option
|
||||
:key "-r"
|
||||
:argument "--ref="
|
||||
:reader 'magit-notes-read-ref)
|
||||
:reader #'magit-notes-read-ref)
|
||||
|
||||
(transient-define-argument magit-notes:--strategy ()
|
||||
:description "Merge strategy"
|
||||
@@ -165,16 +164,16 @@ Also see `magit-notes-merge'."
|
||||
;;; Readers
|
||||
|
||||
(defun magit-notes-read-ref (prompt _initial-input history)
|
||||
(--when-let (magit-completing-read
|
||||
prompt (magit-list-notes-refnames) nil nil
|
||||
(--when-let (magit-get "core.notesRef")
|
||||
(if (string-prefix-p "refs/notes/" it)
|
||||
(substring it 11)
|
||||
it))
|
||||
history)
|
||||
(if (string-prefix-p "refs/" it)
|
||||
it
|
||||
(concat "refs/notes/" it))))
|
||||
(and-let* ((ref (magit-completing-read
|
||||
prompt (magit-list-notes-refnames) nil nil
|
||||
(and-let* ((def (magit-get "core.notesRef")))
|
||||
(if (string-prefix-p "refs/notes/" def)
|
||||
(substring def 11)
|
||||
def))
|
||||
history)))
|
||||
(if (string-prefix-p "refs/" ref)
|
||||
ref
|
||||
(concat "refs/notes/" ref))))
|
||||
|
||||
(defun magit-notes-read-refs (prompt &optional _initial-input _history)
|
||||
(mapcar (lambda (ref)
|
||||
@@ -193,9 +192,9 @@ Also see `magit-notes-merge'."
|
||||
|
||||
(defun magit-notes-read-args (prompt)
|
||||
(list (magit-read-branch-or-commit prompt (magit-stash-at-point))
|
||||
(--when-let (--first (string-match "^--ref=\\(.+\\)" it)
|
||||
(transient-args 'magit-notes))
|
||||
(match-string 1 it))))
|
||||
(and-let* ((str (--first (string-match "^--ref=\\(.+\\)" it)
|
||||
(transient-args 'magit-notes))))
|
||||
(match-string 1 str))))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-notes)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-obsolete.el --- obsolete definitions -*- lexical-binding: t -*-
|
||||
;;; magit-obsolete.el --- Obsolete definitions -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -34,10 +31,10 @@
|
||||
;;; Obsolete since v3.0.0
|
||||
|
||||
(define-obsolete-function-alias 'magit-diff-visit-file-worktree
|
||||
'magit-diff-visit-worktree-file "Magit 3.0.0")
|
||||
#'magit-diff-visit-worktree-file "Magit 3.0.0")
|
||||
|
||||
(define-obsolete-function-alias 'magit-status-internal
|
||||
'magit-status-setup-buffer "Magit 3.0.0")
|
||||
#'magit-status-setup-buffer "Magit 3.0.0")
|
||||
|
||||
(define-obsolete-variable-alias 'magit-mode-setup-hook
|
||||
'magit-setup-buffer-hook "Magit 3.0.0")
|
||||
@@ -46,10 +43,10 @@
|
||||
'magit-branch-direct-configure "Magit 3.0.0")
|
||||
|
||||
(define-obsolete-function-alias 'magit-dispatch-popup
|
||||
'magit-dispatch "Magit 3.0.0")
|
||||
#'magit-dispatch "Magit 3.0.0")
|
||||
|
||||
(define-obsolete-function-alias 'magit-repolist-column-dirty
|
||||
'magit-repolist-column-flag "Magit 3.0.0")
|
||||
#'magit-repolist-column-flag "Magit 3.0.0")
|
||||
|
||||
(define-obsolete-variable-alias 'magit-disable-line-numbers
|
||||
'magit-section-disable-line-numbers "Magit 3.0.0")
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-patch.el --- creating and applying patches -*- lexical-binding: t -*-
|
||||
;;; magit-patch.el --- Creating and applying patches -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -106,7 +103,7 @@ which creates patches for all commits that are reachable from
|
||||
(concat (car (last revs)) "^.." (car revs))
|
||||
(let ((range (magit-read-range-or-commit
|
||||
"Format range or commit")))
|
||||
(if (string-match-p "\\.\\." range)
|
||||
(if (string-search ".." range)
|
||||
range
|
||||
(format "%s~..%s" range range))))
|
||||
(let ((args (transient-args 'magit-patch-create)))
|
||||
@@ -119,7 +116,7 @@ which creates patches for all commits that are reachable from
|
||||
(save-match-data
|
||||
(find-file
|
||||
(expand-file-name
|
||||
(concat (when-let ((v (transient-arg-value "--reroll-count=" args)))
|
||||
(concat (and-let* ((v (transient-arg-value "--reroll-count=" args)))
|
||||
(format "v%s-" v))
|
||||
"0000-cover-letter.patch")
|
||||
(let ((topdir (magit-toplevel)))
|
||||
@@ -163,7 +160,7 @@ which creates patches for all commits that are reachable from
|
||||
:key "C-m v "
|
||||
:shortarg "-v"
|
||||
:argument "--reroll-count="
|
||||
:reader 'transient-read-number-N+)
|
||||
:reader #'transient-read-number-N+)
|
||||
|
||||
(transient-define-argument magit-format-patch:--interdiff ()
|
||||
:description "Insert interdiff"
|
||||
@@ -214,21 +211,21 @@ which creates patches for all commits that are reachable from
|
||||
:class 'transient-option
|
||||
:key "C-m C-f"
|
||||
:argument "--from="
|
||||
:reader 'magit-transient-read-person)
|
||||
:reader #'magit-transient-read-person)
|
||||
|
||||
(transient-define-argument magit-format-patch:--to ()
|
||||
:description "To"
|
||||
:class 'transient-option
|
||||
:key "C-m C-t"
|
||||
:argument "--to="
|
||||
:reader 'magit-transient-read-person)
|
||||
:reader #'magit-transient-read-person)
|
||||
|
||||
(transient-define-argument magit-format-patch:--cc ()
|
||||
:description "CC"
|
||||
:class 'transient-option
|
||||
:key "C-m C-c"
|
||||
:argument "--cc="
|
||||
:reader 'magit-transient-read-person)
|
||||
:reader #'magit-transient-read-person)
|
||||
|
||||
(transient-define-argument magit-format-patch:--output-directory ()
|
||||
:description "Output directory"
|
||||
@@ -236,7 +233,7 @@ which creates patches for all commits that are reachable from
|
||||
:key "C-m o "
|
||||
:shortarg "-o"
|
||||
:argument "--output-directory="
|
||||
:reader 'transient-read-existing-directory)
|
||||
:reader #'transient-read-existing-directory)
|
||||
|
||||
;;;###autoload (autoload 'magit-patch-apply "magit-patch" nil t)
|
||||
(transient-define-prefix magit-patch-apply (file &rest args)
|
||||
@@ -254,7 +251,7 @@ which creates patches for all commits that are reachable from
|
||||
(list (expand-file-name
|
||||
(read-file-name "Apply patch: "
|
||||
default-directory nil nil
|
||||
(when-let ((file (magit-file-at-point)))
|
||||
(and-let* ((file (magit-file-at-point)))
|
||||
(file-relative-name file))))
|
||||
(transient-args 'magit-patch-apply))))
|
||||
(if (not file)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
(define-package "magit" "20220126.1645" "A Git porcelain inside Emacs."
|
||||
(define-package "magit" "20221208.1848" "A Git porcelain inside Emacs."
|
||||
'((emacs "25.1")
|
||||
(compat "28.1.1.2")
|
||||
(dash "20210826")
|
||||
(git-commit "20211004")
|
||||
(magit-section "20211004")
|
||||
(transient "20210920")
|
||||
(with-editor "20211001"))
|
||||
:commit "6ba3b50373fffa89ae99fc0ad5135e3d574f6df4" :authors
|
||||
(git-commit "20221127")
|
||||
(magit-section "20221127")
|
||||
(transient "20220325")
|
||||
(with-editor "20220318"))
|
||||
:commit "99d9b3008adf72a0c2cdb7df70b5ae03ea9271c8" :authors
|
||||
'(("Marius Vollmer" . "marius.vollmer@gmail.com")
|
||||
("Jonas Bernoulli" . "jonas@bernoul.li"))
|
||||
:maintainer
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-process.el --- process functionality -*- lexical-binding: t -*-
|
||||
;;; magit-process.el --- Process functionality -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -33,17 +30,13 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit-utils)
|
||||
(require 'magit-section)
|
||||
(require 'magit-base)
|
||||
(require 'magit-git)
|
||||
(require 'magit-mode)
|
||||
|
||||
(require 'ansi-color)
|
||||
(require 'with-editor)
|
||||
|
||||
(declare-function auth-source-search "auth-source"
|
||||
(&rest spec &key max require create delete &allow-other-keys))
|
||||
|
||||
;;; Options
|
||||
|
||||
(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
|
||||
@@ -286,10 +279,7 @@ Used when `magit-process-display-mode-line-error' is non-nil."
|
||||
"Mode for looking at Git process output."
|
||||
:group 'magit-process
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(setq imenu-prev-index-position-function
|
||||
'magit-imenu--process-prev-index-position-function)
|
||||
(setq imenu-extract-index-name-function
|
||||
'magit-imenu--process-extract-index-name-function))
|
||||
(setq magit--imenu-item-types 'process))
|
||||
|
||||
(defun magit-process-buffer (&optional nodisplay)
|
||||
"Display the current repository's process buffer.
|
||||
@@ -310,8 +300,8 @@ optional NODISPLAY is non-nil also display it."
|
||||
(and (eq major-mode 'magit-process-mode)
|
||||
(equal default-directory topdir)))
|
||||
(buffer-list))
|
||||
(let ((default-directory topdir))
|
||||
(magit-generate-new-buffer 'magit-process-mode)))))
|
||||
(magit-generate-new-buffer 'magit-process-mode
|
||||
nil topdir))))
|
||||
(with-current-buffer buffer
|
||||
(if magit-root-section
|
||||
(when magit-process-log-max
|
||||
@@ -495,7 +485,7 @@ and still alive), as well as the respective Magit status buffer.
|
||||
|
||||
See `magit-start-process' for more information."
|
||||
(message "Running %s %s" (magit-git-executable)
|
||||
(let ((m (mapconcat #'identity (-flatten args) " ")))
|
||||
(let ((m (mapconcat #'identity (flatten-tree args) " ")))
|
||||
(remove-list-of-text-properties 0 (length m) '(face) m)
|
||||
m))
|
||||
(magit-start-git nil args))
|
||||
@@ -623,7 +613,7 @@ Magit status buffer."
|
||||
(let ((process-connection-type nil)
|
||||
(process-environment (magit-process-environment))
|
||||
(default-process-coding-system
|
||||
(magit--process-coding-system)))
|
||||
(magit--process-coding-system)))
|
||||
(apply #'start-file-process "git" process-buf
|
||||
(magit-git-executable) args))))
|
||||
(process-put process 'command-buf command-buf)
|
||||
@@ -733,22 +723,22 @@ Magit status buffer."
|
||||
"Special sentinel used by `magit-run-git-sequencer'."
|
||||
(when (memq (process-status process) '(exit signal))
|
||||
(magit-process-sentinel process event)
|
||||
(when-let ((process-buf (process-buffer process)))
|
||||
(when (buffer-live-p process-buf)
|
||||
(when-let ((status-buf (with-current-buffer process-buf
|
||||
(magit-get-mode-buffer 'magit-status-mode))))
|
||||
(with-current-buffer status-buf
|
||||
(--when-let
|
||||
(magit-get-section
|
||||
`((commit . ,(magit-rev-parse "HEAD"))
|
||||
(,(pcase (car (cadr (-split-at
|
||||
(1+ (length magit-git-global-arguments))
|
||||
(process-command process))))
|
||||
((or "rebase" "am") 'rebase-sequence)
|
||||
((or "cherry-pick" "revert") 'sequence)))
|
||||
(status)))
|
||||
(goto-char (oref it start))
|
||||
(magit-section-update-highlight))))))))
|
||||
(when-let* ((process-buf (process-buffer process))
|
||||
(- (buffer-live-p process-buf))
|
||||
(status-buf (with-current-buffer process-buf
|
||||
(magit-get-mode-buffer 'magit-status-mode))))
|
||||
(with-current-buffer status-buf
|
||||
(--when-let
|
||||
(magit-get-section
|
||||
`((commit . ,(magit-rev-parse "HEAD"))
|
||||
(,(pcase (car (cadr (-split-at
|
||||
(1+ (length magit-git-global-arguments))
|
||||
(process-command process))))
|
||||
((or "rebase" "am") 'rebase-sequence)
|
||||
((or "cherry-pick" "revert") 'sequence)))
|
||||
(status)))
|
||||
(goto-char (oref it start))
|
||||
(magit-section-update-highlight))))))
|
||||
|
||||
(defun magit-process-filter (proc string)
|
||||
"Default filter used by `magit-start-process'."
|
||||
@@ -805,11 +795,11 @@ Magit status buffer."
|
||||
If found, return the password. Otherwise, return nil.
|
||||
|
||||
To use this function add it to the appropriate hook
|
||||
(add-hook 'magit-process-find-password-functions
|
||||
'magit-process-password-auth-source)
|
||||
(add-hook \\='magit-process-find-password-functions
|
||||
\\='magit-process-password-auth-source)
|
||||
|
||||
KEY typically derives from a prompt such as:
|
||||
Password for 'https://yourname@github.com'
|
||||
Password for \\='https://yourname@github.com\\='
|
||||
in which case it would be the string
|
||||
yourname@github.com
|
||||
which matches the ~/.authinfo.gpg entry
|
||||
@@ -842,7 +832,8 @@ be translated on the fly by doing this once
|
||||
|
||||
[1]: https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token."
|
||||
(require 'auth-source)
|
||||
(and (string-match "\\`\\(.+\\)@\\([^@]+\\)\\'" key)
|
||||
(and (fboundp 'auth-source-search)
|
||||
(string-match "\\`\\(.+\\)@\\([^@]+\\)\\'" key)
|
||||
(let* ((user (match-string 1 key))
|
||||
(host (match-string 2 key))
|
||||
(secret
|
||||
@@ -879,7 +870,7 @@ from the user."
|
||||
magit-process-password-prompt-regexps string)))
|
||||
(process-send-string
|
||||
process (magit-process-kill-on-abort process
|
||||
(concat (or (when-let ((key (match-string 99 string)))
|
||||
(concat (or (and-let* ((key (match-string 99 string)))
|
||||
(run-hook-with-args-until-success
|
||||
'magit-process-find-password-functions key))
|
||||
(read-passwd prompt))
|
||||
@@ -958,7 +949,7 @@ as argument."
|
||||
(apply fn name buffer program args)))
|
||||
|
||||
(advice-add 'tramp-sh-handle-start-file-process :around
|
||||
'tramp-sh-handle-start-file-process--magit-tramp-process-environment)
|
||||
#'tramp-sh-handle-start-file-process--magit-tramp-process-environment)
|
||||
|
||||
(defun tramp-sh-handle-process-file--magit-tramp-process-environment
|
||||
(fn program &optional infile destination display &rest args)
|
||||
@@ -969,7 +960,7 @@ as argument."
|
||||
(apply fn program infile destination display args)))
|
||||
|
||||
(advice-add 'tramp-sh-handle-process-file :around
|
||||
'tramp-sh-handle-process-file--magit-tramp-process-environment)
|
||||
#'tramp-sh-handle-process-file--magit-tramp-process-environment)
|
||||
|
||||
(defvar magit-mode-line-process-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
@@ -1028,15 +1019,15 @@ If STR is supplied, it replaces the `mode-line-process' text."
|
||||
(let ((repokey (magit-repository-local-repository)))
|
||||
;; The following closure captures the repokey value, and is
|
||||
;; added to `pre-command-hook'.
|
||||
(cl-labels ((enable-magit-process-unset-mode-line
|
||||
() ;;; Remove ourself from the hook variable, so
|
||||
;;; that we only run once.
|
||||
(remove-hook 'pre-command-hook
|
||||
#'enable-magit-process-unset-mode-line)
|
||||
;; Clear the inhibit flag for the repository in
|
||||
;; which we set it.
|
||||
(magit-repository-local-set
|
||||
'inhibit-magit-process-unset-mode-line nil repokey)))
|
||||
(cl-labels ((enable-magit-process-unset-mode-line ()
|
||||
;; Remove ourself from the hook variable, so
|
||||
;; that we only run once.
|
||||
(remove-hook 'pre-command-hook
|
||||
#'enable-magit-process-unset-mode-line)
|
||||
;; Clear the inhibit flag for the repository in
|
||||
;; which we set it.
|
||||
(magit-repository-local-set
|
||||
'inhibit-magit-process-unset-mode-line nil repokey)))
|
||||
;; Set the inhibit flag until the next command is invoked.
|
||||
(magit-repository-local-set
|
||||
'inhibit-magit-process-unset-mode-line t repokey)
|
||||
@@ -1052,6 +1043,9 @@ If STR is supplied, it replaces the `mode-line-process' text."
|
||||
'magit-mode-line-process-error))
|
||||
(magit-process-unset-mode-line))))
|
||||
|
||||
(add-hook 'magit-refresh-buffer-hook
|
||||
#'magit-process-unset-mode-line-error-status)
|
||||
|
||||
(defun magit-process-unset-mode-line (&optional directory)
|
||||
"Remove the git command from the mode line."
|
||||
(let ((default-directory (or directory default-directory)))
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-pull.el --- update local objects and refs -*- lexical-binding: t -*-
|
||||
;;; magit-pull.el --- Update local objects and refs -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -87,13 +84,13 @@
|
||||
With a prefix argument or when the push-remote is either not
|
||||
configured or unusable, then let the user first configure the
|
||||
push-remote."
|
||||
:if 'magit-get-current-branch
|
||||
:description 'magit-pull--pushbranch-description
|
||||
:if #'magit-get-current-branch
|
||||
:description #'magit-pull--pushbranch-description
|
||||
(interactive (list (magit-pull-arguments)))
|
||||
(pcase-let ((`(,branch ,remote)
|
||||
(magit--select-push-remote "pull from there")))
|
||||
(run-hooks 'magit-credential-hook)
|
||||
(magit-run-git-async "pull" args remote branch)))
|
||||
(magit-run-git-with-editor "pull" args remote branch)))
|
||||
|
||||
(defun magit-pull--pushbranch-description ()
|
||||
;; Also used by `magit-rebase-onto-pushremote'.
|
||||
@@ -117,8 +114,8 @@ push-remote."
|
||||
With a prefix argument or when the upstream is either not
|
||||
configured or unusable, then let the user first configure
|
||||
the upstream."
|
||||
:if 'magit-get-current-branch
|
||||
:description 'magit-pull--upstream-description
|
||||
:if #'magit-get-current-branch
|
||||
:description #'magit-pull--upstream-description
|
||||
(interactive (list (magit-pull-arguments)))
|
||||
(let* ((branch (or (magit-get-current-branch)
|
||||
(user-error "No branch is checked out")))
|
||||
@@ -136,7 +133,7 @@ the upstream."
|
||||
(magit-run-git-with-editor "pull" args remote merge)))
|
||||
|
||||
(defun magit-pull--upstream-description ()
|
||||
(when-let ((branch (magit-get-current-branch)))
|
||||
(and-let* ((branch (magit-get-current-branch)))
|
||||
(or (magit-get-upstream-branch branch)
|
||||
(let ((remote (magit-get "branch" branch "remote"))
|
||||
(merge (magit-get "branch" branch "merge"))
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-push.el --- update remote objects and refs -*- lexical-binding: t -*-
|
||||
;;; magit-push.el --- Update remote objects and refs -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -83,14 +80,14 @@
|
||||
When the push-remote is not configured, then read the push-remote
|
||||
from the user, set it, and then push to it. With a prefix
|
||||
argument the push-remote can be changed before pushed to it."
|
||||
:if 'magit-get-current-branch
|
||||
:description 'magit-push--pushbranch-description
|
||||
:if #'magit-get-current-branch
|
||||
:description #'magit-push--pushbranch-description
|
||||
(interactive (list (magit-push-arguments)))
|
||||
(pcase-let ((`(,branch ,remote ,changed)
|
||||
(magit--select-push-remote "push there")))
|
||||
(when changed
|
||||
(magit-confirm 'set-and-push
|
||||
(replace-regexp-in-string
|
||||
(string-replace
|
||||
"%" "%%"
|
||||
(format "Really use \"%s\" as push-remote and push \"%s\" there"
|
||||
remote branch))))
|
||||
@@ -122,8 +119,8 @@ argument the push-remote can be changed before pushed to it."
|
||||
With a prefix argument or when the upstream is either not
|
||||
configured or unusable, then let the user first configure
|
||||
the upstream."
|
||||
:if 'magit-get-current-branch
|
||||
:description 'magit-push--upstream-description
|
||||
:if #'magit-get-current-branch
|
||||
:description #'magit-push--upstream-description
|
||||
(interactive (list (magit-push-arguments)))
|
||||
(let* ((branch (or (magit-get-current-branch)
|
||||
(user-error "No branch is checked out")))
|
||||
@@ -152,7 +149,7 @@ the upstream."
|
||||
;; is what the user wants to happen.
|
||||
(setq merge (concat "refs/heads/" merge)))
|
||||
(magit-confirm 'set-and-push
|
||||
(replace-regexp-in-string
|
||||
(string-replace
|
||||
"%" "%%"
|
||||
(format "Really use \"%s\" as upstream and push \"%s\" there"
|
||||
upstream branch))))
|
||||
@@ -161,7 +158,7 @@ the upstream."
|
||||
(magit-run-git-async "push" "-v" args remote (concat branch ":" merge))))
|
||||
|
||||
(defun magit-push--upstream-description ()
|
||||
(when-let ((branch (magit-get-current-branch)))
|
||||
(and-let* ((branch (magit-get-current-branch)))
|
||||
(or (magit-get-upstream-branch branch)
|
||||
(let ((remote (magit-get "branch" branch "remote"))
|
||||
(merge (magit-get "branch" branch "merge"))
|
||||
@@ -284,44 +281,73 @@ these Git variables: `push.default', `remote.pushDefault',
|
||||
|
||||
If you add this suffix to a transient prefix without explicitly
|
||||
specifying the description, then an attempt is made to predict
|
||||
what this command will do. For example:
|
||||
what this command will do. To add it use something like:
|
||||
|
||||
(transient-insert-suffix \\='magit-push \"p\"
|
||||
(transient-insert-suffix \\='magit-push \"o\"
|
||||
\\='(\"i\" magit-push-implicitly))"
|
||||
:description 'magit-push-implicitly--desc
|
||||
:description #'magit-push-implicitly--desc
|
||||
(interactive (list (magit-push-arguments)))
|
||||
(run-hooks 'magit-credential-hook)
|
||||
(magit-run-git-async "push" "-v" args))
|
||||
|
||||
(defun magit-push-implicitly--desc ()
|
||||
(let ((default (magit-get "push.default")))
|
||||
(unless (equal default "nothing")
|
||||
(or (when-let ((remote (or (magit-get-remote)
|
||||
(magit-primary-remote)))
|
||||
(refspec (magit-get "remote" remote "push")))
|
||||
(format "%s using %s"
|
||||
(magit--propertize-face remote 'magit-branch-remote)
|
||||
(magit--propertize-face refspec 'bold)))
|
||||
(--when-let (and (not (magit-get-push-branch))
|
||||
(magit-get-upstream-branch))
|
||||
(format "%s aka %s\n"
|
||||
(magit-branch-set-face it)
|
||||
(magit--propertize-face "@{upstream}" 'bold)))
|
||||
(--when-let (magit-get-push-branch)
|
||||
(format "%s aka %s\n"
|
||||
(magit-branch-set-face it)
|
||||
(magit--propertize-face "pushRemote" 'bold)))
|
||||
(--when-let (magit-get-@{push}-branch)
|
||||
(format "%s aka %s\n"
|
||||
(magit-branch-set-face it)
|
||||
(magit--propertize-face "@{push}" 'bold)))
|
||||
(format "using %s (%s is %s)\n"
|
||||
(magit--propertize-face "git push" 'bold)
|
||||
(magit--propertize-face "push.default" 'bold)
|
||||
(magit--propertize-face default 'bold))))))
|
||||
;; This implements the logic for git push as documented.
|
||||
;; First, we resolve a remote to use based on various remote and
|
||||
;; pushRemote options.
|
||||
;; Then, we resolve the refspec to use for the remote based on push
|
||||
;; and pushDefault options.
|
||||
;; Note that the remote and refspec to push are handled separately,
|
||||
;; so it doesn't make sense to talk about "pushing to upstream".
|
||||
;; Depending on the options, you could end up pushing to the
|
||||
;; "upstream" remote but not the "upstream" branch, and vice versa.
|
||||
(let* ((branch (magit-get-current-branch))
|
||||
(remote (or (magit-get-push-remote branch)
|
||||
;; Note: Avoid `magit-get-remote' because it
|
||||
;; filters out the local repo case (".").
|
||||
(magit-get "branch" branch "remote")
|
||||
(let ((remotes (magit-list-remotes)))
|
||||
(cond
|
||||
((and (magit-git-version>= "2.27")
|
||||
(= (length remotes) 1))
|
||||
(car remotes))
|
||||
((member "origin" remotes) "origin"))))))
|
||||
(if (null remote)
|
||||
"nothing (no remote)"
|
||||
(let ((refspec (magit-get "remote" remote "push")))
|
||||
(if refspec
|
||||
(format "to %s with refspecs %s"
|
||||
(magit--propertize-face remote 'bold)
|
||||
(magit--propertize-face refspec 'bold))
|
||||
(pcase (or (magit-get "push.default") "simple")
|
||||
("nothing" "nothing (due to push.default)")
|
||||
((or "current" "simple")
|
||||
(format "%s to %s"
|
||||
(magit--propertize-face branch 'magit-branch-current)
|
||||
(magit--propertize-face (format "%s/%s" remote branch)
|
||||
'magit-branch-remote)))
|
||||
((or "upstream" "tracking")
|
||||
(let ((ref (magit-get "branch" branch "merge")))
|
||||
(if ref
|
||||
(format "%s to %s"
|
||||
(magit--propertize-face branch 'magit-branch-current)
|
||||
(cond
|
||||
((string-prefix-p "refs/heads/" ref)
|
||||
(magit--propertize-face
|
||||
(format "%s/%s" remote
|
||||
(substring ref (length "refs/heads/")))
|
||||
'magit-branch-remote))
|
||||
((not (string-match "/" ref))
|
||||
(magit--propertize-face (format "%s/%s" remote ref)
|
||||
'magit-branch-remote))
|
||||
(t (format "%s as %s"
|
||||
(magit--propertize-face remote 'bold)
|
||||
(magit--propertize-face ref 'bold)))))
|
||||
"nothing (no upstream)")))
|
||||
("matching" (format "all matching to %s"
|
||||
(magit--propertize-face remote 'bold)))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-push-to-remote (remote args)
|
||||
;;;###autoload (autoload 'magit-push-to-remote "magit-push" nil t)
|
||||
(transient-define-suffix magit-push-to-remote (remote args)
|
||||
"Push to REMOTE without using an explicit refspec.
|
||||
The REMOTE is read in the minibuffer.
|
||||
|
||||
@@ -330,14 +356,20 @@ are the arguments specified in the popup buffer. No refspec
|
||||
arguments are used. Instead the behavior depends on at least
|
||||
these Git variables: `push.default', `remote.pushDefault',
|
||||
`branch.<branch>.pushRemote', `branch.<branch>.remote',
|
||||
`branch.<branch>.merge', and `remote.<remote>.push'."
|
||||
`branch.<branch>.merge', and `remote.<remote>.push'.
|
||||
|
||||
You can add this command as a suffix using something like:
|
||||
|
||||
(transient-insert-suffix \\='magit-push \"o\"
|
||||
\\='(\"x\" magit-push-to-remote))"
|
||||
:description #'magit-push-to-remote--desc
|
||||
(interactive (list (magit-read-remote "Push to remote")
|
||||
(magit-push-arguments)))
|
||||
(run-hooks 'magit-credential-hook)
|
||||
(magit-run-git-async "push" "-v" args remote))
|
||||
|
||||
(defun magit-push-to-remote--desc ()
|
||||
(format "using %s\n" (magit--propertize-face "git push <remote>" 'bold)))
|
||||
(format "using %s" (magit--propertize-face "git push <remote>" 'bold)))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-push)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-reflog.el --- inspect ref history -*- lexical-binding: t -*-
|
||||
;;; magit-reflog.el --- Inspect ref history -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -68,7 +65,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
|
||||
:group 'magit-log
|
||||
:group 'magit-margin
|
||||
:type magit-log-margin--custom-type
|
||||
:initialize 'magit-custom-initialize-reset
|
||||
:initialize #'magit-custom-initialize-reset
|
||||
:set-after '(magit-log-margin)
|
||||
:set (apply-partially #'magit-margin-set-variable 'magit-reflog-mode))
|
||||
|
||||
@@ -136,8 +133,8 @@ If `HEAD' is detached, then show the reflog for that instead."
|
||||
(defvar magit-reflog-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map magit-log-mode-map)
|
||||
(define-key map (kbd "C-c C-n") 'undefined)
|
||||
(define-key map (kbd "L") 'magit-margin-settings)
|
||||
(define-key map (kbd "C-c C-n") #'undefined)
|
||||
(define-key map (kbd "L") #'magit-margin-settings)
|
||||
map)
|
||||
"Keymap for `magit-reflog-mode'.")
|
||||
|
||||
@@ -156,7 +153,8 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
|
||||
\\{magit-reflog-mode-map}"
|
||||
:group 'magit-log
|
||||
(hack-dir-local-variables-non-file-buffer))
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(setq magit--imenu-item-types 'commit))
|
||||
|
||||
(defun magit-reflog-setup-buffer (ref)
|
||||
(require 'magit)
|
||||
@@ -167,7 +165,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
(defun magit-reflog-refresh-buffer ()
|
||||
(magit-set-header-line-format (concat "Reflog for " magit-buffer-refname))
|
||||
(magit-insert-section (reflogbuf)
|
||||
(magit-git-wash (apply-partially 'magit-log-wash-log 'reflog)
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'reflog)
|
||||
"reflog" "show" "--format=%h%x00%aN%x00%gd%x00%gs" "--date=raw"
|
||||
magit-buffer-log-args magit-buffer-refname "--")))
|
||||
|
||||
@@ -182,6 +180,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
("branch" . magit-reflog-checkout)
|
||||
("reset" . magit-reflog-reset)
|
||||
("rebase" . magit-reflog-rebase)
|
||||
("rewritten" . magit-reflog-rebase)
|
||||
("cherry-pick" . magit-reflog-cherry-pick)
|
||||
("initial" . magit-reflog-commit)
|
||||
("pull" . magit-reflog-remote)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-refs.el --- listing references -*- lexical-binding: t -*-
|
||||
;;; magit-refs.el --- Listing references -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -130,7 +127,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
|
||||
:group 'magit-margin
|
||||
:safe (lambda (val) (memq val '(all branch nil)))
|
||||
:type magit-log-margin--custom-type
|
||||
:initialize 'magit-custom-initialize-reset
|
||||
:initialize #'magit-custom-initialize-reset
|
||||
:set-after '(magit-log-margin)
|
||||
:set (apply-partially #'magit-margin-set-variable 'magit-refs-mode))
|
||||
|
||||
@@ -277,8 +274,8 @@ the outcome.
|
||||
(defvar magit-refs-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map magit-mode-map)
|
||||
(define-key map (kbd "C-y") 'magit-refs-set-show-commit-count)
|
||||
(define-key map (kbd "L") 'magit-margin-settings)
|
||||
(define-key map (kbd "C-y") #'magit-refs-set-show-commit-count)
|
||||
(define-key map (kbd "L") #'magit-margin-settings)
|
||||
map)
|
||||
"Keymap for `magit-refs-mode'.")
|
||||
|
||||
@@ -301,8 +298,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
\\{magit-refs-mode-map}"
|
||||
:group 'magit-refs
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(setq imenu-create-index-function
|
||||
#'magit-imenu--refs-create-index-function))
|
||||
(setq magit--imenu-group-types '(local remote tags)))
|
||||
|
||||
(defun magit-refs-setup-buffer (ref args)
|
||||
(magit-setup-buffer #'magit-refs-mode nil
|
||||
@@ -318,7 +314,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
(mapconcat #'identity magit-buffer-arguments " ")))
|
||||
(magit-insert-section (branchbuf)
|
||||
(magit-run-section-hook 'magit-refs-sections-hook))
|
||||
(add-hook 'kill-buffer-hook 'magit-preserve-section-visibility-cache))
|
||||
(add-hook 'kill-buffer-hook #'magit-preserve-section-visibility-cache))
|
||||
|
||||
(cl-defmethod magit-buffer-value (&context (major-mode magit-refs-mode))
|
||||
(cons magit-buffer-upstream magit-buffer-arguments))
|
||||
@@ -360,7 +356,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
((eq major-mode 'magit-refs-mode)
|
||||
(setq args magit-buffer-arguments))
|
||||
((and (memq use-buffer-args '(always selected))
|
||||
(when-let ((buffer (magit-get-mode-buffer
|
||||
(when-let* ((buffer (magit-get-mode-buffer ;debbugs#31840
|
||||
'magit-refs-mode nil
|
||||
(eq use-buffer-args 'selected))))
|
||||
(setq args (buffer-local-value 'magit-buffer-arguments buffer))
|
||||
@@ -374,14 +370,14 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
:class 'transient-option
|
||||
:key "-c"
|
||||
:argument "--contains="
|
||||
:reader 'magit-transient-read-revision)
|
||||
:reader #'magit-transient-read-revision)
|
||||
|
||||
(transient-define-argument magit-for-each-ref:--sort ()
|
||||
:description "Sort"
|
||||
:class 'transient-option
|
||||
:key "-s"
|
||||
:argument "--sort="
|
||||
:reader 'magit-read-ref-sort)
|
||||
:reader #'magit-read-ref-sort)
|
||||
|
||||
(defun magit-read-ref-sort (prompt initial-input _history)
|
||||
(magit-completing-read prompt
|
||||
@@ -430,10 +426,12 @@ This command behaves just like `magit-show-commit', except if
|
||||
point is on a reference in a `magit-refs-mode' buffer (a buffer
|
||||
listing branches and tags), in which case the behavior may be
|
||||
different, but only if you have customized the option
|
||||
`magit-visit-ref-behavior' (which see)."
|
||||
`magit-visit-ref-behavior' (which see). When invoked from a
|
||||
menu this command always behaves like `magit-show-commit'."
|
||||
(interactive)
|
||||
(if (and (derived-mode-p 'magit-refs-mode)
|
||||
(magit-section-match '(branch tag)))
|
||||
(magit-section-match '(branch tag))
|
||||
(not (magit-menu-position)))
|
||||
(let ((ref (oref (magit-current-section) value)))
|
||||
(cond (current-prefix-arg
|
||||
(cond ((memq 'focus-on-ref magit-visit-ref-behavior)
|
||||
@@ -477,41 +475,55 @@ Branch %s already exists.
|
||||
|
||||
(defvar magit-remote-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-delete-thing] 'magit-remote-remove)
|
||||
(define-key map "R" 'magit-remote-rename)
|
||||
(magit-menu-set map [magit-delete-thing] #'magit-remote-remove "Remove %m")
|
||||
(magit-menu-set map [magit-file-rename] #'magit-remote-rename "Rename %s")
|
||||
map)
|
||||
"Keymap for `remote' sections.")
|
||||
|
||||
(defvar magit-branch-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-visit-ref)
|
||||
(define-key map [remap magit-delete-thing] 'magit-branch-delete)
|
||||
(define-key map "R" 'magit-branch-rename)
|
||||
(magit-menu-set map [magit-visit-thing] #'magit-visit-ref "Visit commit")
|
||||
(magit-menu-set map [magit-delete-thing] #'magit-branch-delete "Delete %m")
|
||||
(magit-menu-set map [magit-file-rename] #'magit-branch-rename "Rename %s")
|
||||
map)
|
||||
"Keymap for `branch' sections.")
|
||||
|
||||
(defvar magit-tag-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-visit-ref)
|
||||
(define-key map [remap magit-delete-thing] 'magit-tag-delete)
|
||||
(magit-menu-set map [magit-visit-thing] #'magit-visit-ref "Visit %s")
|
||||
(magit-menu-set map [magit-delete-thing] #'magit-tag-delete "Delete %m")
|
||||
map)
|
||||
"Keymap for `tag' sections.")
|
||||
|
||||
(defun magit--painted-branch-as-menu-section (section)
|
||||
(and-let* ((branch (and (magit-section-match 'commit)
|
||||
(magit--painted-branch-at-point))))
|
||||
(let ((dummy (magit-section :type 'branch :value branch)))
|
||||
(oset dummy keymap magit-branch-section-map)
|
||||
(dolist (slot '(start content hidden parent children))
|
||||
(when (slot-boundp section slot)
|
||||
(setf (eieio-oref dummy slot)
|
||||
(eieio-oref section slot))))
|
||||
dummy)))
|
||||
|
||||
(add-hook 'magit-menu-alternative-section-hook
|
||||
#'magit--painted-branch-as-menu-section)
|
||||
|
||||
(defun magit-insert-branch-description ()
|
||||
"Insert header containing the description of the current branch.
|
||||
Insert a header line with the name and description of the
|
||||
current branch. The description is taken from the Git variable
|
||||
`branch.<NAME>.description'; if that is undefined then no header
|
||||
line is inserted at all."
|
||||
(when-let ((branch (magit-get-current-branch))
|
||||
(desc (magit-get "branch" branch "description"))
|
||||
(desc (split-string desc "\n")))
|
||||
(when-let* ((branch (magit-get-current-branch))
|
||||
(desc (magit-get "branch" branch "description"))
|
||||
(desc (split-string desc "\n")))
|
||||
(when (equal (car (last desc)) "")
|
||||
(setq desc (butlast desc)))
|
||||
(magit-insert-section (branchdesc branch t)
|
||||
(magit-insert-heading branch ": " (car desc))
|
||||
(when (cdr desc)
|
||||
(insert (mapconcat 'identity (cdr desc) "\n"))
|
||||
(insert (mapconcat #'identity (cdr desc) "\n"))
|
||||
(insert "\n\n")))))
|
||||
|
||||
(defun magit-insert-tags ()
|
||||
@@ -604,7 +616,7 @@ line is inserted at all."
|
||||
(magit-make-margin-overlay nil t)))
|
||||
|
||||
(defun magit-refs--format-local-branches ()
|
||||
(let ((lines (-keep 'magit-refs--format-local-branch
|
||||
(let ((lines (-keep #'magit-refs--format-local-branch
|
||||
(magit-git-lines
|
||||
"for-each-ref"
|
||||
(concat "--format=\
|
||||
@@ -743,7 +755,7 @@ line is inserted at all."
|
||||
(magit-insert-section-body
|
||||
(let ((start (point))
|
||||
(magit-insert-section--current nil))
|
||||
(magit-git-wash (apply-partially 'magit-log-wash-log 'cherry)
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'cherry)
|
||||
"cherry" "-v" (magit-abbrev-arg) magit-buffer-upstream ref)
|
||||
(if (= (point) start)
|
||||
(message "No cherries for %s" ref)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-remote.el --- transfer Git commits -*- lexical-binding: t -*-
|
||||
;;; magit-remote.el --- Transfer Git commits -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -114,7 +111,7 @@ has to be used to view and change remote related variables."
|
||||
(if (pcase (list magit-remote-add-set-remote.pushDefault
|
||||
(magit-get "remote.pushDefault"))
|
||||
(`(,(pred stringp) ,_) t)
|
||||
((or `(ask ,_) `(ask-if-unset nil))
|
||||
((or `(ask ,_) '(ask-if-unset nil))
|
||||
(y-or-n-p (format "Set `remote.pushDefault' to \"%s\"? " remote))))
|
||||
(progn (magit-call-git "remote" "add" args remote url)
|
||||
(setf (magit-get "remote.pushDefault") remote)
|
||||
@@ -205,7 +202,7 @@ the now stale refspecs. Other stale branches are not removed."
|
||||
(magit-call-git "remote" "rm" remote))
|
||||
(?a "or [a]abort"
|
||||
(user-error "Abort")))
|
||||
(if (if (= (length stale) 1)
|
||||
(if (if (length= stale 1)
|
||||
(pcase-let ((`(,refspec . ,refs) (car stale)))
|
||||
(magit-confirm 'prune-stale-refspecs
|
||||
(format "Prune stale refspec %s and branch %%s" refspec)
|
||||
@@ -268,8 +265,8 @@ refspec."
|
||||
(magit-read-remote "Delete remote"))))
|
||||
(let ((refspecs (magit-get-all "remote" remote "fetch"))
|
||||
(standard (format "+refs/heads/*:refs/remotes/%s/*" remote)))
|
||||
(when (and (= (length refspecs) 1)
|
||||
(not (string-match-p "\\*" (car refspecs)))
|
||||
(when (and (length= refspecs 1)
|
||||
(not (string-search "*" (car refspecs)))
|
||||
(yes-or-no-p (format "Also replace refspec %s with %s? "
|
||||
(car refspecs)
|
||||
standard)))
|
||||
@@ -309,20 +306,20 @@ refspec."
|
||||
|
||||
(transient-define-infix magit-remote.<remote>.url ()
|
||||
:class 'magit--git-variable:urls
|
||||
:scope 'magit--read-remote-scope
|
||||
:scope #'magit--read-remote-scope
|
||||
:variable "remote.%s.url"
|
||||
:multi-value t
|
||||
:history-key 'magit-remote.<remote>.*url)
|
||||
|
||||
(transient-define-infix magit-remote.<remote>.fetch ()
|
||||
:class 'magit--git-variable
|
||||
:scope 'magit--read-remote-scope
|
||||
:scope #'magit--read-remote-scope
|
||||
:variable "remote.%s.fetch"
|
||||
:multi-value t)
|
||||
|
||||
(transient-define-infix magit-remote.<remote>.pushurl ()
|
||||
:class 'magit--git-variable:urls
|
||||
:scope 'magit--read-remote-scope
|
||||
:scope #'magit--read-remote-scope
|
||||
:variable "remote.%s.pushurl"
|
||||
:multi-value t
|
||||
:history-key 'magit-remote.<remote>.*url
|
||||
@@ -330,12 +327,12 @@ refspec."
|
||||
|
||||
(transient-define-infix magit-remote.<remote>.push ()
|
||||
:class 'magit--git-variable
|
||||
:scope 'magit--read-remote-scope
|
||||
:scope #'magit--read-remote-scope
|
||||
:variable "remote.%s.push")
|
||||
|
||||
(transient-define-infix magit-remote.<remote>.tagopt ()
|
||||
:class 'magit--git-variable:choices
|
||||
:scope 'magit--read-remote-scope
|
||||
:scope #'magit--read-remote-scope
|
||||
:variable "remote.%s.tagOpt"
|
||||
:choices '("--no-tags" "--tags"))
|
||||
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-repos.el --- listing repositories -*- lexical-binding: t -*-
|
||||
;;; magit-repos.el --- Listing repositories -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -64,18 +61,21 @@ This option controls which repositories are being listed by
|
||||
:package-version '(magit . "2.9.0")
|
||||
:group 'magit-repolist
|
||||
:type 'hook
|
||||
:get 'magit-hook-custom-get
|
||||
:get #'magit-hook-custom-get
|
||||
:options '(hl-line-mode))
|
||||
|
||||
(defcustom magit-repolist-columns
|
||||
'(("Name" 25 magit-repolist-column-ident nil)
|
||||
("Version" 25 magit-repolist-column-version nil)
|
||||
("Version" 25 magit-repolist-column-version
|
||||
((:sort magit-repolist-version<)))
|
||||
("B<U" 3 magit-repolist-column-unpulled-from-upstream
|
||||
((:right-align t)
|
||||
(:help-echo "Upstream changes not in branch")))
|
||||
(;; (:help-echo "Upstream changes not in branch")
|
||||
(:right-align t)
|
||||
(:sort <)))
|
||||
("B>U" 3 magit-repolist-column-unpushed-to-upstream
|
||||
((:right-align t)
|
||||
(:help-echo "Local changes not in upstream")))
|
||||
(;; (:help-echo "Local changes not in upstream")
|
||||
(:right-align t)
|
||||
(:sort <)))
|
||||
("Path" 99 magit-repolist-column-path nil))
|
||||
"List of columns displayed by `magit-list-repositories'.
|
||||
|
||||
@@ -86,9 +86,15 @@ of the column. FORMAT is a function that is called with one
|
||||
argument, the repository identification (usually its basename),
|
||||
and with `default-directory' bound to the toplevel of its working
|
||||
tree. It has to return a string to be inserted or nil. PROPS is
|
||||
an alist that supports the keys `:right-align' and `:pad-right'.
|
||||
Some entries also use `:help-echo', but `tabulated-list' does not
|
||||
actually support that yet.
|
||||
an alist that supports the keys `:right-align', `:pad-right' and
|
||||
`:sort'.
|
||||
|
||||
The `:sort' function has a weird interface described in the
|
||||
docstring of `tabulated-list--get-sort'. Alternatively `<' and
|
||||
`magit-repolist-version<' can be used as those functions are
|
||||
automatically replaced with functions that satisfy the interface.
|
||||
Set `:sort' to nil to inhibit sorting; if unspecifed, then the
|
||||
column is sortable using the default sorter.
|
||||
|
||||
You may wish to display a range of numeric columns using just one
|
||||
character per column and without any padding between columns, in
|
||||
@@ -105,6 +111,7 @@ than 9."
|
||||
(list (choice :tag "Property"
|
||||
(const :right-align)
|
||||
(const :pad-right)
|
||||
(const :sort)
|
||||
(symbol))
|
||||
(sexp :tag "Value"))))))
|
||||
|
||||
@@ -137,7 +144,7 @@ non-nil, means to invert the resulting sort."
|
||||
(boolean :tag "Flip order"))))
|
||||
|
||||
;;; List Repositories
|
||||
;;;; Command
|
||||
;;;; List Commands
|
||||
;;;###autoload
|
||||
(defun magit-list-repositories ()
|
||||
"Display a list of repositories.
|
||||
@@ -147,14 +154,7 @@ repositories are displayed."
|
||||
(interactive)
|
||||
(magit-repolist-setup (default-value 'magit-repolist-columns)))
|
||||
|
||||
;;;; Mode
|
||||
|
||||
(defvar magit-repolist-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map tabulated-list-mode-map)
|
||||
(define-key map (kbd "C-m") 'magit-repolist-status)
|
||||
map)
|
||||
"Local keymap for Magit-Repolist mode buffers.")
|
||||
;;;; Mode Commands
|
||||
|
||||
(defun magit-repolist-status (&optional _button)
|
||||
"Show the status for the repository at point."
|
||||
@@ -163,15 +163,116 @@ repositories are displayed."
|
||||
(magit-status-setup-buffer (expand-file-name it))
|
||||
(user-error "There is no repository at point")))
|
||||
|
||||
(defun magit-repolist-mark ()
|
||||
"Mark a repository and move to the next line."
|
||||
(interactive)
|
||||
(magit-repolist--ensure-padding)
|
||||
(tabulated-list-put-tag "*" t))
|
||||
|
||||
(defun magit-repolist-unmark ()
|
||||
"Unmark a repository and move to the next line."
|
||||
(interactive)
|
||||
(tabulated-list-put-tag " " t))
|
||||
|
||||
(defun magit-repolist-fetch (repos)
|
||||
"Fetch all marked or listed repositories."
|
||||
(interactive (list (magit-repolist--get-repos ?*)))
|
||||
(run-hooks 'magit-credential-hook)
|
||||
(magit-repolist--mapc (apply-partially #'magit-run-git "remote" "update")
|
||||
repos "Fetching in %s..."))
|
||||
|
||||
(defun magit-repolist-find-file-other-frame (repos file)
|
||||
"Find a file in all marked or listed repositories."
|
||||
(interactive (list (magit-repolist--get-repos ?*)
|
||||
(read-string "Find file in repositories: ")))
|
||||
(magit-repolist--mapc (apply-partially #'find-file-other-frame file) repos))
|
||||
|
||||
(defun magit-repolist--ensure-padding ()
|
||||
"Set `tabulated-list-padding' to 2, unless that is already non-zero."
|
||||
(when (zerop tabulated-list-padding)
|
||||
(setq tabulated-list-padding 2)
|
||||
(tabulated-list-init-header)
|
||||
(tabulated-list-print t)))
|
||||
|
||||
(defun magit-repolist--get-repos (&optional char)
|
||||
"Return marked repositories or `all' if none are marked.
|
||||
If optional CHAR is non-nil, then only return repositories
|
||||
marked with that character. If no repositories are marked
|
||||
then ask whether to act on all repositories instead."
|
||||
(or (magit-repolist--marked-repos char)
|
||||
(if (magit-confirm 'repolist-all
|
||||
"Nothing selected. Act on ALL displayed repositories")
|
||||
'all
|
||||
(user-error "Abort"))))
|
||||
|
||||
(defun magit-repolist--marked-repos (&optional char)
|
||||
"Return marked repositories.
|
||||
If optional CHAR is non-nil, then only return repositories
|
||||
marked with that character."
|
||||
(let (c list)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (not (eobp))
|
||||
(setq c (char-after))
|
||||
(unless (eq c ?\s)
|
||||
(if char
|
||||
(when (eq c char)
|
||||
(push (tabulated-list-get-id) list))
|
||||
(push (cons c (tabulated-list-get-id)) list)))
|
||||
(forward-line)))
|
||||
list))
|
||||
|
||||
(defun magit-repolist--mapc (fn repos &optional msg)
|
||||
"Apply FN to each directory in REPOS for side effects only.
|
||||
If REPOS is the symbol `all', then call FN for all displayed
|
||||
repositories. When FN is called, `default-directory' is bound to
|
||||
the top-level directory of the current repository. If optional
|
||||
MSG is non-nil then that is displayed around each call to FN.
|
||||
If it contains \"%s\" then the directory is substituted for that."
|
||||
(when (eq repos 'all)
|
||||
(setq repos nil)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (not (eobp))
|
||||
(push (tabulated-list-get-id) repos)
|
||||
(forward-line)))
|
||||
(setq repos (nreverse repos)))
|
||||
(let ((base default-directory)
|
||||
(len (length repos))
|
||||
(i 0))
|
||||
(mapc (lambda (repo)
|
||||
(let ((default-directory
|
||||
(file-name-as-directory (expand-file-name repo base))))
|
||||
(if msg
|
||||
(let ((msg (concat (format "(%s/%s) " (cl-incf i) len)
|
||||
(format msg default-directory))))
|
||||
(message msg)
|
||||
(funcall fn)
|
||||
(message (concat msg "done")))
|
||||
(funcall fn))))
|
||||
repos)))
|
||||
|
||||
;;;; Mode
|
||||
|
||||
(defvar magit-repolist-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map tabulated-list-mode-map)
|
||||
(define-key map (kbd "C-m") #'magit-repolist-status)
|
||||
(define-key map (kbd "m") #'magit-repolist-mark)
|
||||
(define-key map (kbd "u") #'magit-repolist-unmark)
|
||||
(define-key map (kbd "f") #'magit-repolist-fetch)
|
||||
(define-key map (kbd "5") #'magit-repolist-find-file-other-frame)
|
||||
map)
|
||||
"Local keymap for Magit-Repolist mode buffers.")
|
||||
|
||||
(define-derived-mode magit-repolist-mode tabulated-list-mode "Repos"
|
||||
"Major mode for browsing a list of Git repositories."
|
||||
(setq-local x-stretch-cursor nil)
|
||||
(setq tabulated-list-padding 0)
|
||||
(add-hook 'tabulated-list-revert-hook 'magit-repolist-refresh nil t)
|
||||
(add-hook 'tabulated-list-revert-hook #'magit-repolist-refresh nil t)
|
||||
(setq imenu-prev-index-position-function
|
||||
'magit-imenu--repolist-prev-index-position-function)
|
||||
(setq imenu-extract-index-name-function
|
||||
'magit-imenu--repolist-extract-index-name-function))
|
||||
#'magit-repolist--imenu-prev-index-position)
|
||||
(setq imenu-extract-index-name-function #'tabulated-list-get-id))
|
||||
|
||||
(defun magit-repolist-setup (columns)
|
||||
(unless magit-repository-directories
|
||||
@@ -180,10 +281,11 @@ repositories are displayed."
|
||||
(with-current-buffer (get-buffer-create "*Magit Repositories*")
|
||||
(magit-repolist-mode)
|
||||
(setq-local magit-repolist-columns columns)
|
||||
(magit-repolist-setup-1)
|
||||
(magit-repolist-refresh)
|
||||
(switch-to-buffer (current-buffer))))
|
||||
|
||||
(defun magit-repolist-refresh ()
|
||||
(defun magit-repolist-setup-1 ()
|
||||
(unless tabulated-list-sort-key
|
||||
(setq tabulated-list-sort-key
|
||||
(pcase-let ((`(,column . ,flip) magit-repolist-sort-key))
|
||||
@@ -191,10 +293,25 @@ repositories are displayed."
|
||||
(caar magit-repolist-columns))
|
||||
flip))))
|
||||
(setq tabulated-list-format
|
||||
(vconcat (mapcar (pcase-lambda (`(,title ,width ,_fn ,props))
|
||||
(nconc (list title width t)
|
||||
(-flatten props)))
|
||||
magit-repolist-columns)))
|
||||
(vconcat (-map-indexed
|
||||
(lambda (idx column)
|
||||
(pcase-let* ((`(,title ,width ,_fn ,props) column)
|
||||
(sort-set (assoc :sort props))
|
||||
(sort-fn (cadr sort-set)))
|
||||
(nconc (list title width
|
||||
(cond ((eq sort-fn '<)
|
||||
(magit-repolist-make-sorter
|
||||
sort-fn #'string-to-number idx))
|
||||
((eq sort-fn 'magit-repolist-version<)
|
||||
(magit-repolist-make-sorter
|
||||
sort-fn #'identity idx))
|
||||
(sort-fn sort-fn)
|
||||
(sort-set nil)
|
||||
(t t)))
|
||||
(flatten-tree props))))
|
||||
magit-repolist-columns))))
|
||||
|
||||
(defun magit-repolist-refresh ()
|
||||
(setq tabulated-list-entries
|
||||
(mapcar (pcase-lambda (`(,id . ,path))
|
||||
(let ((default-directory path))
|
||||
@@ -216,8 +333,24 @@ repositories are displayed."
|
||||
(tabulated-list-print t)
|
||||
(message "Listing repositories...done"))
|
||||
|
||||
(defun magit-repolist--imenu-prev-index-position ()
|
||||
(and (not (bobp))
|
||||
(forward-line -1)))
|
||||
|
||||
;;;; Columns
|
||||
|
||||
(defun magit-repolist-make-sorter (sort-predicate convert-cell column-idx)
|
||||
"Return a function suitable as a sorter for tabulated lists.
|
||||
See `tabulated-list--get-sorter'. Given a more reasonable API
|
||||
this would not be necessary and one could just use SORT-PREDICATE
|
||||
directly. CONVERT-CELL can be used to turn the cell value, which
|
||||
is always a string back into e.g. a number. COLUMN-IDX has to be
|
||||
the index of the column that uses the returned sorter function."
|
||||
(lambda (a b)
|
||||
(funcall sort-predicate
|
||||
(funcall convert-cell (aref (cadr a) column-idx))
|
||||
(funcall convert-cell (aref (cadr b) column-idx)))))
|
||||
|
||||
(defun magit-repolist-column-ident (spec)
|
||||
"Insert the identification of the repository.
|
||||
Usually this is just its basename."
|
||||
@@ -227,26 +360,47 @@ Usually this is just its basename."
|
||||
"Insert the absolute path of the repository."
|
||||
(abbreviate-file-name default-directory))
|
||||
|
||||
(defvar magit-repolist-column-version-regexp "\
|
||||
\\(?1:-\\(?2:[0-9]*\\)\
|
||||
\\(?3:-g[a-z0-9]*\\)\\)?\
|
||||
\\(?:-\\(?4:dirty\\)\\)\
|
||||
?\\'")
|
||||
|
||||
(defvar magit-repolist-column-version-resume-regexp
|
||||
"\\`Resume development\\'")
|
||||
|
||||
(defun magit-repolist-column-version (_)
|
||||
"Insert a description of the repository's `HEAD' revision."
|
||||
(when-let ((v (or (magit-git-string "describe" "--tags" "--dirty")
|
||||
(and-let* ((v (or (magit-git-string "describe" "--tags" "--dirty")
|
||||
;; If there are no tags, use the date in MELPA format.
|
||||
(magit-git-string "show" "--no-patch" "--format=%cd-g%h"
|
||||
(magit-rev-format "%cd-g%h" nil
|
||||
"--date=format:%Y%m%d.%H%M"))))
|
||||
(save-match-data
|
||||
(when (string-match
|
||||
"\\(?:-\\([0-9]*\\)-g[a-z0-9]*\\)?\\(?:-\\(dirty\\)\\)?\\'" v)
|
||||
(when (string-match magit-repolist-column-version-regexp v)
|
||||
(magit--put-face (match-beginning 0) (match-end 0) 'shadow v)
|
||||
(when (match-end 1)
|
||||
(magit--put-face (match-beginning 1) (match-end 1) 'bold v))
|
||||
(when (match-end 2)
|
||||
(magit--put-face (match-beginning 2) (match-end 2) 'error v)))
|
||||
(magit--put-face (match-beginning 2) (match-end 2) 'bold v))
|
||||
(when (match-end 4)
|
||||
(magit--put-face (match-beginning 4) (match-end 4) 'error v))
|
||||
(when (and (equal (match-string 2 v) "1")
|
||||
(string-match-p magit-repolist-column-version-resume-regexp
|
||||
(magit-rev-format "%s")))
|
||||
(setq v (replace-match (propertize "+" 'face 'shadow) t t v 1))))
|
||||
(if (and v (string-match "\\`[0-9]" v))
|
||||
(concat " " v)
|
||||
(when (and v (string-match "\\`[^0-9]+" v))
|
||||
(magit--put-face 0 (match-end 0) 'shadow v))
|
||||
v))))
|
||||
|
||||
(defun magit-repolist-version< (a b)
|
||||
(save-match-data
|
||||
(let ((re "[0-9]+\\(\\.[0-9]*\\)*"))
|
||||
(setq a (and (string-match re a) (match-string 0 a)))
|
||||
(setq b (and (string-match re b) (match-string 0 b)))
|
||||
(cond ((and a b) (version< a b))
|
||||
(b nil)
|
||||
(t t)))))
|
||||
|
||||
(defun magit-repolist-column-branch (_)
|
||||
"Insert the current branch."
|
||||
(let ((branch (magit-get-current-branch)))
|
||||
@@ -281,23 +435,23 @@ which only lists the first one found."
|
||||
|
||||
(defun magit-repolist-column-unpulled-from-upstream (spec)
|
||||
"Insert number of upstream commits not in the current branch."
|
||||
(--when-let (magit-get-upstream-branch)
|
||||
(magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" it)) spec)))
|
||||
(and-let* ((br (magit-get-upstream-branch)))
|
||||
(magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" br)) spec)))
|
||||
|
||||
(defun magit-repolist-column-unpulled-from-pushremote (spec)
|
||||
"Insert number of commits in the push branch but not the current branch."
|
||||
(--when-let (magit-get-push-branch nil t)
|
||||
(magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" it)) spec)))
|
||||
(and-let* ((br (magit-get-push-branch nil t)))
|
||||
(magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" br)) spec)))
|
||||
|
||||
(defun magit-repolist-column-unpushed-to-upstream (spec)
|
||||
"Insert number of commits in the current branch but not its upstream."
|
||||
(--when-let (magit-get-upstream-branch)
|
||||
(magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" it)) spec)))
|
||||
(and-let* ((br (magit-get-upstream-branch)))
|
||||
(magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" br)) spec)))
|
||||
|
||||
(defun magit-repolist-column-unpushed-to-pushremote (spec)
|
||||
"Insert number of commits in the current branch but not its push branch."
|
||||
(--when-let (magit-get-push-branch nil t)
|
||||
(magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" it)) spec)))
|
||||
(and-let* ((br (magit-get-push-branch nil t)))
|
||||
(magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" br)) spec)))
|
||||
|
||||
(defun magit-repolist-column-branches (spec)
|
||||
"Insert number of branches."
|
||||
@@ -359,12 +513,12 @@ instead."
|
||||
directory-files-no-dot-files-regexp t)))))
|
||||
|
||||
(defun magit-list-repos-uniquify (alist)
|
||||
(let (result (dict (make-hash-table :test 'equal)))
|
||||
(let (result (dict (make-hash-table :test #'equal)))
|
||||
(dolist (a (delete-dups alist))
|
||||
(puthash (car a) (cons (cdr a) (gethash (car a) dict)) dict))
|
||||
(maphash
|
||||
(lambda (key value)
|
||||
(if (= (length value) 1)
|
||||
(if (length= value 1)
|
||||
(push (cons key (car value)) result)
|
||||
(setq result
|
||||
(append result
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-reset.el --- reset fuctionality -*- lexical-binding: t -*-
|
||||
;;; magit-reset.el --- Reset functionality -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -31,6 +28,8 @@
|
||||
|
||||
(require 'magit)
|
||||
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload (autoload 'magit-reset "magit" nil t)
|
||||
(transient-define-prefix magit-reset ()
|
||||
"Reset the `HEAD', index and/or worktree to a previous state."
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-sequence.el --- history manipulation in Magit -*- lexical-binding: t -*-
|
||||
;;; magit-sequence.el --- History manipulation in Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2011-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -95,8 +92,8 @@
|
||||
"Resume the current cherry-pick or revert sequence."
|
||||
(interactive)
|
||||
(if (magit-sequencer-in-progress-p)
|
||||
(if (magit-anything-unstaged-p t)
|
||||
(user-error "Cannot continue due to unstaged changes")
|
||||
(if (magit-anything-unmerged-p)
|
||||
(user-error "Cannot continue due to unresolved conflicts")
|
||||
(magit-run-git-sequencer
|
||||
(if (magit-revert-in-progress-p) "revert" "cherry-pick") "--continue"))
|
||||
(user-error "No cherry-pick or revert in progress")))
|
||||
@@ -165,7 +162,7 @@ This discards all changes made since the sequence started."
|
||||
:class 'transient-option
|
||||
:shortarg "-m"
|
||||
:argument "--mainline="
|
||||
:reader 'transient-read-number-N+)
|
||||
:reader #'transient-read-number-N+)
|
||||
|
||||
(defun magit-cherry-pick-read-args (prompt)
|
||||
(list (or (nreverse (magit-region-values 'commit))
|
||||
@@ -176,8 +173,8 @@ This discards all changes made since the sequence started."
|
||||
(declare (indent defun))
|
||||
(let ((commits (or (nreverse (magit-region-values 'commit))
|
||||
(list (funcall (if away
|
||||
'magit-read-branch-or-commit
|
||||
'magit-read-other-branch-or-commit)
|
||||
#'magit-read-branch-or-commit
|
||||
#'magit-read-other-branch-or-commit)
|
||||
(format "%s cherry" (capitalize verb))))))
|
||||
(current (or (magit-get-current-branch)
|
||||
(and allow-detached (magit-rev-parse "HEAD")))))
|
||||
@@ -186,8 +183,8 @@ This discards all changes made since the sequence started."
|
||||
(let ((reachable (magit-rev-ancestor-p (car commits) current))
|
||||
(msg "Cannot %s cherries that %s reachable from HEAD"))
|
||||
(pcase (list away reachable)
|
||||
(`(nil t) (user-error msg verb "are"))
|
||||
(`(t nil) (user-error msg verb "are not"))))
|
||||
('(nil t) (user-error msg verb "are"))
|
||||
('(t nil) (user-error msg verb "are not"))))
|
||||
`(,commits
|
||||
,@(funcall fn commits)
|
||||
,(transient-args 'magit-cherry-pick))))
|
||||
@@ -313,12 +310,11 @@ the process manually."
|
||||
(magit-refresh)))
|
||||
(t
|
||||
(magit-git "checkout" src)
|
||||
(let ((process-environment process-environment))
|
||||
(push (format "%s=%s -i -ne '/^pick (%s)/ or print'"
|
||||
"GIT_SEQUENCE_EDITOR"
|
||||
magit-perl-executable
|
||||
(mapconcat #'magit-rev-abbrev commits "|"))
|
||||
process-environment)
|
||||
(with-environment-variables
|
||||
(("GIT_SEQUENCE_EDITOR"
|
||||
(format "%s -i -ne '/^pick (%s)/ or print'"
|
||||
magit-perl-executable
|
||||
(mapconcat #'magit-rev-abbrev commits "|"))))
|
||||
(magit-run-git-sequencer "rebase" "-i" keep))
|
||||
(when checkout-dst
|
||||
(set-process-sentinel
|
||||
@@ -334,13 +330,13 @@ the process manually."
|
||||
(defun magit--cherry-pick (commits args &optional revert)
|
||||
(let ((command (if revert "revert" "cherry-pick")))
|
||||
(when (stringp commits)
|
||||
(setq commits (if (string-match-p "\\.\\." commits)
|
||||
(setq commits (if (string-search ".." commits)
|
||||
(split-string commits "\\.\\.")
|
||||
(list commits))))
|
||||
(magit-run-git-sequencer
|
||||
(if revert "revert" "cherry-pick")
|
||||
(pcase-let ((`(,merge ,non-merge)
|
||||
(-separate 'magit-merge-commit-p commits)))
|
||||
(-separate #'magit-merge-commit-p commits)))
|
||||
(cond
|
||||
((not merge)
|
||||
(--remove (string-prefix-p "--mainline=" it) args))
|
||||
@@ -357,7 +353,11 @@ the process manually."
|
||||
|
||||
(defun magit-cherry-pick-in-progress-p ()
|
||||
;; .git/sequencer/todo does not exist when there is only one commit left.
|
||||
(file-exists-p (magit-git-dir "CHERRY_PICK_HEAD")))
|
||||
(or (file-exists-p (magit-git-dir "CHERRY_PICK_HEAD"))
|
||||
;; And CHERRY_PICK_HEAD does not exist when a conflict happens
|
||||
;; while picking a series of commits with --no-commit.
|
||||
(when-let ((line (magit-file-line (magit-git-dir "sequencer/todo"))))
|
||||
(string-prefix-p "pick" line))))
|
||||
|
||||
;;; Revert
|
||||
|
||||
@@ -409,7 +409,11 @@ without prompting."
|
||||
|
||||
(defun magit-revert-in-progress-p ()
|
||||
;; .git/sequencer/todo does not exist when there is only one commit left.
|
||||
(file-exists-p (magit-git-dir "REVERT_HEAD")))
|
||||
(or (file-exists-p (magit-git-dir "REVERT_HEAD"))
|
||||
;; And REVERT_HEAD does not exist when a conflict happens while
|
||||
;; reverting a series of commits with --no-commit.
|
||||
(when-let ((line (magit-file-line (magit-git-dir "sequencer/todo"))))
|
||||
(string-prefix-p "revert" line))))
|
||||
|
||||
;;; Patch
|
||||
|
||||
@@ -448,7 +452,7 @@ without prompting."
|
||||
:class 'transient-option
|
||||
:argument "-p"
|
||||
:allow-empty t
|
||||
:reader 'transient-read-number-N+)
|
||||
:reader #'transient-read-number-N+)
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-am-apply-patches (&optional files args)
|
||||
@@ -519,9 +523,12 @@ This discards all changes made since the sequence started."
|
||||
("-r" "Rebase merges" ("-r" "--rebase-merges=")
|
||||
magit-rebase-merges-select-mode
|
||||
:if (lambda () (magit-git-version>= "2.18.0")))
|
||||
("-u" "Update branches" "--update-refs"
|
||||
:if (lambda () (magit-git-version>= "2.38.0")))
|
||||
(7 magit-merge:--strategy)
|
||||
(7 magit-merge:--strategy-option)
|
||||
(7 "=X" magit-diff:--diff-algorithm :argument "-Xdiff-algorithm=")
|
||||
(7 "-f" "Force rebase" ("-f" "--force-rebase"))
|
||||
("-d" "Use author date as committer date" "--committer-date-is-author-date")
|
||||
("-t" "Use current time as author date" "--ignore-date")
|
||||
("-a" "Autosquash" "--autosquash")
|
||||
@@ -579,8 +586,8 @@ This discards all changes made since the sequence started."
|
||||
With a prefix argument or when the push-remote is either not
|
||||
configured or unusable, then let the user first configure the
|
||||
push-remote."
|
||||
:if 'magit-get-current-branch
|
||||
:description 'magit-pull--pushbranch-description
|
||||
:if #'magit-get-current-branch
|
||||
:description #'magit-pull--pushbranch-description
|
||||
(interactive (list (magit-rebase-arguments)))
|
||||
(pcase-let ((`(,branch ,remote)
|
||||
(magit--select-push-remote "rebase onto that")))
|
||||
@@ -593,8 +600,8 @@ push-remote."
|
||||
With a prefix argument or when the upstream is either not
|
||||
configured or unusable, then let the user first configure
|
||||
the upstream."
|
||||
:if 'magit-get-current-branch
|
||||
:description 'magit-rebase--upstream-description
|
||||
:if #'magit-get-current-branch
|
||||
:description #'magit-rebase--upstream-description
|
||||
(interactive (list (magit-rebase-arguments)))
|
||||
(let* ((branch (or (magit-get-current-branch)
|
||||
(user-error "No branch is checked out")))
|
||||
@@ -607,7 +614,7 @@ the upstream."
|
||||
(magit-git-rebase upstream args)))
|
||||
|
||||
(defun magit-rebase--upstream-description ()
|
||||
(when-let ((branch (magit-get-current-branch)))
|
||||
(and-let* ((branch (magit-get-current-branch)))
|
||||
(or (magit-get-upstream-branch branch)
|
||||
(let ((remote (magit-get "branch" branch "remote"))
|
||||
(merge (magit-get "branch" branch "merge"))
|
||||
@@ -660,9 +667,9 @@ START has to be selected from a list of recent commits."
|
||||
(declare (indent 2))
|
||||
(when commit
|
||||
(if (eq commit :merge-base)
|
||||
(setq commit (--if-let (magit-get-upstream-branch)
|
||||
(magit-git-string "merge-base" it "HEAD")
|
||||
nil))
|
||||
(setq commit
|
||||
(and-let* ((upstream (magit-get-upstream-branch)))
|
||||
(magit-git-string "merge-base" upstream "HEAD")))
|
||||
(unless (magit-rev-ancestor-p commit "HEAD")
|
||||
(user-error "%s isn't an ancestor of HEAD" commit))
|
||||
(if (magit-commit-parents commit)
|
||||
@@ -683,7 +690,7 @@ START has to be selected from a list of recent commits."
|
||||
editor))
|
||||
process-environment))
|
||||
(magit-run-git-sequencer "rebase" "-i" args
|
||||
(unless (member "--root" args) commit)))
|
||||
(and (not (member "--root" args)) commit)))
|
||||
(magit-log-select
|
||||
`(lambda (commit)
|
||||
;; In some cases (currently just magit-rebase-remove-commit), "-c
|
||||
@@ -814,8 +821,7 @@ edit. With a prefix argument the old message is reused as-is."
|
||||
(magit-commit-amend-assert
|
||||
(magit-file-line (magit-git-dir "rebase-merge/orig-head"))))
|
||||
(if noedit
|
||||
(let ((process-environment process-environment))
|
||||
(push "GIT_EDITOR=true" process-environment)
|
||||
(with-environment-variables (("GIT_EDITOR" "true"))
|
||||
(magit-run-git-async (magit--rebase-resume-command) "--continue")
|
||||
(set-process-sentinel magit-this-process
|
||||
#'magit-sequencer-process-sentinel)
|
||||
@@ -972,13 +978,13 @@ status buffer (i.e. the reverse of how they will be applied)."
|
||||
(dolist (line (magit-rebase--todo))
|
||||
(with-slots (action-type action action-options target) line
|
||||
(pcase action-type
|
||||
(`commit
|
||||
('commit
|
||||
(magit-sequence-insert-commit action target 'magit-sequence-pick))
|
||||
((or (or `exec `label)
|
||||
(and `merge (guard (not action-options))))
|
||||
(insert (propertize action 'font-lock-face 'magit-sequence-onto) "\s"
|
||||
(propertize target 'font-lock-face 'git-rebase-label) "\n"))
|
||||
(`merge
|
||||
('merge
|
||||
(if-let ((hash (and (string-match "-[cC] \\([^ ]+\\)" action-options)
|
||||
(match-string 1 action-options))))
|
||||
(magit-insert-section (commit hash)
|
||||
@@ -990,8 +996,8 @@ status buffer (i.e. the reverse of how they will be applied)."
|
||||
(magit-sequence-insert-sequence
|
||||
(magit-file-line (magit-git-dir "rebase-merge/stopped-sha"))
|
||||
onto
|
||||
(--when-let (magit-file-lines (magit-git-dir "rebase-merge/done"))
|
||||
(cadr (split-string (car (last it)))))))
|
||||
(and-let* ((lines (magit-file-lines (magit-git-dir "rebase-merge/done"))))
|
||||
(cadr (split-string (car (last lines)))))))
|
||||
|
||||
(defun magit-rebase-insert-apply-sequence (onto)
|
||||
(let ((rewritten
|
||||
@@ -1051,7 +1057,7 @@ status buffer (i.e. the reverse of how they will be applied)."
|
||||
(magit-sequence-insert-commit "gone" stop 'magit-sequence-drop)))
|
||||
(setq stop nil))))
|
||||
(dolist (rev done)
|
||||
(apply 'magit-sequence-insert-commit
|
||||
(apply #'magit-sequence-insert-commit
|
||||
(cond ((equal rev stop)
|
||||
;; ...but its reincarnation lives on.
|
||||
;; Or it didn't die in the first place.
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-sparse-checkout.el --- sparse checkout support for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-sparse-checkout.el --- Sparse checkout support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Kyle Meyer <kyle@kyleam.com>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-stash.el --- stash support for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-stash.el --- Stash support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -79,7 +76,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
|
||||
:group 'magit-stash
|
||||
:group 'magit-margin
|
||||
:type magit-log-margin--custom-type
|
||||
:initialize 'magit-custom-initialize-reset
|
||||
:initialize #'magit-custom-initialize-reset
|
||||
:set-after '(magit-log-margin)
|
||||
:set (apply-partially #'magit-margin-set-variable 'magit-stashes-mode))
|
||||
|
||||
@@ -221,8 +218,9 @@ use \"git stash\" and are generally more flexible but don't allow
|
||||
specifying a list of files to be stashed."
|
||||
:man-page "git-stash"
|
||||
["Arguments"
|
||||
(magit:-- :reader ,(-rpartial #'magit-read-files
|
||||
#'magit-modified-files))
|
||||
(magit:-- :reader (lambda (prompt initial-input history)
|
||||
(magit-read-files prompt initial-input history
|
||||
#'magit-modified-files)))
|
||||
("-u" "Also save untracked files" ("-u" "--include-untracked"))
|
||||
("-a" "Also save untracked and ignored files" ("-a" "--all"))
|
||||
("-k" "Keep index" ("-k" "--keep-index"))
|
||||
@@ -320,7 +318,7 @@ current branch or `HEAD' as the start-point."
|
||||
(magit-stash-create message index worktree untracked))
|
||||
(if (eq keep 'worktree)
|
||||
(with-temp-buffer
|
||||
(magit-git-insert "diff" "--cached")
|
||||
(magit-git-insert "diff" "--cached" "--no-ext-diff")
|
||||
(magit-run-git-with-input
|
||||
"apply" "--reverse" "--cached" "--ignore-space-change" "-")
|
||||
(magit-run-git-with-input
|
||||
@@ -377,16 +375,17 @@ current branch or `HEAD' as the start-point."
|
||||
|
||||
(defvar magit-stashes-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-delete-thing] 'magit-stash-clear)
|
||||
(magit-menu-set map [magit-visit-thing] #'magit-stash-list "List %t")
|
||||
(magit-menu-set map [magit-delete-thing] #'magit-stash-clear "Clear %t")
|
||||
map)
|
||||
"Keymap for `stashes' section.")
|
||||
|
||||
(defvar magit-stash-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-stash-show)
|
||||
(define-key map [remap magit-delete-thing] 'magit-stash-drop)
|
||||
(define-key map "a" 'magit-stash-apply)
|
||||
(define-key map "A" 'magit-stash-pop)
|
||||
(magit-menu-set map [magit-visit-thing] #'magit-stash-show "Visit %v")
|
||||
(magit-menu-set map [magit-delete-thing] #'magit-stash-drop "Delete %M")
|
||||
(magit-menu-set map [magit-cherry-apply] #'magit-stash-apply "Apply %M")
|
||||
(magit-menu-set map [magit-cherry-pick] #'magit-stash-pop "Pop %M")
|
||||
map)
|
||||
"Keymap for `stash' sections.")
|
||||
|
||||
@@ -418,7 +417,7 @@ instead of \"Stashes:\"."
|
||||
(backward-char)
|
||||
(magit-log-format-margin autostash author date)))))
|
||||
(if verified
|
||||
(magit-git-wash (apply-partially 'magit-log-wash-log 'stash)
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'stash)
|
||||
"reflog" "--format=%gd%x00%aN%x00%at%x00%gs" ref)
|
||||
(insert ?\n)
|
||||
(save-excursion
|
||||
@@ -447,7 +446,7 @@ instead of \"Stashes:\"."
|
||||
(magit-insert-heading (if (equal magit-buffer-refname "refs/stash")
|
||||
"Stashes:"
|
||||
(format "Stashes [%s]:" magit-buffer-refname)))
|
||||
(magit-git-wash (apply-partially 'magit-log-wash-log 'stash)
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'stash)
|
||||
"reflog" "--format=%gd%x00%aN%x00%at%x00%gs" magit-buffer-refname)))
|
||||
|
||||
(cl-defmethod magit-buffer-value (&context (major-mode magit-stashes-mode))
|
||||
@@ -462,8 +461,8 @@ If there is no stash buffer in the same frame, then do nothing."
|
||||
(magit--maybe-update-stash-buffer)))
|
||||
|
||||
(defun magit--maybe-update-stash-buffer ()
|
||||
(when-let ((stash (magit-section-value-if 'stash))
|
||||
(buffer (magit-get-mode-buffer 'magit-stash-mode nil t)))
|
||||
(when-let* ((stash (magit-section-value-if 'stash))
|
||||
(buffer (magit-get-mode-buffer 'magit-stash-mode nil t)))
|
||||
(if magit--update-stash-buffer
|
||||
(setq magit--update-stash-buffer (list stash buffer))
|
||||
(setq magit--update-stash-buffer (list stash buffer))
|
||||
@@ -496,7 +495,8 @@ If there is no stash buffer in the same frame, then do nothing."
|
||||
(define-derived-mode magit-stash-mode magit-diff-mode "Magit Stash"
|
||||
"Mode for looking at individual stashes."
|
||||
:group 'magit-diff
|
||||
(hack-dir-local-variables-non-file-buffer))
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(setq magit--imenu-group-types '(commit)))
|
||||
|
||||
(defun magit-stash-setup-buffer (stash args files)
|
||||
(magit-setup-buffer #'magit-stash-mode nil
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-status.el --- the grand overview -*- lexical-binding: t -*-
|
||||
;;; magit-status.el --- The grand overview -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -171,7 +168,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
|
||||
:group 'magit-status
|
||||
:group 'magit-margin
|
||||
:type magit-log-margin--custom-type
|
||||
:initialize 'magit-custom-initialize-reset
|
||||
:initialize #'magit-custom-initialize-reset
|
||||
:set-after '(magit-log-margin)
|
||||
:set (apply-partially #'magit-margin-set-variable 'magit-status-mode))
|
||||
|
||||
@@ -292,7 +289,7 @@ prefix arguments:
|
||||
(put 'magit-status 'interactive-only 'magit-status-setup-buffer)
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'magit 'magit-status
|
||||
(defalias 'magit #'magit-status
|
||||
"An alias for `magit-status' for better discoverability.
|
||||
|
||||
Instead of invoking this alias for `magit-status' using
|
||||
@@ -324,7 +321,7 @@ Prefix arguments have the same meaning as for `magit-status',
|
||||
and additionally cause the buffer to be refresh.
|
||||
|
||||
To use this function instead of `magit-status', add this to your
|
||||
init file: (global-set-key (kbd \"C-x g\") 'magit-status-quick)."
|
||||
init file: (global-set-key (kbd \"C-x g\") \\='magit-status-quick)."
|
||||
(interactive)
|
||||
(if-let ((buffer
|
||||
(and (not current-prefix-arg)
|
||||
@@ -333,37 +330,13 @@ init file: (global-set-key (kbd \"C-x g\") 'magit-status-quick)."
|
||||
(magit-display-buffer buffer)
|
||||
(call-interactively #'magit-status)))
|
||||
|
||||
(defvar magit--remotes-using-recent-git nil)
|
||||
|
||||
(defun magit--tramp-asserts (directory)
|
||||
(when-let ((remote (file-remote-p directory)))
|
||||
(unless (member remote magit--remotes-using-recent-git)
|
||||
(if-let ((version (let ((default-directory directory))
|
||||
(magit-git-version))))
|
||||
(if (magit--version>= version magit--minimal-git)
|
||||
(push remote magit--remotes-using-recent-git)
|
||||
(display-warning 'magit (format "\
|
||||
Magit requires Git >= %s, but on %s the version is %s.
|
||||
|
||||
If multiple Git versions are installed on the host, then the
|
||||
problem might be that TRAMP uses the wrong executable.
|
||||
|
||||
Check the value of `magit-remote-git-executable' and consult
|
||||
the info node `(tramp)Remote programs'.
|
||||
" magit--minimal-git remote version) :error))
|
||||
(display-warning 'magit (format "\
|
||||
Magit cannot find Git on %s.
|
||||
|
||||
Check the value of `magit-remote-git-executable' and consult
|
||||
the info node `(tramp)Remote programs'." remote) :error)))))
|
||||
|
||||
;;; Mode
|
||||
|
||||
(defvar magit-status-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map magit-mode-map)
|
||||
(define-key map "j" 'magit-status-jump)
|
||||
(define-key map [remap dired-jump] 'magit-dired-jump)
|
||||
(define-key map "j" #'magit-status-jump)
|
||||
(define-key map [remap dired-jump] #'magit-dired-jump)
|
||||
map)
|
||||
"Keymap for `magit-status-mode'.")
|
||||
|
||||
@@ -430,8 +403,10 @@ Type \\[magit-commit] to create a commit.
|
||||
\\{magit-status-mode-map}"
|
||||
:group 'magit-status
|
||||
(hack-dir-local-variables-non-file-buffer)
|
||||
(setq imenu-create-index-function
|
||||
'magit-imenu--status-create-index-function))
|
||||
(when magit-status-initial-section
|
||||
(add-hook 'magit-refresh-buffer-hook
|
||||
#'magit-status-goto-initial-section nil t))
|
||||
(setq magit--imenu-group-types '(not branch commit)))
|
||||
|
||||
(put 'magit-status-mode 'magit-diff-default-arguments
|
||||
'("--no-ext-diff"))
|
||||
@@ -442,7 +417,8 @@ Type \\[magit-commit] to create a commit.
|
||||
(defun magit-status-setup-buffer (&optional directory)
|
||||
(unless directory
|
||||
(setq directory default-directory))
|
||||
(magit--tramp-asserts directory)
|
||||
(when (file-remote-p directory)
|
||||
(magit-git-version-assert))
|
||||
(let* ((default-directory directory)
|
||||
(d (magit-diff--get-value 'magit-status-mode
|
||||
magit-status-use-buffer-arguments))
|
||||
@@ -476,19 +452,7 @@ Type \\[magit-commit] to create a commit.
|
||||
(magit-run-section-hook 'magit-status-sections-hook)))
|
||||
|
||||
(defun magit-status-goto-initial-section ()
|
||||
"In a `magit-status-mode' buffer, jump `magit-status-initial-section'.
|
||||
Actually doing so is deferred until `magit-refresh-buffer-hook'
|
||||
runs `magit-status-goto-initial-section-1'. That function then
|
||||
removes itself from the hook, so that this only happens when the
|
||||
status buffer is first created."
|
||||
(when (and magit-status-initial-section
|
||||
(derived-mode-p 'magit-status-mode))
|
||||
(add-hook 'magit-refresh-buffer-hook
|
||||
'magit-status-goto-initial-section-1 nil t)))
|
||||
|
||||
(defun magit-status-goto-initial-section-1 ()
|
||||
"In a `magit-status-mode' buffer, jump `magit-status-initial-section'.
|
||||
This function removes itself from `magit-refresh-buffer-hook'."
|
||||
"Jump to the section specified by `magit-status-initial-section'."
|
||||
(when-let ((section
|
||||
(--some (if (integerp it)
|
||||
(nth (1- it)
|
||||
@@ -503,7 +467,7 @@ This function removes itself from `magit-refresh-buffer-hook'."
|
||||
(magit-section-hide section)
|
||||
(magit-section-show section))))
|
||||
(remove-hook 'magit-refresh-buffer-hook
|
||||
'magit-status-goto-initial-section-1 t))
|
||||
#'magit-status-goto-initial-section t))
|
||||
|
||||
(defun magit-status-maybe-update-revision-buffer (&optional _)
|
||||
"When moving in the status buffer, update the revision buffer.
|
||||
@@ -536,7 +500,8 @@ The sections are inserted by running the functions on the hook
|
||||
|
||||
(defvar magit-error-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-process-buffer)
|
||||
(magit-menu-set map [magit-visit-thing]
|
||||
#'magit-process-buffer "Visit process output")
|
||||
map)
|
||||
"Keymap for `error' sections.")
|
||||
|
||||
@@ -652,17 +617,17 @@ arguments are for internal use only."
|
||||
|
||||
(defun magit-insert-push-branch-header ()
|
||||
"Insert a header line about the branch the current branch is pushed to."
|
||||
(when-let ((branch (magit-get-current-branch))
|
||||
(target (magit-get-push-branch branch)))
|
||||
(when-let* ((branch (magit-get-current-branch))
|
||||
(target (magit-get-push-branch branch)))
|
||||
(magit-insert-section (branch target)
|
||||
(insert (format "%-10s" "Push: "))
|
||||
(insert
|
||||
(if (magit-rev-verify target)
|
||||
(concat target " "
|
||||
(and magit-status-show-hashes-in-headers
|
||||
(concat (and magit-status-show-hashes-in-headers
|
||||
(concat (propertize (magit-rev-format "%h" target)
|
||||
'font-lock-face 'magit-hash)
|
||||
" "))
|
||||
target " "
|
||||
(funcall magit-log-format-message-function target
|
||||
(funcall magit-log-format-message-function nil
|
||||
(or (magit-rev-format "%s" target)
|
||||
@@ -689,14 +654,13 @@ arguments are for internal use only."
|
||||
(when (or this-tag next-tag)
|
||||
(magit-insert-section (tag (or this-tag next-tag))
|
||||
(insert (format "%-10s" (if both-tags "Tags: " "Tag: ")))
|
||||
(cl-flet ((insert-count
|
||||
(tag count face)
|
||||
(insert (concat (propertize tag 'font-lock-face 'magit-tag)
|
||||
(and (> count 0)
|
||||
(format " (%s)"
|
||||
(propertize
|
||||
(format "%s" count)
|
||||
'font-lock-face face)))))))
|
||||
(cl-flet ((insert-count (tag count face)
|
||||
(insert (concat (propertize tag 'font-lock-face 'magit-tag)
|
||||
(and (> count 0)
|
||||
(format " (%s)"
|
||||
(propertize
|
||||
(format "%s" count)
|
||||
'font-lock-face face)))))))
|
||||
(when this-tag (insert-count this-tag this-cnt 'magit-branch-local))
|
||||
(when both-tags (insert ", "))
|
||||
(when next-tag (insert-count next-tag next-cnt 'magit-tag)))
|
||||
@@ -726,10 +690,10 @@ arguments are for internal use only."
|
||||
If no remote is configured for the current branch, then fall back
|
||||
showing the \"origin\" remote, or if that does not exist the first
|
||||
remote in alphabetic order."
|
||||
(when-let ((name (magit-get-some-remote))
|
||||
;; Under certain configurations it's possible for url
|
||||
;; to be nil, when name is not, see #2858.
|
||||
(url (magit-get "remote" name "url")))
|
||||
(when-let* ((name (magit-get-some-remote))
|
||||
;; Under certain configurations it's possible for
|
||||
;; url to be nil, when name is not, see #2858.
|
||||
(url (magit-get "remote" name "url")))
|
||||
(magit-insert-section (remote name)
|
||||
(insert (format "%-10s" "Remote: "))
|
||||
(insert (propertize name 'font-lock-face 'magit-branch-remote) ?\s)
|
||||
@@ -739,8 +703,8 @@ remote in alphabetic order."
|
||||
|
||||
(defvar magit-untracked-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-delete-thing] 'magit-discard)
|
||||
(define-key map "s" 'magit-stage)
|
||||
(magit-menu-set map [magit-stage-file] #'magit-stage "Stage files")
|
||||
(magit-menu-set map [magit-delete-thing] #'magit-discard "Discard files")
|
||||
map)
|
||||
"Keymap for the `untracked' section.")
|
||||
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-submodule.el --- submodule support for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-submodule.el --- Submodule support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2011-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
@@ -66,14 +63,27 @@ is inserted. If it is nil, then all sections listed in
|
||||
|
||||
(defcustom magit-submodule-list-columns
|
||||
'(("Path" 25 magit-modulelist-column-path nil)
|
||||
("Version" 25 magit-repolist-column-version nil)
|
||||
("Version" 25 magit-repolist-column-version
|
||||
((:sort magit-repolist-version<)))
|
||||
("Branch" 20 magit-repolist-column-branch nil)
|
||||
("B<U" 3 magit-repolist-column-unpulled-from-upstream ((:right-align t)))
|
||||
("B>U" 3 magit-repolist-column-unpushed-to-upstream ((:right-align t)))
|
||||
("B<P" 3 magit-repolist-column-unpulled-from-pushremote ((:right-align t)))
|
||||
("B>P" 3 magit-repolist-column-unpushed-to-pushremote ((:right-align t)))
|
||||
("B" 3 magit-repolist-column-branches ((:right-align t)))
|
||||
("S" 3 magit-repolist-column-stashes ((:right-align t))))
|
||||
("B<U" 3 magit-repolist-column-unpulled-from-upstream
|
||||
((:right-align t)
|
||||
(:sort <)))
|
||||
("B>U" 3 magit-repolist-column-unpushed-to-upstream
|
||||
((:right-align t)
|
||||
(:sort <)))
|
||||
("B<P" 3 magit-repolist-column-unpulled-from-pushremote
|
||||
((:right-align t)
|
||||
(:sort <)))
|
||||
("B>P" 3 magit-repolist-column-unpushed-to-pushremote
|
||||
((:right-align t)
|
||||
(:sort <)))
|
||||
("B" 3 magit-repolist-column-branches
|
||||
((:right-align t)
|
||||
(:sort <)))
|
||||
("S" 3 magit-repolist-column-stashes
|
||||
((:right-align t)
|
||||
(:sort <))))
|
||||
"List of columns displayed by `magit-list-submodules'.
|
||||
|
||||
Each element has the form (HEADER WIDTH FORMAT PROPS).
|
||||
@@ -83,7 +93,15 @@ of the column. FORMAT is a function that is called with one
|
||||
argument, the repository identification (usually its basename),
|
||||
and with `default-directory' bound to the toplevel of its working
|
||||
tree. It has to return a string to be inserted or nil. PROPS is
|
||||
an alist that supports the keys `:right-align' and `:pad-right'.
|
||||
an alist that supports the keys `:right-align', `:pad-right' and
|
||||
`:sort'.
|
||||
|
||||
The `:sort' function has a weird interface described in the
|
||||
docstring of `tabulated-list--get-sort'. Alternatively `<' and
|
||||
`magit-repolist-version<' can be used as those functions are
|
||||
automatically replaced with functions that satisfy the interface.
|
||||
Set `:sort' to nil to inhibit sorting; if unspecifed, then the
|
||||
column is sortable using the default sorter.
|
||||
|
||||
You may wish to display a range of numeric columns using just one
|
||||
character per column and without any padding between columns, in
|
||||
@@ -100,6 +118,7 @@ than 9."
|
||||
(list (choice :tag "Property"
|
||||
(const :right-align)
|
||||
(const :pad-right)
|
||||
(const :sort)
|
||||
(symbol))
|
||||
(sexp :tag "Value"))))))
|
||||
|
||||
@@ -115,6 +134,8 @@ if non-nil, means to invert the resulting sort."
|
||||
(cons (string :tag "Column name")
|
||||
(boolean :tag "Flip order"))))
|
||||
|
||||
(defvar magit-submodule-list-format-path-functions nil)
|
||||
|
||||
(defcustom magit-submodule-remove-trash-gitdirs nil
|
||||
"Whether `magit-submodule-remove' offers to trash module gitdirs.
|
||||
|
||||
@@ -163,7 +184,7 @@ and also setting this variable to t will lead to tears."
|
||||
())
|
||||
|
||||
(cl-defmethod transient-format-description ((obj magit--git-submodule-suffix))
|
||||
(let ((value (delq nil (mapcar 'transient-infix-value transient--suffixes))))
|
||||
(let ((value (delq nil (mapcar #'transient-infix-value transient--suffixes))))
|
||||
(replace-regexp-in-string
|
||||
"\\[--[^]]+\\]"
|
||||
(lambda (match)
|
||||
@@ -460,12 +481,12 @@ or, failing that, the abbreviated HEAD commit hash."
|
||||
(magit-with-toplevel
|
||||
(let* ((modules (magit-list-module-paths))
|
||||
(path-format (format "%%-%is "
|
||||
(min (apply 'max (mapcar 'length modules))
|
||||
(min (apply #'max (mapcar #'length modules))
|
||||
(/ (window-width) 2))))
|
||||
(branch-format (format "%%-%is " (min 25 (/ (window-width) 3)))))
|
||||
(dolist (module modules)
|
||||
(let ((default-directory
|
||||
(expand-file-name (file-name-as-directory module))))
|
||||
(expand-file-name (file-name-as-directory module))))
|
||||
(magit-insert-section (magit-module-section module t)
|
||||
(insert (propertize (format path-format module)
|
||||
'font-lock-face 'magit-diff-file-heading))
|
||||
@@ -488,19 +509,25 @@ or, failing that, the abbreviated HEAD commit hash."
|
||||
|
||||
(defvar magit-modules-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-list-submodules)
|
||||
(magit-menu-set map [remap magit-visit-thing]
|
||||
#'magit-list-submodules "List %t")
|
||||
map)
|
||||
"Keymap for `modules' sections.")
|
||||
|
||||
(defvar magit-module-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map magit-file-section-map)
|
||||
(define-key map (kbd "C-j") 'magit-submodule-visit)
|
||||
(define-key map [C-return] 'magit-submodule-visit)
|
||||
(define-key map [remap magit-visit-thing] 'magit-submodule-visit)
|
||||
(define-key map [remap magit-delete-thing] 'magit-submodule-unpopulate)
|
||||
(define-key map "K" 'magit-file-untrack)
|
||||
(define-key map "R" 'magit-file-rename)
|
||||
(define-key map (kbd "C-j") #'magit-submodule-visit)
|
||||
(define-key map [C-return] #'magit-submodule-visit)
|
||||
(magit-menu-set map [magit-visit-thing]
|
||||
#'magit-submodule-visit "Visit %s")
|
||||
(magit-menu-set map [magit-stage-file]
|
||||
#'magit-stage "Stage %T"
|
||||
'(:visible (eq (magit-diff-type) 'unstaged)))
|
||||
(magit-menu-set map [magit-unstage-file]
|
||||
#'magit-unstage "Unstage %T"
|
||||
'(:visible (eq (magit-diff-type) 'staged)))
|
||||
(define-key-after map [separator-magit-submodule] menu-bar-separator)
|
||||
(magit-menu-set map [magit-submodule] #'magit-submodule "Module commands...")
|
||||
map)
|
||||
"Keymap for `module' sections.")
|
||||
|
||||
@@ -578,15 +605,16 @@ These sections can be expanded to show the respective commits."
|
||||
(dolist (module modules)
|
||||
(when (magit-module-worktree-p module)
|
||||
(let ((default-directory
|
||||
(expand-file-name (file-name-as-directory module))))
|
||||
(expand-file-name (file-name-as-directory module))))
|
||||
(when (magit-file-accessible-directory-p default-directory)
|
||||
(magit-insert-section sec (magit-module-section module t)
|
||||
(magit-insert-heading
|
||||
(propertize module
|
||||
'font-lock-face 'magit-diff-file-heading)
|
||||
":")
|
||||
(oset sec range range)
|
||||
(magit-git-wash
|
||||
(apply-partially 'magit-log-wash-log 'module)
|
||||
(apply-partially #'magit-log-wash-log 'module)
|
||||
"-c" "push.default=current" "log" "--oneline" range)
|
||||
(when (> (point)
|
||||
(oref sec content))
|
||||
@@ -615,40 +643,29 @@ These sections can be expanded to show the respective commits."
|
||||
:group 'magit-repolist-mode
|
||||
(setq-local x-stretch-cursor nil)
|
||||
(setq tabulated-list-padding 0)
|
||||
(add-hook 'tabulated-list-revert-hook 'magit-submodule-list-refresh nil t)
|
||||
(add-hook 'tabulated-list-revert-hook #'magit-submodule-list-refresh nil t)
|
||||
(setq imenu-prev-index-position-function
|
||||
#'magit-imenu--submodule-prev-index-position-function)
|
||||
(setq imenu-extract-index-name-function
|
||||
#'magit-imenu--submodule-extract-index-name-function))
|
||||
#'magit-repolist--imenu-prev-index-position)
|
||||
(setq imenu-extract-index-name-function #'tabulated-list-get-id))
|
||||
|
||||
(defvar-local magit-submodule-list-predicate nil)
|
||||
|
||||
(defun magit-submodule-list-setup (columns &optional predicate)
|
||||
(magit-display-buffer
|
||||
(or (magit-get-mode-buffer 'magit-submodule-list-mode)
|
||||
(magit-with-toplevel
|
||||
(magit-generate-new-buffer 'magit-submodule-list-mode))))
|
||||
(magit-generate-new-buffer 'magit-submodule-list-mode)))
|
||||
(magit-submodule-list-mode)
|
||||
(setq-local magit-repolist-columns columns)
|
||||
(setq-local magit-repolist-sort-key magit-submodule-list-sort-key)
|
||||
(setq-local magit-submodule-list-predicate predicate)
|
||||
(magit-repolist-setup-1)
|
||||
(magit-submodule-list-refresh))
|
||||
|
||||
(defun magit-submodule-list-refresh ()
|
||||
(unless tabulated-list-sort-key
|
||||
(setq tabulated-list-sort-key
|
||||
(pcase-let ((`(,column . ,flip) magit-submodule-list-sort-key))
|
||||
(cons (or (car (assoc column magit-submodule-list-columns))
|
||||
(caar magit-submodule-list-columns))
|
||||
flip))))
|
||||
(setq tabulated-list-format
|
||||
(vconcat (mapcar (pcase-lambda (`(,title ,width ,_fn ,props))
|
||||
(nconc (list title width t)
|
||||
(-flatten props)))
|
||||
magit-repolist-columns)))
|
||||
(setq tabulated-list-entries
|
||||
(-keep (lambda (module)
|
||||
(let ((default-directory
|
||||
(expand-file-name (file-name-as-directory module))))
|
||||
(expand-file-name (file-name-as-directory module))))
|
||||
(and (file-exists-p ".git")
|
||||
(or (not magit-submodule-list-predicate)
|
||||
(funcall magit-submodule-list-predicate module))
|
||||
@@ -669,7 +686,10 @@ These sections can be expanded to show the respective commits."
|
||||
|
||||
(defun magit-modulelist-column-path (spec)
|
||||
"Insert the relative path of the submodule."
|
||||
(cadr (assq :path spec)))
|
||||
(let ((path (cadr (assq :path spec))))
|
||||
(or (run-hook-with-args-until-success
|
||||
'magit-submodule-list-format-path-functions path)
|
||||
path)))
|
||||
|
||||
;;; Utilities
|
||||
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-subtree.el --- subtree support for Magit -*- lexical-binding: t -*-
|
||||
;;; magit-subtree.el --- Subtree support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2011-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
@@ -71,7 +68,7 @@
|
||||
:class 'transient-option
|
||||
:shortarg "-P"
|
||||
:argument "--prefix="
|
||||
:reader 'magit-subtree-read-prefix)
|
||||
:reader #'magit-subtree-read-prefix)
|
||||
|
||||
(defun magit-subtree-read-prefix (prompt &optional default _history)
|
||||
(let* ((insert-default-directory nil)
|
||||
@@ -107,7 +104,7 @@
|
||||
:class 'transient-option
|
||||
:key "-o"
|
||||
:argument "--onto="
|
||||
:reader 'magit-transient-read-revision)
|
||||
:reader #'magit-transient-read-revision)
|
||||
|
||||
(defun magit-subtree-prefix (transient prompt)
|
||||
(--if-let (--first (string-prefix-p "--prefix=" it)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-tag.el --- tag functionality -*- lexical-binding: t -*-
|
||||
;;; magit-tag.el --- Tag functionality -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -34,6 +31,8 @@
|
||||
;; For `magit-tag-delete'.
|
||||
(defvar helm-comp-read-use-marked)
|
||||
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload (autoload 'magit-tag "magit" nil t)
|
||||
(transient-define-prefix magit-tag ()
|
||||
"Create or delete a tag."
|
||||
@@ -58,7 +57,7 @@
|
||||
:class 'transient-option
|
||||
:shortarg "-u"
|
||||
:argument "--local-user="
|
||||
:reader 'magit-read-gpg-signing-key
|
||||
:reader #'magit-read-gpg-signing-key
|
||||
:history-key 'magit:--gpg-sign)
|
||||
|
||||
;;;###autoload
|
||||
@@ -140,15 +139,21 @@ If this matches versions that are not dot separated numbers,
|
||||
then `magit-tag-version-regexp-alist' has to contain entries
|
||||
for the separators allowed here.")
|
||||
|
||||
(defvar magit-release-commit-regexp "\\`Release version \\(.+\\)\\'"
|
||||
"Regexp used by `magit-tag-release' to parse release commit messages.
|
||||
The first submatch must match the version string.")
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-tag-release (tag msg &optional args)
|
||||
"Create a release tag.
|
||||
"Create a release tag for `HEAD'.
|
||||
|
||||
Assume that release tags match `magit-release-tag-regexp'.
|
||||
|
||||
First prompt for the name of the new tag using the highest
|
||||
existing tag as initial input and leaving it to the user to
|
||||
increment the desired part of the version string.
|
||||
If `HEAD's message matches `magit-release-commit-regexp', then
|
||||
base the tag on the version string specified by that. Otherwise
|
||||
prompt for the name of the new tag using the highest existing
|
||||
tag as initial input and leaving it to the user to increment the
|
||||
desired part of the version string.
|
||||
|
||||
If `--annotate' is enabled, then prompt for the message of the
|
||||
new tag. Base the proposed tag message on the message of the
|
||||
@@ -161,7 +166,28 @@ like \"/path/to/foo-bar\"."
|
||||
(save-match-data
|
||||
(pcase-let*
|
||||
((`(,pver ,ptag ,pmsg) (car (magit--list-releases)))
|
||||
(tag (read-string "Create release tag: " ptag))
|
||||
(msg (magit-rev-format "%s"))
|
||||
(ver (and (string-match magit-release-commit-regexp msg)
|
||||
(match-string 1 msg)))
|
||||
(_ (and (not ver)
|
||||
(require (quote sisyphus) nil t)
|
||||
(string-match magit-release-commit-regexp
|
||||
(magit-rev-format "%s" ptag))
|
||||
(user-error "Use `sisyphus-create-release' first")))
|
||||
(tag (cond
|
||||
((not ptag)
|
||||
(read-string "Create first release tag: "
|
||||
(if (and ver (string-match-p "\\`[0-9]" ver))
|
||||
(concat "v" ver)
|
||||
ver)))
|
||||
(ver
|
||||
(concat (and (string-match magit-release-tag-regexp ptag)
|
||||
(match-string 1 ptag))
|
||||
ver))
|
||||
(t
|
||||
(read-string
|
||||
(format "Create release tag (previous was %s): " ptag)
|
||||
ptag))))
|
||||
(ver (and (string-match magit-release-tag-regexp tag)
|
||||
(match-string 2 tag)))
|
||||
(args (magit-tag-arguments)))
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-transient.el --- support for transients -*- lexical-binding: t -*-
|
||||
;;; magit-transient.el --- Support for transients -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -39,13 +36,17 @@
|
||||
;;; Classes
|
||||
|
||||
(defclass magit--git-variable (transient-variable)
|
||||
((scope :initarg :scope)))
|
||||
((scope :initarg :scope)
|
||||
(global :initarg :global :initform nil)))
|
||||
|
||||
(defclass magit--git-variable:choices (magit--git-variable)
|
||||
((choices :initarg :choices)
|
||||
(fallback :initarg :fallback :initform nil)
|
||||
(default :initarg :default :initform nil)))
|
||||
|
||||
(defclass magit--git-variable:boolean (magit--git-variable:choices)
|
||||
((choices :initarg :choices :initform '("true" "false"))))
|
||||
|
||||
(defclass magit--git-variable:urls (magit--git-variable)
|
||||
((seturl-arg :initarg :seturl-arg :initform nil)))
|
||||
|
||||
@@ -61,22 +62,32 @@
|
||||
|
||||
(cl-defmethod transient-init-value ((obj magit--git-variable))
|
||||
(let ((variable (format (oref obj variable)
|
||||
(oref obj scope))))
|
||||
(oref obj scope)))
|
||||
(arg (if (oref obj global) "--global" "--local")))
|
||||
(oset obj variable variable)
|
||||
(oset obj value
|
||||
(cond ((oref obj multi-value)
|
||||
(magit-get-all variable))
|
||||
(magit-get-all arg variable))
|
||||
(t
|
||||
(magit-git-string "config" "--local" variable))))))
|
||||
(magit-get arg variable))))))
|
||||
|
||||
(cl-defmethod transient-init-value ((obj magit--git-variable:boolean))
|
||||
(let ((variable (format (oref obj variable)
|
||||
(oref obj scope)))
|
||||
(arg (if (oref obj global) "--global" "--local")))
|
||||
(oset obj variable variable)
|
||||
(oset obj value (if (magit-get-boolean arg variable) "true" "false"))))
|
||||
|
||||
;;;; Read
|
||||
|
||||
(cl-defmethod transient-infix-read :around ((obj magit--git-variable:urls))
|
||||
(mapcar (lambda (url)
|
||||
(if (string-prefix-p "~" url)
|
||||
(expand-file-name url)
|
||||
url))
|
||||
(cl-call-next-method obj)))
|
||||
(transient--with-emergency-exit
|
||||
(transient--with-suspended-override
|
||||
(mapcar (lambda (url)
|
||||
(if (string-prefix-p "~" url)
|
||||
(expand-file-name url)
|
||||
url))
|
||||
(cl-call-next-method obj)))))
|
||||
|
||||
(cl-defmethod transient-infix-read ((obj magit--git-variable:choices))
|
||||
(let ((choices (oref obj choices)))
|
||||
@@ -108,11 +119,12 @@
|
||||
;;;; Set
|
||||
|
||||
(cl-defmethod transient-infix-set ((obj magit--git-variable) value)
|
||||
(let ((variable (oref obj variable)))
|
||||
(let ((variable (oref obj variable))
|
||||
(arg (if (oref obj global) "--global" "--local")))
|
||||
(oset obj value value)
|
||||
(if (oref obj multi-value)
|
||||
(magit-set-all value variable)
|
||||
(magit-set value variable))
|
||||
(magit-set-all value arg variable)
|
||||
(magit-set value arg variable))
|
||||
(magit-refresh)
|
||||
(unless (or value transient--prefix)
|
||||
(message "Unset %s" variable))))
|
||||
@@ -151,25 +163,31 @@
|
||||
(cl-defmethod transient-format-value ((obj magit--git-variable:choices))
|
||||
(let* ((variable (oref obj variable))
|
||||
(choices (oref obj choices))
|
||||
(local (magit-git-string "config" "--local" variable))
|
||||
(globalp (oref obj global))
|
||||
(value nil)
|
||||
(global (magit-git-string "config" "--global" variable))
|
||||
(default (oref obj default))
|
||||
(defaultp (oref obj default))
|
||||
(default (if (functionp defaultp) (funcall defaultp obj) defaultp))
|
||||
(fallback (oref obj fallback))
|
||||
(fallback (and fallback
|
||||
(when-let ((val (magit-get fallback)))
|
||||
(and-let* ((val (magit-get fallback)))
|
||||
(concat fallback ":" val)))))
|
||||
(if (not globalp)
|
||||
(setq value (magit-git-string "config" "--local" variable))
|
||||
(setq value global)
|
||||
(setq global nil))
|
||||
(when (functionp choices)
|
||||
(setq choices (funcall choices)))
|
||||
(concat
|
||||
(propertize "[" 'face 'transient-inactive-value)
|
||||
(mapconcat (lambda (choice)
|
||||
(propertize choice 'face (if (equal choice local)
|
||||
(propertize choice 'face (if (equal choice value)
|
||||
(if (member choice choices)
|
||||
'transient-value
|
||||
'font-lock-warning-face)
|
||||
'transient-inactive-value)))
|
||||
(if (and local (not (member local choices)))
|
||||
(cons local choices)
|
||||
(if (and value (not (member value choices)))
|
||||
(cons value choices)
|
||||
choices)
|
||||
(propertize "|" 'face 'transient-inactive-value))
|
||||
(and (or global fallback default)
|
||||
@@ -177,7 +195,7 @@
|
||||
(propertize "|" 'face 'transient-inactive-value)
|
||||
(cond (global
|
||||
(propertize (concat "global:" global)
|
||||
'face (cond (local
|
||||
'face (cond (value
|
||||
'transient-inactive-value)
|
||||
((member global choices)
|
||||
'transient-value)
|
||||
@@ -185,14 +203,16 @@
|
||||
'font-lock-warning-face))))
|
||||
(fallback
|
||||
(propertize fallback
|
||||
'face (if local
|
||||
'face (if value
|
||||
'transient-inactive-value
|
||||
'transient-value)))
|
||||
(default
|
||||
(propertize (concat "default:" default)
|
||||
'face (if local
|
||||
'transient-inactive-value
|
||||
'transient-value))))))
|
||||
(propertize (if (functionp defaultp)
|
||||
(concat "dwim:" default)
|
||||
(concat "default:" default))
|
||||
'face (if value
|
||||
'transient-inactive-value
|
||||
'transient-value))))))
|
||||
(propertize "]" 'face 'transient-inactive-value))))
|
||||
|
||||
;;; _
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;;; magit-version.el --- the Magit version you are using
|
||||
|
||||
(setq magit-version "3.3.0")
|
||||
(setq magit-version 3.3.0)
|
||||
|
||||
(provide 'migit-version)
|
||||
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-wip.el --- commit snapshots to work-in-progress refs -*- lexical-binding: t -*-
|
||||
;;; magit-wip.el --- Commit snapshots to work-in-progress refs -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -140,10 +137,10 @@ variant `magit-wip-after-save-mode'."
|
||||
:lighter magit-wip-after-save-local-mode-lighter
|
||||
(if magit-wip-after-save-local-mode
|
||||
(if (and buffer-file-name (magit-inside-worktree-p t))
|
||||
(add-hook 'after-save-hook 'magit-wip-commit-buffer-file t t)
|
||||
(add-hook 'after-save-hook #'magit-wip-commit-buffer-file t t)
|
||||
(setq magit-wip-after-save-local-mode nil)
|
||||
(user-error "Need a worktree and a file"))
|
||||
(remove-hook 'after-save-hook 'magit-wip-commit-buffer-file t)))
|
||||
(remove-hook 'after-save-hook #'magit-wip-commit-buffer-file t)))
|
||||
|
||||
(defun magit-wip-after-save-local-mode-turn-on ()
|
||||
(and buffer-file-name
|
||||
@@ -224,8 +221,8 @@ command which is about to be called are committed."
|
||||
:lighter magit-wip-initial-backup-mode-lighter
|
||||
:global t
|
||||
(if magit-wip-initial-backup-mode
|
||||
(add-hook 'before-save-hook 'magit-wip-commit-initial-backup)
|
||||
(remove-hook 'before-save-hook 'magit-wip-commit-initial-backup)))
|
||||
(add-hook 'before-save-hook #'magit-wip-commit-initial-backup)
|
||||
(remove-hook 'before-save-hook #'magit-wip-commit-initial-backup)))
|
||||
|
||||
(defun magit--any-wip-mode-enabled-p ()
|
||||
"Return non-nil if any global wip mode is enabled."
|
||||
@@ -301,14 +298,7 @@ commit message."
|
||||
;; deleted in the temporary index.
|
||||
(magit-call-git
|
||||
"update-index" "--add" "--remove"
|
||||
(and (pcase (magit-repository-local-get
|
||||
'update-index-has-ignore-sw-p 'unset)
|
||||
(`unset
|
||||
(let ((val (magit-git-version>= "2.25.0")))
|
||||
(magit-repository-local-set
|
||||
'update-index-has-ignore-sw-p val)
|
||||
val))
|
||||
(val val))
|
||||
(and (magit-git-version>= "2.25.0")
|
||||
"--ignore-skip-worktree-entries")
|
||||
"--" files)
|
||||
(magit-with-toplevel
|
||||
@@ -376,7 +366,7 @@ commit message."
|
||||
(defun magit--wip-ref (namespace &optional ref)
|
||||
(concat magit-wip-namespace namespace
|
||||
(or (and ref (string-prefix-p "refs/" ref) ref)
|
||||
(when-let ((branch (and (not (equal ref "HEAD"))
|
||||
(and-let* ((branch (and (not (equal ref "HEAD"))
|
||||
(or ref (magit-get-current-branch)))))
|
||||
(concat "refs/heads/" branch))
|
||||
"HEAD")))
|
||||
@@ -384,7 +374,7 @@ commit message."
|
||||
(defun magit-wip-maybe-add-commit-hook ()
|
||||
(when (and magit-wip-merge-branch
|
||||
(magit-wip-any-enabled-p))
|
||||
(add-hook 'git-commit-post-finish-hook 'magit-wip-commit nil t)))
|
||||
(add-hook 'git-commit-post-finish-hook #'magit-wip-commit nil t)))
|
||||
|
||||
(defun magit-wip-any-enabled-p ()
|
||||
(or magit-wip-mode
|
||||
@@ -443,7 +433,7 @@ many \"branches\" of each wip ref are shown."
|
||||
args files))
|
||||
|
||||
(defun magit-wip-log-get-tips (wipref count)
|
||||
(when-let ((reflog (magit-git-lines "reflog" wipref)))
|
||||
(and-let* ((reflog (magit-git-lines "reflog" wipref)))
|
||||
(let (tips)
|
||||
(while (and reflog (> count 1))
|
||||
;; "start autosaving ..." is the current message, but it used
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
;;; magit-worktree.el --- worktree support -*- lexical-binding: t -*-
|
||||
;;; magit-worktree.el --- Worktree support -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2010-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
@@ -21,7 +18,7 @@
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -33,7 +30,7 @@
|
||||
|
||||
;;; Options
|
||||
|
||||
(defcustom magit-worktree-read-directory-name-function 'read-directory-name
|
||||
(defcustom magit-worktree-read-directory-name-function #'read-directory-name
|
||||
"Function used to read a directory for worktree commands.
|
||||
This is called with one argument, the prompt, and can be used
|
||||
to e.g. use a base directory other than `default-directory'.
|
||||
@@ -150,8 +147,10 @@ then show it in Dired instead."
|
||||
|
||||
(defvar magit-worktree-section-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map [remap magit-visit-thing] 'magit-worktree-status)
|
||||
(define-key map [remap magit-delete-thing] 'magit-worktree-delete)
|
||||
(magit-menu-set map [magit-visit-thing] #'magit-worktree-status "Visit %s")
|
||||
(magit-menu-set map [magit-delete-thing] #'magit-worktree-delete "Delete %m")
|
||||
(define-key-after map [separator-magit-worktree] menu-bar-separator)
|
||||
(magit-menu-set map [magit-worktree ] #'magit-worktree "Worktree commands...")
|
||||
map)
|
||||
"Keymap for `worktree' sections.")
|
||||
|
||||
@@ -159,7 +158,7 @@ then show it in Dired instead."
|
||||
"Insert sections for all worktrees.
|
||||
If there is only one worktree, then insert nothing."
|
||||
(let ((worktrees (magit-list-worktrees)))
|
||||
(when (> (length worktrees) 1)
|
||||
(when (length> worktrees 1)
|
||||
(magit-insert-section (worktrees)
|
||||
(magit-insert-heading "Worktrees:")
|
||||
(let* ((cols
|
||||
|
||||
@@ -1,42 +1,49 @@
|
||||
;;; magit.el --- A Git porcelain inside Emacs -*- lexical-binding: t; coding: utf-8 -*-
|
||||
;;; magit.el --- A Git porcelain inside Emacs -*- lexical-binding:t; coding:utf-8 -*-
|
||||
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
;;
|
||||
;; You should have received a copy of the AUTHORS.md file which
|
||||
;; lists all contributors. If not, see http://magit.vc/authors.
|
||||
;; Copyright (C) 2008-2022 The Magit Project Contributors
|
||||
|
||||
;; Author: Marius Vollmer <marius.vollmer@gmail.com>
|
||||
;; Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Kyle Meyer <kyle@kyleam.com>
|
||||
;; Noam Postavsky <npostavs@users.sourceforge.net>
|
||||
;; Kyle Meyer <kyle@kyleam.com>
|
||||
;; Former-Maintainers:
|
||||
;; Nicolas Dudebout <nicolas.dudebout@gatech.edu>
|
||||
;; Peter J. Weisberg <pj@irregularexpressions.net>
|
||||
;; Phil Jackson <phil@shellarchive.co.uk>
|
||||
;; Rémi Vanicat <vanicat@debian.org>
|
||||
;; Yann Hodique <yann.hodique@gmail.com>
|
||||
;; Nicolas Dudebout <nicolas.dudebout@gatech.edu>
|
||||
;; Noam Postavsky <npostavs@users.sourceforge.net>
|
||||
;; Peter J. Weisberg <pj@irregularexpressions.net>
|
||||
;; Phil Jackson <phil@shellarchive.co.uk>
|
||||
;; Rémi Vanicat <vanicat@debian.org>
|
||||
;; Yann Hodique <yann.hodique@gmail.com>
|
||||
|
||||
;; Keywords: git tools vc
|
||||
;; Homepage: https://github.com/magit/magit
|
||||
;; Package-Requires: ((emacs "25.1") (dash "2.19.1") (git-commit "3.3.0") (magit-section "3.3.0") (transient "0.3.6") (with-editor "3.0.5"))
|
||||
;; Package-Version: 3.3.0
|
||||
;; Keywords: git tools vc
|
||||
|
||||
;; Package-Version: 3.3.0.50-git
|
||||
;; Package-Requires: (
|
||||
;; (emacs "25.1")
|
||||
;; (compat "28.1.1.2")
|
||||
;; (dash "2.19.1")
|
||||
;; (git-commit "3.3.0")
|
||||
;; (magit-section "3.3.0")
|
||||
;; (transient "0.3.6")
|
||||
;; (with-editor "3.0.5"))
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software; you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;; Magit is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published
|
||||
;; by the Free Software Foundation, either version 3 of the License,
|
||||
;; or (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
;; License for more details.
|
||||
;; Magit is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see http://www.gnu.org/licenses.
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;; Magit requires at least GNU Emacs 25.1 and Git 2.2.0.
|
||||
;; You should have received a copy of the AUTHORS.md file, which
|
||||
;; lists all contributors. If not, see https://magit.vc/authors.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
@@ -65,8 +72,21 @@
|
||||
(require 'package nil t) ; used in `magit-version'
|
||||
(require 'with-editor)
|
||||
|
||||
(defconst magit--minimal-git "2.2.0")
|
||||
(defconst magit--minimal-emacs "25.1")
|
||||
;; For `magit:--gpg-sign'
|
||||
(declare-function epg-list-keys "epg" (context &optional name mode))
|
||||
(declare-function epg-decode-dn "epg" (alist))
|
||||
|
||||
;;; Options
|
||||
|
||||
(defcustom magit-openpgp-default-signing-key nil
|
||||
"Fingerprint of your default Openpgp key used for signing.
|
||||
If the specified primary key has signing capacity then it is used
|
||||
as the value of the `--gpg-sign' argument without prompting, even
|
||||
when other such keys exist. To be able to select another key you
|
||||
must then use a prefix argument."
|
||||
:package-version '(magit . "3.4.0")
|
||||
:group 'magit-commands
|
||||
:type 'string)
|
||||
|
||||
;;; Faces
|
||||
|
||||
@@ -92,7 +112,7 @@ own faces for the `header-line', or for parts of the
|
||||
(defface magit-hash
|
||||
'((((class color) (background light)) :foreground "grey60")
|
||||
(((class color) (background dark)) :foreground "grey40"))
|
||||
"Face for the sha1 part of the log output."
|
||||
"Face for the commit object name in the log output."
|
||||
:group 'magit-faces)
|
||||
|
||||
(defface magit-tag
|
||||
@@ -279,7 +299,7 @@ Also see info node `(magit)Commands for Buffers Visiting Files'."
|
||||
|
||||
;;;###autoload
|
||||
(progn
|
||||
(defun magit-maybe-define-global-key-bindings ()
|
||||
(defun magit-maybe-define-global-key-bindings (&optional force)
|
||||
(when magit-define-global-key-bindings
|
||||
(let ((map (current-global-map)))
|
||||
(dolist (elt '(("C-x g" . magit-status)
|
||||
@@ -287,12 +307,13 @@ Also see info node `(magit)Commands for Buffers Visiting Files'."
|
||||
("C-c M-g" . magit-file-dispatch)))
|
||||
(let ((key (kbd (car elt)))
|
||||
(def (cdr elt)))
|
||||
(unless (or (lookup-key map key)
|
||||
(where-is-internal def (make-sparse-keymap) t))
|
||||
(when (or force
|
||||
(not (or (lookup-key map key)
|
||||
(where-is-internal def (make-sparse-keymap) t))))
|
||||
(define-key map key def)))))))
|
||||
(if after-init-time
|
||||
(magit-maybe-define-global-key-bindings)
|
||||
(add-hook 'after-init-hook 'magit-maybe-define-global-key-bindings t)))
|
||||
(add-hook 'after-init-hook #'magit-maybe-define-global-key-bindings t)))
|
||||
|
||||
;;; Dispatch Popup
|
||||
|
||||
@@ -317,7 +338,7 @@ Also see info node `(magit)Commands for Buffers Visiting Files'."
|
||||
("F" "Pull" magit-pull)
|
||||
;; g ↓
|
||||
;; G → magit-refresh-all
|
||||
("h" "Help" magit-help)
|
||||
("h" "Help" magit-info)
|
||||
("H" "Section info" magit-describe-section :if-derived magit-mode)]
|
||||
[("i" "Ignore" magit-gitignore)
|
||||
("I" "Init" magit-init)
|
||||
@@ -368,10 +389,12 @@ Also see info node `(magit)Commands for Buffers Visiting Files'."
|
||||
("U" "Unstage all" magit-unstage-all)]]
|
||||
["Essential commands"
|
||||
:if-derived magit-mode
|
||||
("g" " refresh current buffer" magit-refresh)
|
||||
("<tab>" " toggle section at point" magit-section-toggle)
|
||||
("<return>" "visit thing at point" magit-visit-thing)
|
||||
("C-x m" " show all key bindings" describe-mode)])
|
||||
[("g" " refresh current buffer" magit-refresh)
|
||||
("q" " bury current buffer" magit-mode-bury-buffer)
|
||||
("<tab>" " toggle section at point" magit-section-toggle)
|
||||
("<return>" "visit thing at point" magit-visit-thing)]
|
||||
[("C-x m" "show all key bindings" describe-mode)
|
||||
("C-x i" "show Info manual" magit-info)]])
|
||||
|
||||
;;; Git Popup
|
||||
|
||||
@@ -398,7 +421,8 @@ This affects `magit-git-command', `magit-git-command-topdir',
|
||||
("k" "gitk" magit-run-gitk)
|
||||
("a" "gitk --all" magit-run-gitk-all)
|
||||
("b" "gitk --branches" magit-run-gitk-branches)
|
||||
("g" "git gui" magit-run-git-gui)]])
|
||||
("g" "git gui" magit-run-git-gui)
|
||||
("m" "git mergetool --gui" magit-git-mergetool)]])
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-git-command (command)
|
||||
@@ -444,26 +468,77 @@ is run in the top-level directory of the current working tree."
|
||||
(magit--shell-command command (magit-toplevel)))
|
||||
|
||||
(defun magit--shell-command (command &optional directory)
|
||||
(let ((default-directory (or directory default-directory))
|
||||
(process-environment process-environment))
|
||||
(push "GIT_PAGER=cat" process-environment)
|
||||
(magit--with-connection-local-variables
|
||||
(magit-start-process shell-file-name nil
|
||||
shell-command-switch command)))
|
||||
(let ((default-directory (or directory default-directory)))
|
||||
(with-environment-variables (("GIT_PAGER" "cat"))
|
||||
(magit--with-connection-local-variables
|
||||
(magit-start-process shell-file-name nil
|
||||
shell-command-switch command))))
|
||||
(magit-process-buffer))
|
||||
|
||||
(defun magit-read-shell-command (&optional toplevel initial-input)
|
||||
(let ((default-directory
|
||||
(if (or toplevel current-prefix-arg)
|
||||
(or (magit-toplevel)
|
||||
(magit--not-inside-repository-error))
|
||||
default-directory)))
|
||||
(if (or toplevel current-prefix-arg)
|
||||
(or (magit-toplevel)
|
||||
(magit--not-inside-repository-error))
|
||||
default-directory)))
|
||||
(read-shell-command (if magit-shell-command-verbose-prompt
|
||||
(format "Async shell command in %s: "
|
||||
(abbreviate-file-name default-directory))
|
||||
"Async shell command: ")
|
||||
initial-input 'magit-git-command-history)))
|
||||
|
||||
;;; Shared Infix Arguments
|
||||
|
||||
(transient-define-argument magit:--gpg-sign ()
|
||||
:description "Sign using gpg"
|
||||
:class 'transient-option
|
||||
:shortarg "-S"
|
||||
:argument "--gpg-sign="
|
||||
:allow-empty t
|
||||
:reader #'magit-read-gpg-signing-key)
|
||||
|
||||
(defvar magit-gpg-secret-key-hist nil)
|
||||
|
||||
(defun magit-read-gpg-secret-key
|
||||
(prompt &optional initial-input history predicate default)
|
||||
(require 'epa)
|
||||
(let* ((keys (cl-mapcan
|
||||
(lambda (cert)
|
||||
(and (or (not predicate)
|
||||
(funcall predicate cert))
|
||||
(let* ((key (car (epg-key-sub-key-list cert)))
|
||||
(fpr (epg-sub-key-fingerprint key))
|
||||
(id (epg-sub-key-id key))
|
||||
(author
|
||||
(and-let* ((id-obj
|
||||
(car (epg-key-user-id-list cert))))
|
||||
(let ((id-str (epg-user-id-string id-obj)))
|
||||
(if (stringp id-str)
|
||||
id-str
|
||||
(epg-decode-dn id-obj))))))
|
||||
(list
|
||||
(propertize fpr 'display
|
||||
(concat (substring fpr 0 (- (length id)))
|
||||
(propertize id 'face 'highlight)
|
||||
" " author))))))
|
||||
(epg-list-keys (epg-make-context epa-protocol) nil t)))
|
||||
(choice (or (and (not current-prefix-arg)
|
||||
(or (and (length= keys 1) (car keys))
|
||||
(and default (car (member default keys)))))
|
||||
(completing-read prompt keys nil nil nil
|
||||
history nil initial-input))))
|
||||
(set-text-properties 0 (length choice) nil choice)
|
||||
choice))
|
||||
|
||||
(defun magit-read-gpg-signing-key (prompt &optional initial-input history)
|
||||
(magit-read-gpg-secret-key
|
||||
prompt initial-input history
|
||||
(lambda (cert)
|
||||
(cl-some (lambda (key)
|
||||
(memq 'sign (epg-sub-key-capability key)))
|
||||
(epg-key-sub-key-list cert)))
|
||||
magit-openpgp-default-signing-key))
|
||||
|
||||
;;; Font-Lock Keywords
|
||||
|
||||
(defconst magit-font-lock-keywords
|
||||
@@ -486,7 +561,7 @@ is run in the top-level directory of the current working tree."
|
||||
|
||||
;;; Version
|
||||
|
||||
(defvar magit-version 'undefined
|
||||
(defvar magit-version #'undefined
|
||||
"The version of Magit that you're using.
|
||||
Use the function by the same name instead of this variable.")
|
||||
|
||||
@@ -579,12 +654,7 @@ and Emacs to it."
|
||||
(locate-library "magit.el" t))
|
||||
(lm-header "Package-Version"))))))
|
||||
"")
|
||||
(or (let ((magit-git-debug
|
||||
(lambda (err)
|
||||
(display-warning '(magit git)
|
||||
err :error))))
|
||||
(magit-git-version t))
|
||||
"(unknown)")
|
||||
(magit--safe-git-version)
|
||||
emacs-version
|
||||
system-type)
|
||||
print-dest))
|
||||
@@ -597,75 +667,26 @@ and Emacs to it."
|
||||
(message "Cannot determine Magit's version %S" debug)))
|
||||
magit-version))
|
||||
|
||||
;;; Debugging Tools
|
||||
|
||||
(defun magit-debug-git-executable ()
|
||||
"Display a buffer with information about `magit-git-executable'.
|
||||
Also include information about `magit-remote-git-executable'.
|
||||
See info node `(magit)Debugging Tools' for more information."
|
||||
(interactive)
|
||||
(with-current-buffer (get-buffer-create "*magit-git-debug*")
|
||||
(pop-to-buffer (current-buffer))
|
||||
(erase-buffer)
|
||||
(insert (format "magit-remote-git-executable: %S\n"
|
||||
magit-remote-git-executable))
|
||||
(insert (concat
|
||||
(format "magit-git-executable: %S" magit-git-executable)
|
||||
(and (not (file-name-absolute-p magit-git-executable))
|
||||
(format " [%S]" (executable-find magit-git-executable)))
|
||||
(format " (%s)\n"
|
||||
(let* ((errmsg nil)
|
||||
(magit-git-debug (lambda (err) (setq errmsg err))))
|
||||
(or (magit-git-version t) errmsg)))))
|
||||
(insert (format "exec-path: %S\n" exec-path))
|
||||
(--when-let (cl-set-difference
|
||||
(-filter #'file-exists-p (remq nil (parse-colon-path
|
||||
(getenv "PATH"))))
|
||||
(-filter #'file-exists-p (remq nil exec-path))
|
||||
:test #'file-equal-p)
|
||||
(insert (format " entries in PATH, but not in exec-path: %S\n" it)))
|
||||
(dolist (execdir exec-path)
|
||||
(insert (format " %s (%s)\n" execdir (car (file-attributes execdir))))
|
||||
(when (file-directory-p execdir)
|
||||
(dolist (exec (directory-files
|
||||
execdir t (concat
|
||||
"\\`git" (regexp-opt exec-suffixes) "\\'")))
|
||||
(insert (format " %s (%s)\n" exec
|
||||
(let* ((magit-git-executable exec)
|
||||
(errmsg nil)
|
||||
(magit-git-debug (lambda (err) (setq errmsg err))))
|
||||
(or (magit-git-version t) errmsg)))))))))
|
||||
|
||||
;;; Startup Asserts
|
||||
|
||||
(defun magit-startup-asserts ()
|
||||
(when-let ((val (getenv "GIT_DIR")))
|
||||
(setenv "GIT_DIR")
|
||||
(message "Magit unset $GIT_DIR (was %S). See \
|
||||
https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike" val))
|
||||
(message
|
||||
"Magit unset $GIT_DIR (was %S). See %s" val
|
||||
;; Note: Pass URL as argument rather than embedding in the format
|
||||
;; string to prevent the single quote from being rendered
|
||||
;; according to `text-quoting-style'.
|
||||
"https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike"))
|
||||
(when-let ((val (getenv "GIT_WORK_TREE")))
|
||||
(setenv "GIT_WORK_TREE")
|
||||
(message "Magit unset $GIT_WORK_TREE (was %S). See \
|
||||
https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike" val))
|
||||
(let ((version (magit-git-version)))
|
||||
(when (and version
|
||||
(version< version magit--minimal-git)
|
||||
(not (equal (getenv "CI") "true")))
|
||||
(display-warning 'magit (format "\
|
||||
Magit requires Git >= %s, you are using %s.
|
||||
|
||||
If this comes as a surprise to you, because you do actually have
|
||||
a newer version installed, then that probably means that the
|
||||
older version happens to appear earlier on the `$PATH'. If you
|
||||
always start Emacs from a shell, then that can be fixed in the
|
||||
shell's init file. If you start Emacs by clicking on an icon,
|
||||
or using some sort of application launcher, then you probably
|
||||
have to adjust the environment as seen by graphical interface.
|
||||
For X11 something like ~/.xinitrc should work.
|
||||
|
||||
If you use Tramp to work inside remote Git repositories, then you
|
||||
have to make sure a suitable Git is used on the remote machines
|
||||
too.\n" magit--minimal-git version) :error)))
|
||||
(message
|
||||
"Magit unset $GIT_WORK_TREE (was %S). See %s" val
|
||||
;; See comment above.
|
||||
"https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike"))
|
||||
;; Git isn't required while building Magit.
|
||||
(unless (bound-and-true-p byte-compile-current-file)
|
||||
(magit-git-version-assert))
|
||||
(when (version< emacs-version magit--minimal-emacs)
|
||||
(display-warning 'magit (format "\
|
||||
Magit requires Emacs >= %s, you are using %s.
|
||||
@@ -715,16 +736,16 @@ For X11 something like ~/.xinitrc should work.\n"
|
||||
(require 'magit-sparse-checkout)
|
||||
(require 'magit-extras)
|
||||
(require 'git-rebase)
|
||||
(require 'magit-imenu)
|
||||
(require 'magit-bookmark)))
|
||||
|
||||
(with-eval-after-load 'bookmark
|
||||
(require 'magit-bookmark))
|
||||
|
||||
(if after-init-time
|
||||
(progn (magit-startup-asserts)
|
||||
(magit-version))
|
||||
(add-hook 'after-init-hook #'magit-startup-asserts t)
|
||||
(add-hook 'after-init-hook #'magit-version t))
|
||||
(unless (bound-and-true-p byte-compile-current-file)
|
||||
(if after-init-time
|
||||
(progn (magit-startup-asserts)
|
||||
(magit-version))
|
||||
(add-hook 'after-init-hook #'magit-startup-asserts t)
|
||||
(add-hook 'after-init-hook #'magit-version t)))
|
||||
|
||||
;;; magit.el ends here
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user