pkg update and first config fix

org-brain not working, add org-roam
This commit is contained in:
2022-12-19 23:02:34 +01:00
parent 02b3e07185
commit 82f05baffe
885 changed files with 356098 additions and 36993 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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))

View File

@@ -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 " "))

View File

@@ -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

View File

@@ -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:

View File

@@ -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)

View File

@@ -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 ()

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)]

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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}"))))
;;; _

View File

@@ -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)

View File

@@ -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.")

View File

@@ -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 ()

View File

@@ -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)

View File

@@ -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")

View File

@@ -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)

View 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

View File

@@ -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)))

View File

@@ -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"))

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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"))

View File

@@ -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

View File

@@ -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."

View File

@@ -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.

View File

@@ -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:

View File

@@ -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

View File

@@ -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.")

View File

@@ -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

View File

@@ -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)

View File

@@ -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)))

View File

@@ -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))))
;;; _

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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