git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: [GSoC][Draft Proposal v2] Finish converting git submodule to builtin
  2021-04-08 10:19  5% ` [GSoC][Draft Proposal v2] " Atharva Raykar
  2021-04-11 10:17  5%   ` [GSoC][Draft Proposal v3] " Atharva Raykar
@ 2021-05-14 16:00  2%   ` Atharva Raykar
  1 sibling, 0 replies; 200+ results
From: Atharva Raykar @ 2021-05-14 16:00 UTC (permalink / raw)
  To: git; +Cc: Christian Couder, Shourya Shukla, Shourya Shukla,
	Kaartic Sivaraam

On 08-Apr-2021, at 15:49, Atharva Raykar <raykar.ath@gmail.com> wrote:
> 
> Here's my updated draft. Changes since v1:
> 
> - Elaborated more on example porting strategy, stating how the patches
>   could be broken up.
> - Made language at the end of section 6 less ambiguous.
> - Updated status of microproject.
> - s/git/Git in several places.
> 
> Markdown version: https://gist.github.com/tfidfwastaken/0c6ca9ef2a452f110a416351541e0f19
> 
> --8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<--
>                          ___________________
> 
>                           GSOC GIT PROPOSAL
> 
>                             Atharva Raykar
>                          ___________________
> 
> 
> Table of Contents
> _________________
> 
> 1. Personal Details
> 2. Background
> 3. Me and Git
> .. 1. Current knowledge of Git
> 4. The Project: Finish converting `git submodule' to builtin
> 5. Prior work
> 6. General implementation strategy
> 7. Timeline (using the format dd/mm)
> 8. Beyond GSoC
> 9. Blogging
> 10. Final Remarks: A little more about me
> 
> 
> 1 Personal Details
> ==================
> 
>  Name : Atharva Raykar
>  Major : Computer Science and Engineering
>  Email : raykar.ath@gmail.com
>  IRC nick : atharvaraykar on #git and #git-devel
>  Address : RB 103, Purva Riviera, Marathahalli, Bangalore
>  Postal Code : 560037
>  Time Zone : IST (UTC+5:30)
>  GitHub : github.com/tfidfwastaken
> 
> 
> 2 Background
> ============
> 
>  I am Atharva Raykar, currently in my third year of studying Computer
>  Science and Engineering at PES University, Bangalore. I have always
>  enjoyed programming since a young age, but my deep appreciation for
>  good program design and creating the right abstractions came during my
>  exploration of the various rabbitholes of knowledge originating from
>  communities around the internet. I have personally enjoyed learning
>  about Functional Programming, Database Architecture and Operating
>  Systems, and my interests keep expanding as I explore more in this
>  field.
> 
>  I owe my appreciation of this rich field to these communities, and I
>  always wanted to give back. With that goal, I restarted the [PES Open
>  Source] community in our campus, with the goal of creating spaces
>  where members could share knowledge, much in the same spirit as the
>  communities that kickstarted my journey in Computer Science. I learnt
>  a lot about collaborating in the open, maintainership, and reviewing
>  code. While I have made many small contributions to projects in the
>  past, I am hoping GSoC will help me make the leap to a larger and more
>  substantial contribution to one of my favourite projects that made it
>  all possible in my journey with Open Source.
> 
> 
> [PES Open Source] <https://pesos.github.io>
> 
> 
> 3 Me and Git
> ============
> 
>  Here are the various forms of contributions that I have made to Git:
> 
>  - [Microproject] userdiff: userdiff: add support for Scheme Status: In
>    progress, patch v3 requiring a review List:
>    <https://lore.kernel.org/git/20210408091442.22740-1-raykar.ath@gmail.com/>
> 
>  - [Git Education] Conducted a workshop with attendance of hundreds of
>    students new to git, and increased the prevalence of of git's usage
>    in my campus.
>    Photos: <https://photos.app.goo.gl/T7CPk1zkHdK7mx6v7> and
>    <https://photos.app.goo.gl/bzTgdHMttxDen6z9A>
> 
>  I intend to continue helping people out on the mailing list and IRC
>  and tending to patches wherever possible in the meantime.
> 
> 
> 3.1 Current knowledge of Git
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
>  I use Git almost daily in some form, and I am fairly comfortable with
>  it. I have already read and understood the chapters from the Git Book
>  about submodules along with the one on objects, references, packfiles
>  and the refspec.
> 
> 
> 4 The Project: Finish converting `git submodule' to builtin
> ===========================================================
> 
>  Git has historically had many components implemented in the form of
>  shell scripts. This was less than ideal for several reasons:
>  - Portability: Non-POSIX systems like Windows don't play nice with
>    shell script commands like grep, cd and printf, to name a few, and
>    these commands have to be reimplemented for the system. There are
>    also POSIX to Windows path conversion issues.
>  - No direct access to plumbing: Shell commands do not have direct
>    access to the low level Git API, and a separate shell is spawned to
>    just to carry out their operations.
>  - Performance: Shell scripts tend to create a lot of child processes
>    which slows down the functioning of these commands, especially with
>    large repositories.
>  Over the years, many GSoC students have converted the shell versions
>  of these commands to C. Git `submodule' is the last of these to be
>  converted.
> 
> 
> 5 Prior work
> ============
> 
>  I will be taking advantage of the knowledge that was gained in the
>  process of the converting the previous scripts and avoiding all the
>  gotchas that may be present in the process. There may be a bunch of
>  useful helper functions in the previous patches that can be reused as
>  well (more investigation needed to determine what exactly is
>  reusable).
> 
>  Currently the only other commands left to be completed for `submodule'
>  are `add' and `update'. Work for `add' has already been started by a
>  previous GSoCer, Shourya Shukla, and needs to picked up from there.
>  `update' has had some of its functionality moved over to
>  `submodule--helper.c' where Stefan Beller added the helper functions
>  `update-clone', `update-module-mode', `remote-branch' and more.
> 
>  References:
>  <https://github.com/gitgitgadget/git/issues/541#issuecomment-769245064>
>  <https://github.com/git/git/commit/4d6d6ef1fc>
>  <https://github.com/git/git/commit/48308681b072a1d32e1361c255347324a8ad151e>
>  <https://github.com/git/git/commit/ee69b2a90c5031bffb3341c5e50653a6ecca89ac>
>  <https://github.com/git/git/commit/92bbe7ccf1fedac825f2c6ab4c8de91dc5370fd2>
> 
>  I'll have these as my references when I am working on the project:
>  His blog about his progress:
>  <https://shouryashukla.blogspot.com/2020/08/the-final-report.html>
>  (more has been implemented since)
>  Shourya's latest patch for `submodule add':
>  <https://lore.kernel.org/git/20201007074538.25891-1-shouryashukla.oo@gmail.com/>
> 
>  For the most part, the implementation looks fairly complete, but there
>  seems to be a segfault occurring, along with a few changes suggested
>  by the reviewers. It will be helpful to contact Shourya to fully
>  understand what needs to be done.
> 
>  Prathamesh's previous conversion work:
>  <https://lore.kernel.org/git/20170724203454.13947-1-pc44800@gmail.com/#t>
> 
>  The ultimate goal would be to get rid of `git-submodules.sh'
>  altogether -- which will complete the porting efforts of `submodule'
>  to C.
> 
> 
> 6 General implementation strategy
> =================================
> 
>  The way to port the shell to C code for `submodule' will largely
>  remain the same. There already exists the builtin
>  `submodule--helper.c' which contains most of the previous commands'
>  ports. All that the shell script for `git-submodule.sh' is doing for
>  the previously completed ports is parsing the flags and then calling
>  the helper, which does all the business logic.
> 
>  So I will be moving out all the business logic that the shell script
>  is performing to `submodule--helper.c'. Any reusable functionality
>  that is introduced during the port will be added to `submodule.c' in
>  the top level.
> 
>      For example: The general strategy for converting `cmd_update()' would
>      be to have a call to `submodule--helper' in the shell script to a
>      function which would resemble something like `module_update()'. This
>      would perform the work being done by the shell script past the flags
>      being parsed and make the necessary call to `update_clone()', which
>      returns information about the cloned modules. For each cloned module,
>      it will find out the update mode through `module_update_mode()', and
>      run the appropriate operation according to that mode (like a rebase,
>      if that was the update mode).
> 
>      One possible way this work can be broken up into multiple patches, is
>      by moving over the shell code into C in a bottom-up manner.
>      For example: The shell part which retrieves the latest revision in the
>      remote (if --remote is specified) can be wrapped into a command of
>      `submodule--helper.c'. Then we can move the part where we run the
>      update method (ie the `case' on line 611 onwards) into a C function.
>      Eventually, the shell part will just look like a bunch of invocations
>      to `submodule--helper', at which point, the whole thing can be
>      encapsulated in a single command called `git submodule--helper update'
>      (Bonus: Move the whole functionality to C, including the parsing of
>      flags, to work towards getting rid of `git-submodule.sh'). I believe
>      this is a fairly non-destructive and incremental way to work, and the
>      porting efforts by Stefan seem to follow this same kind of philosophy.
>      I will most likely end up tuning the size of these increments when I
>      get around to planning in my first phase of the project.
> 
>  After this process, I will be adding the `add' and `update' command to
>  the commands array in `submodule--helper.c'. And since these two
>  functions are the last bit of functionality left to convert in
>  submodules, an extended goal can be to get rid of the shell script
>  altogether, and make the helper into the actual builtin [1].
> 
>  [1]
>  <https://lore.kernel.org/git/nycvar.QRO.7.76.6.2011191327320.56@tvgsbejvaqbjf.bet/>

Hi all. I wanted to keep you informed, there have been some changes
in my personal schedule.

> 7 Timeline (using the format dd/mm)
> ===================================
> 
>  Periods of limited availability (read: hectic chaos):
>  - From 13/04 to 20/04 I will be having project evaluations and lab
>    assessments for five of my courses.
>  - From 20/04 to 01/05 I have my in-semester exams.
>  - For a period of two weeks in the range of 08/05 to 29/05 I will be
>    having my end-semester exams.
>  My commitment: I will still have time during my finals to help people
>  out on the mailing list, get acquainted with the community and its
>  processes, and even review patches if I can. This is because we get
>  holidays between each exam, and my grades are good enough to that I
>  can prioritise Git over my studies ;-)

Because of how hard COVID's second wave has hit my place, my exams
(which happen offline) had been indefinitely postponed. My university
has since given me the new dates for the finals -- either I give it on
June 2, or give it on an unannounced date in July. Either way it will
be happening during the GSoC coding period.

I just want to reiterate that I will be less available in the two weeks
during which the exams take place. I intend to work half-time on the
project only for those two weeks, and I don't mind working a little
extra on the other days to make up for it.

I will send another update for which slot I will be choosing *if* I get
selected for GSoC. Since the dates are shifting around a lot, according
to the situation, I will send updates on those as well.

>  And on the safe side, I will still engage with the community from now
>  till 07/06 so that the community bonding period is not compromised in
>  any way.
> 
>  Periods of abundant availability: After 29/05 all the way to the first
>  week of August, I will be having my summer break, so I can dedicate
>  myself to Git full-time :-)
> 
>  I would have also finished all my core courses, so even after that, I
>  will have enough of time to give back to Git past my GSoC period.
> 
>  Phase 1: 07/06 to 14/06 -- Investigate and devise a strategy to port
>  the submodule functions
>  - This phase will be more diagrams in my notebook than code in my
>    editor -- I will go through all the methods used to port the other
>    submodule functions and see how to do the same for what is left.
>  - I will find the C equivalents of all the shell invocations in
>    `git-submodule.sh', and see what invocations have /no/ equivalent
>    and need to be created as helpers in C (Eg: What is the equivalent
>    to the `ensure-core-worktree' invocation in C?). For all the helpers
>    and new functionality that I do introduce, I will need to create the
>    testing strategy for the same.
>  - I will go through all the work done by Shourya in his patch, and try
>    to understand it properly. I will also see the mistakes that were
>    caught in all the reviews for previous submodule conversion patches
>    and try to learn from them before I jump to the code.
>  - Deliverable: I will create a checklist for all the work that needs
>    to be done with as much detail as I can with the help of inputs from
>    my mentor and all the knowledge I have gained in the process.
> 
>  Phase 2: 14/06 to 28/06 -- Convert `add' to builtin in C
>  - I will work on completing `git submodule add'. One strategy would be
>    to either reimplement the whole thing using what was learnt in
>    Shourya's attempt, but it is probably wiser to just take his patch
>    and modify it. I would know what to do by the time I reach this
>    phase.
>  - I will also add tests for this functionality. I will also document
>    my changes when required. These would be unit tests for the helpers
>    introduced, and integration of `add' with the other commands.
>  - Deliverable: Completely port `add' to C!
> 
>  Phase 3: 28/06 to 16/08 -- Convert `update' to builtin
>  - Some work has already been done by Stephan Beller that moves the
>    functionality of `update' to `submodule--helper.c':
>    <https://github.com/git/git/commit/48308681b072a1d32e1361c255347324a8ad151e>,
>    but a lot of the business logic of going into the submodule and
>    checking out or merging or rebasing needs to still be converted.
>    Plenty to do here.
>  - As with `add', all of the appropriate tests need to be written and
>    the changes documented. As I have learnt from the Pro Git Book,
>    there are a lot of subtleties with how update does its work that I
>    need to watch out for.
>  - Deliverable: Completely port `update' to C!
> 
>  Bonus Phase: If I am ahead of time -- Remove the need for a
>  `submodule--helper', and make it a proper C builtin.
>  - Once all the submodule functionality is ported, the shell script is
>    not really doing much more than parsing the arguments and passing it
>    to the helper. We won't need this anymore if it is implemented.
> 
> 
> 8 Beyond GSoC
> =============
> 
>  I love the process of working as a community more than anything else,
>  and I already felt very welcomed by the Git community the moment I
>  started sending in my microproject patch series. Whether I am selected
>  or not, I will continue giving back to Git wherever I can. Since my
>  final year is light on coursework, I will be able to mentor people and
>  help expand the Git developer community through all the ways I can (be
>  it code review, helping people find the right resources or evangelism
>  of Git).
> 
> 
> 9 Blogging
> ==========
> 
>  I will be blogging about my progress on a weekly basis and either post
>  it on my website at <https://atharvaraykar.me> (probably will tuck it
>  away in a /gsoc path). Technical blogging is not particularly new to
>  me, and I hope my posts can help future contributors of Git.
> 
> 
> 10 Final Remarks: A little more about me
> ========================================
> 
>  These are some of my core values that I believe will be important to
>  pull off this project and make the most of my time in GSoC:
>  - Hard problems don't frustrate me, rather they excite me. Bugs make
>    my brain perk up. I love the process of learning.
>  - I am pro-transparency. If I am having some trouble, I will be open
>    about it. I don't hesitate to ask questions and dig deep if I need
>    to.
>  - At the same time, when I ask a question, I only do so after I have
>    struggled with the problem for enough time and done my due diligence
>    in trying to solve it. Clear communication is very important to make
>    this work.
>  - I am also very comfortable with learning things all on my own (I
>    have barely known any other way), and working in a remote,
>    asynchronous setting.
>  I hope to make the world better in my own small way by contributing to
>  a tool that everyone uses and I like. It's more rewarding than any
>  internship that my peers are doing this year. I look forward to
>  learning more.
> 

--
Atharva Raykar


^ permalink raw reply	[relevance 2%]

* [GSoC] Proposal: Convert Git submodule to built-in
@ 2021-04-13 10:26  5% Firmin Martin
  0 siblings, 0 replies; 200+ results
From: Firmin Martin @ 2021-04-13 10:26 UTC (permalink / raw)
  To: git; +Cc: christian.couder, shouryashukla.oo, periperidip

Hi everyone and potential mentors,

I'm Firmin, a master student who plan applying to GSoC this year. You can find
below my proposal "Convert Git submodule to built-in". Any thought or
feedback are welcomed.

I'm sorry to send my proposal this late, but I was overwhelmed these days.

I highly recommend to read the Google docs version of my proposal as the
textual version (converted through pandoc) missed all hyperlinks,
markups and heading levels. 

    https://docs.google.com/document/d/1321TC1Nkn-MpjvKv0VigEHRzcMIyOHO6m8dMsw9SCb4/edit?usp=sharing

Thanks,

Firmin

==========================================================================

Personal Details

Contact Information

-   Name: Firmin Martin

-   Blog: https://firminmartin.com

-   Current location: Paris, France (UTC+02:00)

-   Availability: fully available starting from mid-April

-   Emails: <<email1>>, <<email2>>

-   Github: firmart

-   StackExchange: firmin-martin

Technical Background

I am Firmin Martin, a master student in Theoretical Computer Science at
École Normale Supérieure de Lyon. My interests include mathematical
logic (proof theory), formal verification and human-based computation.

My first ever programming language was C and it remains my favorite so
far. As a matter of fact, I was involved years ago in a bioinformatics
project at Institut Curie in which my task consisted of, among others,
refactoring a large portion (2k+ loc.) of a C MPI codebase and porting a
sequential Java code into a parallel MPI version. I thus developed, in
the meantime, solid debugging skills using Valgrind and GDB.

I also write shell scripts on a regular basis to satisfy my daily needs.

Programming Environment

I’m on a dual-boot Ubuntu 20.04/Windows 10, but work primarily on
Ubuntu. I use Emacs as my main editor and Vim in the terminal. I use Git
on a daily-basis either through git itself, the CLI utility tig or the
Emacs package Magit.

Open Source Contributions

I’m also a partisan of free/libre and open-source softwares, and
contribute to them regularly. That being said, my contribution to FLOSS
projects is limited to sporadic bug reports and tiny patches/PRs towards
softwares I use everyday. I also open-sourced some Emacs packages I plan
to include in the package archive in the future. Here is a short list of
my contributions to depict my interests.

-   A tiny PR to translate-shell. translate-shell coding-style has
      strongly inspired me when I wrote a cheat-sheet maker (2k+ loc. of
      pure awk) as a (now archived) hobby project.

-   Emacs packages

    -   A fix from the maintainer of Emacs Org mode based on a bug I
          reported

    -   Some packages I wrote: org-glaux, notmuch-notify,
          org-desc-initial etc.

    -   Some packages I contributed to: vuiet, mpv.el, org-krita etc.

Learning Git’s Design & Development Process

Despite using Git for years, I reached its codebase for the first time
in mid-March 2021. I started to learn the organization of the source
code (built-in vs. non-built-in scripts, subcommands cmd_* and more),
the test infrastructure, the internals (through the Git Pro book), etc.
It also took me a while to learn the development process of Git: e.g.
the release cycle, and peculiarly to figure out how email-based workflow
works as I was used to Github’s PR model and prior this time frame,
though I subscribed to some mailing lists using this workflow (Org mode,
notmuch), I didn’t go further than reporting bugs and suggesting
workarounds. During this period, I also had the opportunity to learn how
to polish and build a patch through some commands/options I never used
before: git rebase -i, git add -p or git pull -r. Navigating through the
commits log was also very helpful to apprehend design decisions.

Contributions to Git

+----------------------------------------------------------------------+
| user-manual.txt: assign preface an id and a title                    |
|                                                                      |
| Status: next, also see What's cooking in git.git.                    |
|                                                                      |
| git/git: fc12b6fdde47cfb5                                            |
|                                                                      |
| firmart/git: doc/assign-preface-id-and-title                         |
|                                                                      |
| Mailing list: [PATCH v2 0/1][GSoC] user-manual.txt: assign preface   |
| an id and a title                                                    |
|                                                                      |
| Abstract:                                                            |
|                                                                      |
|   Fix two warnings causing visible issues in                         |
|   Documentation/{user-manual.texi, git.info}.                        |
+----------------------------------------------------------------------+

+----------------------------------------------------------------------+
| doc: (monospace) apply CodingGuidelines on a large-scale             |
|                                                                      |
| Status: WIP                                                          |
|                                                                      |
| firmart/git: doc/apply-coding-guidelines                             |
|                                                                      |
| Mailing list: [RFC PATCH v1 00/13][GSoC] doc: (monospace) apply      |
| CodingGuidelines on a large-scale                                    |
|                                                                      |
| Abstract:                                                            |
|                                                                      |
|   Make the documentation fully compliant regarding monospace font.   |
|   It involves around 6k lines of changes made through interactive    |
|   substitutions. It probably needs to be split off in even smaller   |
|   chunks to be digestible by reviewers.                              |
+----------------------------------------------------------------------+

Project proposal: Convert submodule to builtin

Introduction

Quoting from the Pro Git book:

  “Git was initially a toolkit for a version control system rather than
  a full user-friendly VCS, it has a number of subcommands that do
  low-level work and were designed to be chained together UNIX-style or
  called from scripts. These commands are generally referred to as Git’s
  ‘plumbing’ commands, while the more user-friendly commands are called
  ‘porcelain’ commands.”

A lot of Git’s “porcelain” commands stem from this idea and were
consequently written as shell/Perl scripts composed by Git’s “plumbing”
commands and other shell utilities. Over the time, different platforms
were targeted to be supported and projects using Git have grown in size.
Portability and performance became non-negligible topics.

For instance, Git for Windows relies on a modified version of Cygwin,
called MSYS2, to run those shell scripts. They tend to have
compatibility issues due to this requirement (see the next section).

Moreover, even though subshell overheads are relatively cheap, they can
grow fastly when involved in a loop or spawn in a nested fashion. The
situation is even worse when a high-level porcelain shell command calls
another one. Hopefully, since the very beginning, it was a common
practice to make mature shell commands built-in to avoid this concern.

To see the evolution of this process, one can easily make the following
table indicating the date and the commit of popular commands made
built-in thanks to git naming consistency. Though some of them are born
built-in, the majority was first implemented as shell/Perl or even Tcl
scripts[1].

Legend.

-   <date>: date of the command turning built-in.

-   builtin (<date>): the command is implemented directly as built-in in
      the given date.

-   ongoing (<patch>): there is an active process to turn the command
      built-in.

+----------+----------+----------+----------+----------+----------+
| Command  | Date     | Commit   | Command  | Date     | Commit   |
+==========+==========+==========+==========+==========+==========+
| add      | 20       | c6       | mai      | builtin  | 20       |
|          | 16-05-17 | 99f9b924 | ntenance |          | 57d75038 |
|          |          |          |          | (202     |          |
|          |          |          |          | 0-09-17) |          |
+----------+----------+----------+----------+----------+----------+
| am       | 20       | 78       | merge    | 20       | 1c       |
|          | 15-08-04 | 3d7e865e |          | 08-07-07 | 7b76be7d |
+----------+----------+----------+----------+----------+----------+
| archive  | builtin  | 4d       | mv       | 20       | 11       |
|          |          | f096a5ca |          | 06-06-26 | be42a476 |
|          | (200     |          |          |          |          |
|          | 6-09-07) |          |          |          |          |
+----------+----------+----------+----------+----------+----------+
| bisect   | ongoing  | N/A      | notes    | 20       | cd       |
|          |          |          |          | 10-02-13 | 067d3bf4 |
|          | (last    |          |          |          |          |
|          | patch)   |          |          |          |          |
+----------+----------+----------+----------+----------+----------+
| branch   | 20       | c3       | pull     | 20       | b1       |
|          | 06-10-23 | 1820c26b |          | 15-06-18 | 456605c2 |
+----------+----------+----------+----------+----------+----------+
| bundle   | builtin  | 2e       | push     | 20       | ec       |
|          |          | 0afafebd |          | 06-08-02 | 19a22b74 |
|          | (200     |          |          |          |          |
|          | 7-02-22) |          |          |          |          |
+----------+----------+----------+----------+----------+----------+
| checkout | 20       | 78       | ra       | builtin  | 34       |
|          | 08-02-07 | 2c2d65c2 | nge-diff |          | 8ae56cb2 |
|          |          |          |          | (202     |          |
|          |          |          |          | 0-09-17) |          |
+----------+----------+----------+----------+----------+----------+
| che      | 20       | 95       | rebase   | 20       | d0       |
| rry-pick | 07-03-01 | 09af686b |          | 19-03-18 | 3ebd411c |
+----------+----------+----------+----------+----------+----------+
| clean    | 20       | 11       | reset    | 20       | 0e       |
|          | 07-11-11 | 3f10f22f |          | 07-09-11 | 5a7faa3a |
+----------+----------+----------+----------+----------+----------+
| clone    | 20       | 84       | restore  | builtin  | 46       |
|          | 08-04-27 | 34c2f1af |          | (201     | e91b663b |
|          |          |          |          | 9-04-25) |          |
+----------+----------+----------+----------+----------+----------+
| commit   | 20       | f5       | revert   | 20       | 95       |
|          | 07-11-08 | bbc3225c |          | 07-03-01 | 09af686b |
+----------+----------+----------+----------+----------+----------+
| describe | 20       | 9a       | rm       | 20       | d9       |
|          | 07-01-10 | 0eaf83ea |          | 06-05-19 | b814cc97 |
+----------+----------+----------+----------+----------+----------+
| diff     | 20       | 8a       | shortlog | 20       | b8       |
|          | 06-05-01 | b99476ec |          | 06-11-19 | ec59234b |
+----------+----------+----------+----------+----------+----------+
| difftool | 20       | 01       | show     | 20       | ba       |
|          | 17-01-19 | 9678d6b1 |          | 06-04-15 | 1d45051e |
+----------+----------+----------+----------+----------+----------+
| fetch    | 20       | b8       | sparse-  | builtin  | 94       |
|          | 07-09-10 | 88d61c83 | checkout |          | c0956b60 |
|          |          |          |          | (201     |          |
|          |          |          |          | 9-11-21) |          |
+----------+----------+----------+----------+----------+----------+
| form     | 20       | 68       | stash    | 20       | 40       |
| at-patch | 06-05-21 | 5637381a |          | 19-02-25 | af146834 |
+----------+----------+----------+----------+----------+----------+
| gc       | 20       | 67       | status   | 20       | f5       |
|          | 07-03-13 | 57ada403 |          | 07-11-08 | bbc3225c |
+----------+----------+----------+----------+----------+----------+
| grep     | 20       | 63       | s        | ongoing  | N/A      |
|          | 06-05-16 | dffdf03d | ubmodule |          |          |
|          |          |          |          | (last    |          |
|          |          |          |          | patch)   |          |
+----------+----------+----------+----------+----------+----------+
| init     | builtin  | e8       | switch   | builtin  | d7       |
|          |          | 3c516331 |          |          | 87d311db |
|          | (200     |          |          | (201     |          |
|          | 5-04-07) |          |          | 9-03-29) |          |
+----------+----------+----------+----------+----------+----------+
| log      | 20       | e3       | tag      | 20       | 62       |
|          | 06-04-14 | a125a94d |          | 07-07-20 | e09ce998 |
+----------+----------+----------+----------+----------+----------+
|          | worktree | builtin  | df       |          |          |
|          |          |          | 0b6cfbda |          |          |
|          |          | (201     |          |          |          |
|          |          | 5-01-29) |          |          |          |
+----------+----------+----------+----------+----------+----------+

Additionally, per a mail from Johannes Schindelin, in which he stated
the current conversion process of remaining scripts, we can further note
the following scripts’ conversion status (with my personal adaptation).

+----------------+----------------+----------------+----------------+
| Scripts        | Status         | Scripts        | Status         |
+================+================+================+================+
| git-difft      | Candidates for | git-fi         | Deprecated     |
| ool--helper.sh | being          | lter-branch.sh |                |
|                | converted      |                |                |
| git-mer        |                | gi             |                |
| getool--lib.sh |                | t-rebase--pres |                |
|                |                | erve-merges.sh |                |
| gi             |                |                |                |
| t-mergetool.sh |                |                |                |
|                |                |                |                |
| git-me         |                |                |                |
| rge-octopus.sh |                |                |                |
|                |                |                |                |
| git-mer        |                |                |                |
| ge-one-file.sh |                |                |                |
|                |                |                |                |
| git-me         |                |                |                |
| rge-resolve.sh |                |                |                |
+----------------+----------------+----------------+----------------+
| git-           | Support for    | g              | Too complex or |
| quiltimport.sh | legacy[3] SCMs | it-instaweb.sh |                |
|                |                |                | too many       |
| git-a          |                | git-r          | dependencies   |
| rchimport.perl |                | equest-pull.sh |                |
|                |                |                |                |
| git-cvsexp     |                | git-           |                |
| ortcommit.perl |                | web--browse.sh |                |
|                |                |                |                |
| git-           |                | git-s          |                |
| cvsimport.perl |                | end-email.perl |                |
|                |                |                |                |
| git-           |                | git-svn.perl   |                |
| cvsserver.perl |                |                |                |
|                |                | git-add--in    |                |
|                |                | teractive.perl |                |
+----------------+----------------+----------------+----------------+

 Summary

The goal of this GSoC project is to finish the ongoing conversion
(started in 2015) of the submodule’s commands from shell script into C
and totally get rid of the file git-submodule.sh. The file
submodule--helper.c will henceforth be renamed to submodule.c. The
benefit to doing so is not only performance-wise, but also
compatibility-wise. A quote from Johannes Schindelin, the maintainer of
Git for Windows, could explain this well:

  “Since git submodule is still implemented as a Unix shell script (and
  traditionally, there have been tons of issues with that due to the
  need to use a derivative of Cygwin to interpret such scripts) [...]”

Previous Works

-   During 2015-2019, Stefan Beller has worked on the conversion of the
      update command, has finished the conversion of the init command
      and has ported multiple helper functions in C (module_list,
      resolve_relative_url, update-module-mode etc.). He has also
      written in C the absorbgitdirs command.

-   Prathamesh Chavan (GSoC 2017) has finished the conversion of the
      foreach, deinit, sync and status commands and has ported the
      helper function set_name_rev in C. He has also worked on an early
      version of the command add on which Shourya Shukla was based
      later.

-   Shourya Shukla (GSoC 2020) has finished the conversion of set-url
      and set-branch commands. He also continued and finished Chavan’s
      work on the summary (patch) command. His patch on the conversion
      of the add command is currently at version 3, but staled since
      then.

Conversion Status of Submodule’s Subcommands

Most of the submodule’s subcommands (set-branch, set-url, summary,
status, init, deinit, foreach and sync) have only the options left to
parse. As for absorbgitdirs, it was written fully in C by Stefan Beller
since the beginning.

Consequently, the remaining tasks are the conversion of the update and
add subcommands which have both 160 loc. involving essentially Git’s
plumbing, branching plus some basic filtering with sed and grep besides
the options left to parse. The conversion of the add subcommand has a
long-standing history (see previous works).

Correspondence Between Submodule’s Shell and C Code

To better understand how the conversion would work and how the converted
code would look, one should examine the components constituting a
submodule’s subcommand in shell and C respectively.

-   A submodule’s subcommand in shell corresponds simply to

    -   An entry point function cmd_<subcommand> (e.g. cmd_add) which
          handles options parsing, performs business logic with the
          assistance of helper functions and Git’s plumbing.

    -   Several helper functions such as sanitize_submodule_env which
          essentially unset all Git’s environment variables of a
          repository except GIT_CONFIG_PARAMETERS.

-   On the other hand, a submodule’s subcommand in C is more structural.
      It corresponds to

    -   A “principal” function <subcommand>_submodule (e.g.
          init_submodule) which performs the essential business logic.
          It has at least three parameters: path, prefix and flags
          coming from the subcommand’s entry point (see below).

    -   A facultative callback function <subcommand>_submodule_cb (e.g.
          init_submodule_cb) serving as an argument of the higher-order
          function for_each_listed_submodule which applies the callback
          function on a list of submodules one by one. The callback
          functions are essentially wrappers of the subcommand’s
          “principal” function except that they have a uniform signature
          (precisely, the type each_submodule_fn).

    -   A facultative[4] callback structure <subcommand>_cb (e.g.
          init_cb), initialized by the macro <SUBCOMMAND>_CB_INIT (e.g.
          INIT_CB_INIT), storing option values and flags to serve as an
          argument of for_each_listed_submodule and the callback
          function. This structure is necessary to keep the uniform
          signature of the callback function: it packs together some
          arguments which feed the “principal” function.

    -   An entry point function module_<subcommand>[5] (e.g.
          module_init) which parses options, handles flags and
          eventually calls for_each_listed_submodule along with the
          callback function and structure on a list of submodules.

    -   A registration of the subcommand in the structure commands and
          indication whether the subcommand supports --super-prefix.

    -   Several helper functions: either subcommand-specific (e.g.
          print_status is uniquely dedicated to the status subcommand)
          or with general purpose (e.g. revision name retrieval:
          compute_rev_name; URL computation: relative_url,
          chop_last_dir; string manipulation: starts_with_dot_dot_slash
          etc.)

Proposed Timeline

Present - 17 May: warm-up

While waiting for the announcement of the selected student, I would want
to be more involved in the Git’s development & submission process, as I
would be fully available starting from mid-April. This would start by
discussing in the mailing-list some RFCs I have in mind, not necessarily
directly related to submodules (as it is reserved to the selected
student), e.g.

-   Address the “NEEDSWORK” in path.c::normalize_path_copy_len. This can
      be proved useful in the next phase while dealing with the path
      normalization (multiple trailing slashes) occurred in cmd_add.
      This point was discussed in Shourya Shukla last patch's cover
      letter.

-   Improve git add -p user interface -- fix corrupt patch line number,
      paginate diff hunks, and change behaviour of SIGINT in the
      interactive process -- and trying to reproduce an issue I faced,
      namely “git add -p restarts itself after selecting the last diff
      hunk” and figure out a solution.

-   See whether there is room for improvement regarding git format-patch
      --cover-letter which overwrites existing cover-letter having the
      same name. Could we just replace the diff statistics of the old
      cover letter, and keep its title and content ? Or alternatively,
      create a new cover letter whose filename is suffixed by “~” or “_”
      ? These are the questions that need to be answered.

-   Adding a “subcommand” entry in Git’s glossary. E.g. submodule is a
      Git’s subcommand, add is a submodule’s subcommand.

-   Finish the work-in-progress patch series which aims to make the
      documentation fully compliant regarding monospaced font (see
      Contributions to Git).

May 17 - June 7: community bonding

I will use this three weeks time frame to familiarize myself with the
codebase and make a series of trivials yet useful patches (as depicted
below) to present a slightly polished version to the community in hope
to obtain feedback in an early stage and not miss out important
mistakes. In the end, it would help to have a better estimation of the
schedule with mentors. More concretely, that could be translated as
follows.

-   Study the last patch of Shourya Shukla and available routines in
      submodule.c and builtin/submodule--helper.c.

-   See if there is any portion of code in his patch which could be
      reused to

-   Port shell helper functions: especially sanitize_submodule_env which
      appears numerous times, but also its by-products is_tip_reachable
      and fetch_in_submodule.

-   Port the basic filtering using sane_grep and sed occurring in
      cmd_add (e.g. path normalization). As stated in the previous
      section, the function path.c::normalize_path_copy_len once fixed
      could be proved useful.

-   Find out present issues in his patch (e.g. potential memory leak in
      string manipulation) and incorporate feedback to the patch.

-   Study and update present tests to cover new code.

-   Port set-branch, set-url, summary, status, init, deinit, foreach and
      sync options parsing into builtin/submodule--helper.c so that they
      merely become wrapper of their C counterparts (i.e. exactly the
      current status of the absorbgitdirs command).

-   Submit the slightly improved version (RFC) of Shourya Shukla's patch
      incorporating above considerations (split off in multiple commits)
      along with a summary of the patch status. Having a first round of
      review in an early stage would help to detect important mistakes
      requiring to be taken into consideration.

-   Discuss with mentors to rearrange the schedule if necessary.

June 7 - July 12: porting the add subcommand & mid-term evaluation (5 weeks)

I would want to start tackling the add subcommand as I believe its
long-standing conversion was due to its low priority (it was in Chavan
proposal’s wishlist and in Shukla proposal’s last phase). At this stage,
based on the previous phase’s investigation and first round of review,
it would be clear what pieces are missing.

Also, as Prathamesh Chavan’s weekly summaries suggest (12th, 13th and
14th), he took more than two weeks to deal with failed tests as the
invocation of the subcommand add is widely present in the tests (137
instances[6] among 53 test files[7]). I would expect to spend a fair
amount of time dealing with them too.

July 12 - August 2: porting the update subcommand (3 weeks)

As Philippe Blain pointed out on Github, it would be better to start
converting the update command after having acquired enough insight
regarding git submodules. That is why I place it right after the port of
the add command. I allocate 3 weeks to deal with it as it is mainly
constituted of business logic involving built-in function calls. This
being said, I will be peculiarly cautious as bugs could emerge
unexpectedly.

August 2 - August 16: buffering phase

This period will serve as a buffering phase.

-   If everything goes well, the remaining part of git-submodule.sh will
      be converted at this phase.

-   This stage will also be the time for polishing, testing and
      debugging. Without being too optimistic and considering past years
      students' schedules, there would still be bugs lurking around at
      this phase.

-   If the submit process goes faster than expected, I will use the
      remaining time to tackle some of the numerous NEEDSWORK in
      submodule.c (three in total) and builtin/submodule--helper.c (five
      in total).

Weekly Blogpost 

I commit myself to writing a blog post each week on my blog to allow
mentors and other contributors keep tracking of my progress. I felt that
Shukla’s blog has provided valuable insight at the moment of this
document being written, and according to Shukla’s words, Matheus
Tavares’ blog (GSoC 2019) has in turn somehow inspired him. I hope I
could do the same for future GSoC applicants and keep this great
tradition.

Regarding the Review Process

As pointed out by Junio C. Hamano, converting a subcommand in a single
patch makes the review process harder than it should be. I suggest
gradually converting portions of the shell script into multiple C
internal helping commands and commit them separately while keeping the
code functionality. Doing so, it would be easier to locate the removed
shell code and compare it to the converted C code. This is actually what
Stefan Beller has done when converting a part of the update command. In
the last patch of Shourya Shukla, once everything is satisfying enough
(e.g. no memory leak), the commits could be squashed and the helper
functions could be merged if needed.

I also plan to send a weekly summary in the mailing list to present the
ongoing progress and challenge. When things become mature enough, I will
also attach the whole patch series to the summary (exactly as Prathamesh
Chavan did from week 5).

Epilogue

I unfortunately started late and did not have the opportunity to
contribute to code-related patches being overwhelmed (see contributions
to Git). But, to be fair, the amount of things I learned during this
period through the mailing list, the commits log, the documentation or
the codebase is absolutely stunning.

As discussed at the beginning of this document, I have the habit of
contributing to open source softwares I’m using on a regular basis. It
seems the bottleneck of contributing to Git was the lack of
understanding on the mail-based workflow, a thing that I happily
overcomed. From now on, I would be able to contribute to more
open-source projects I benefit from (e.g. Emacs, Org-mode, notmuch
etc.). And of course, the adventure with Git has just started!

References

Proposals

-   Johannes Schindelin's description of the project on Git for Windows’
      issue tracker

-   Shourya Shukla's GSoC 2020 proposal

-   Prathamesh Chavan's GSoC 2017 proposal

Final Reports

-   Prathamesh Chavan's final report

-   Shourya Shukla's final report

Last Patch Series

-   Stefan Beller's partial port of the subcommand update (including
      implementation of the helper function update_module_mode)

-   Stefan Beller's port of helper functions: module_list, module_name
      and module_clone

-   Prathamesh Chavan's port of the status subcommand and introduction
      of get_submodule_displaypath and for_each_listed_submodule

-   Prathamesh Chavan's port of the foreach subcommand

-   Prathamesh Chavan's port of the sync and deinit subcommand

-   Shourya Shukla's port of the set-branch subcommand

-   Shourya Shukla’s port of the set-url subcommand

-   Shourya Shukla's port on the summary subcommand

-   Shourya Shukla’s last patch on the port of the add subcommand

Documentations

-   Git Tools - Submodules from the Pro Git book

-   Git’s man pages: gitsubmodules, git-submodule and gitmodules

GSoC Weekly Summary

-   Shourya Shukla's Blog

-   Prathamesh Chavan's weekly summary and patch series

[1] See gitk-git/gitk and git-gui/git-gui.sh

[2] That being said, quilt last release was from 2019.

[3] That being said, quilt last release was from 2019.

[4] Relevant if a callback function is required by the subcommand.

[5] It does basically the same thing as cmd_<git-subcommand> functions
(e.g. cmd_commit) except that the prefix module_ is a convention
suggesting it’s a subcommand of a Git’s subcommand (i.e. in our context
a submodule’s subcommand).

[6] grep -R 'git submodule add' | wc -l

[7] grep -Rl 'git submodule add' | sort | uniq | wc -l

^ permalink raw reply	[relevance 5%]

* [GSoC][Draft Proposal v3] Finish converting git submodule to builtin
  2021-04-08 10:19  5% ` [GSoC][Draft Proposal v2] " Atharva Raykar
@ 2021-04-11 10:17  5%   ` Atharva Raykar
  2021-05-14 16:00  2%   ` [GSoC][Draft Proposal v2] " Atharva Raykar
  1 sibling, 0 replies; 200+ results
From: Atharva Raykar @ 2021-04-11 10:17 UTC (permalink / raw)
  To: git; +Cc: christian.couder, shouryashukla.oo, periperidip

Changes since v2:

- Add more detail in my example of how I would convert `submodule update`
  -- mainly I showed possible names for the invocations, the arguments it
  takes, and operations it performs.

- Clarify that `module_update()` is a function that I will write, and
  does not currently exist in the codebase.

- Add stepwise high-level workflow in section 6

- Exorcise the last remaining gits and bring back Gits

Markdown version: https://gist.github.com/tfidfwastaken/0c6ca9ef2a452f110a416351541e0f19

--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<--

                          ___________________

                           GSOC GIT PROPOSAL

                             Atharva Raykar
                          ___________________


Table of Contents
_________________

1. Personal Details
2. Background
3. Me and Git
.. 1. Current knowledge of Git
4. The Project: Finish converting `git submodule' to builtin
5. Prior work
6. General implementation strategy
7. Timeline (using the format dd/mm)
8. Beyond GSoC
9. Blogging
10. Final Remarks: A little more about me


1 Personal Details
==================

  Name : Atharva Raykar
  Major : Computer Science and Engineering
  Email : raykar.ath@gmail.com
  IRC nick : atharvaraykar on #git and #git-devel
  Address : RB 103, Purva Riviera, Marathahalli, Bangalore
  Postal Code : 560037
  Time Zone : IST (UTC+5:30)
  GitHub : github.com/tfidfwastaken


2 Background
============

  I am Atharva Raykar, currently in my third year of studying Computer
  Science and Engineering at PES University, Bangalore. I have always
  enjoyed programming since a young age, but my deep appreciation for
  good program design and creating the right abstractions came during my
  exploration of the various rabbitholes of knowledge originating from
  communities around the internet. I have personally enjoyed learning
  about Functional Programming, Database Architecture and Operating
  Systems, and my interests keep expanding as I explore more in this
  field.

  I owe my appreciation of this rich field to these communities, and I
  always wanted to give back. With that goal, I restarted the [PES Open
  Source] community in our campus, with the goal of creating spaces
  where members could share knowledge, much in the same spirit as the
  communities that kickstarted my journey in Computer Science. I learnt
  a lot about collaborating in the open, maintainership, and reviewing
  code. While I have made many small contributions to projects in the
  past, I am hoping GSoC will help me make the leap to a larger and more
  substantial contribution to one of my favourite projects that made it
  all possible in my journey with Open Source.


[PES Open Source] <https://pesos.github.io>


3 Me and Git
============

  Here are the various forms of contributions that I have made to Git:

  - [Microproject] userdiff: add support for Scheme
    Status: In progress, patch v3 requiring a review
    List: <https://lore.kernel.org/git/20210408091442.22740-1-raykar.ath@gmail.com/>

  - [Git Education] Conducted a workshop with attendance of hundreds of
    students new to Git, and increased the prevalence of of Git's usage
    in my campus.
    Photos: <https://photos.app.goo.gl/T7CPk1zkHdK7mx6v7> and
    <https://photos.app.goo.gl/bzTgdHMttxDen6z9A>

  I intend to continue helping people out on the mailing list and IRC
  and tending to patches wherever possible in the meantime.


3.1 Current knowledge of Git
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  I use Git almost daily in some form, and I am fairly comfortable with
  it. I have already read and understood the chapters from the Git Book
  about submodules along with the one on objects, references, packfiles
  and the refspec.


4 The Project: Finish converting `git submodule' to builtin
===========================================================

  Git has historically had many components implemented in the form of
  shell scripts. This was less than ideal for several reasons:
  - Portability: Non-POSIX systems like Windows don't play nice with
    shell script commands like grep, cd and printf, to name a few, and
    these commands have to be reimplemented for the system. There are
    also POSIX to Windows path conversion issues.
  - No direct access to plumbing: Shell commands do not have direct
    access to the low level Git API, and a separate shell is spawned to
    just to carry out their operations.
  - Performance: Shell scripts tend to create a lot of child processes
    which slows down the functioning of these commands, especially with
    large repositories.
  Over the years, many GSoC students have converted the shell versions
  of these commands to C. Git `submodule' is the last of these to be
  converted.


5 Prior work
============

  I will be taking advantage of the knowledge that was gained in the
  process of the converting the previous scripts and avoiding all the
  gotchas that may be present in the process. There may be a bunch of
  useful helper functions in the previous patches that can be reused as
  well (more investigation needed to determine what exactly is
  reusable).

  Currently the only other commands left to be completed for `submodule'
  are `add' and `update'. Work for `add' has already been started by a
  previous GSoCer, Shourya Shukla, and needs to picked up from there.
  `update' has had some of its functionality moved over to
  `submodule--helper.c' where Stefan Beller added the helper functions
  `update-clone', `update-module-mode', `remote-branch' and more.

  References:
  <https://github.com/gitgitgadget/git/issues/541#issuecomment-769245064>
  <https://github.com/git/git/commit/4d6d6ef1fc>
  <https://github.com/git/git/commit/48308681b072a1d32e1361c255347324a8ad151e>
  <https://github.com/git/git/commit/ee69b2a90c5031bffb3341c5e50653a6ecca89ac>
  <https://github.com/git/git/commit/92bbe7ccf1fedac825f2c6ab4c8de91dc5370fd2>

  I'll have these as my references when I am working on the project:
  His blog about his progress:
  <https://shouryashukla.blogspot.com/2020/08/the-final-report.html>
  (more has been implemented since)
  Shourya's latest patch for `submodule add':
  <https://lore.kernel.org/git/20201007074538.25891-1-shouryashukla.oo@gmail.com/>

  For the most part, the implementation looks fairly complete, but there
  seems to be a segfault occurring, along with a few changes suggested
  by the reviewers. It will be helpful to contact Shourya to fully
  understand what needs to be done.

  Prathamesh's previous conversion work:
  <https://lore.kernel.org/git/20170724203454.13947-1-pc44800@gmail.com/#t>

  The ultimate goal would be to get rid of `git-submodules.sh'
  altogether -- which will complete the porting efforts of `submodule'
  to C.


6 General implementation strategy
=================================

  The way to port the shell to C code for `submodule' will largely
  remain the same. There already exists the builtin
  `submodule--helper.c' which contains most of the previous commands'
  ports. All that the shell script for `git-submodule.sh' is doing for
  the previously completed ports is parsing the flags and then calling
  the helper, which does all the business logic.

  So I will be moving out all the business logic that the shell script
  is performing to `submodule--helper.c'. Any reusable functionality
  that is introduced during the port will be added to `submodule.c' in
  the top level.

      For example: The general strategy for converting `cmd_update()' would
      be to have an invocation of to `submodule--helper update <flags>' in
      the shell script which maps to a C function which I would create,
      named `module_update()'. This would perform the work being done by the
      shell script past the flags being parsed and make the necessary call
      to `update_clone()'.
      `update_clone()' takes care of cloning all the submodules and returns
      their SHA1, whether the module was just cloned, and the path to the
      submodule. For each cloned module, it uses the information in those
      entries to find out the update mode through `module_update_mode()',
      and run the appropriate operation according to that mode (like a
      rebase, if that was the update mode). The SHA1 from `update_clone()'
      helps us determine whether we need to update the submodules to match
      what the superproject expects.

      One possible way this work can be broken up into multiple patches is
      by moving over the shell code into C in a bottom-up manner.

      For example: The shell part which retrieves the latest revision in the
      remote (if --remote is specified) can be wrapped into an invocation
      like `git submodule--helper update-remote ${nofetch:+--nofetch}
      <sm_path>'. This would return the remote name and SHA1 for the remote
      tracked by the submodule. Then we can move the part where we run the
      update method (ie the `case' on line 611 onwards) into a C function
      that is invoked by something that looks like `git submodule--helper
      run-update-operation $update-module'. This will run the update
      function, ie, either checkout, merge or rebase depending on the flags
      passed, or configuration setup by the end user. Eventually, the shell
      part will just look like a bunch of invocations to
      `submodule--helper', at which point, the whole thing can be
      encapsulated in a single command called `git submodule--helper update
      <flags>' (Bonus: Move the whole functionality to C, including the
      parsing of flags, to work towards getting rid of `git-submodule.sh').
      I believe this is a fairly non-destructive and incremental way to
      work, and the porting efforts by Stefan seem to follow this same kind
      of philosophy. I will most likely end up tuning the size of these
      increments when I get around to planning in my first phase of the
      project.

  What I have mentioned above is just illustrating what my workflow
  might look like, and the details are subject to change as I will
  probably discover nicer ways to get to the end goal of moving
  everything to `submodule--helper'. What will remain unchanged though,
  is my high level workflow, which can be summarized to these four
  steps:

  1. Identify parts in git-submodule.sh that have cohesive functionality
  2. Rewrite that functionality in C, which can be invoked from `git
     submodule--helper <function name> <args>`
  3. Remove the shell code and replace it with the above invocation.
     This could be sent as one patch, making it easier to review. Steps
     1 to 3 are repeated until the shell code is reduced to a bunch of
     calls to `submodule--helper'
  4. Once the shell code is reduced to only a bunch of calls to
     `submodule--helper', wrap all of that into one call that looks like
     `git submodule--helper update <flags>' that encapsulates all the
     functionality done by the other helper function calls.

  After this process, I will be adding the `add' and `update' command to
  the commands array in `submodule--helper.c'. And since these two
  functions are the last bit of functionality left to convert in
  submodules, an extended goal can be to get rid of the shell script
  altogether, and make the helper into the actual builtin [1].

  [1]
  <https://lore.kernel.org/git/nycvar.QRO.7.76.6.2011191327320.56@tvgsbejvaqbjf.bet/>


7 Timeline (using the format dd/mm)
===================================

  Periods of limited availability (read: hectic chaos):
  - From 13/04 to 20/04 I will be having project evaluations and lab
    assessments for five of my courses.
  - From 20/04 to 01/05 I have my in-semester exams.
  - For a period of two weeks in the range of 08/05 to 29/05 I will be
    having my end-semester exams.
  My commitment: I will still have time during my finals to help people
  out on the mailing list, get acquainted with the community and its
  processes, and even review patches if I can. This is because we get
  holidays between each exam, and my grades are good enough to that I
  can prioritise Git over my studies ;-)

  And on the safe side, I will still engage with the community from now
  till 07/06 so that the community bonding period is not compromised in
  any way.

  Periods of abundant availability: After 29/05 all the way to the first
  week of August, I will be having my summer break, so I can dedicate
  myself to Git full-time :-)

  I would have also finished all my core courses, so even after that, I
  will have enough of time to give back to Git past my GSoC period.

  Phase 1: 07/06 to 14/06 -- Investigate and devise a strategy to port
  the submodule functions
  - This phase will be more diagrams in my notebook than code in my
    editor -- I will go through all the methods used to port the other
    submodule functions and see how to do the same for what is left.
  - I will find the C equivalents of all the shell invocations in
    `git-submodule.sh', and see what invocations have /no/ equivalent
    and need to be created as helpers in C (Eg: What is the equivalent
    to the `ensure-core-worktree' invocation in C?). For all the helpers
    and new functionality that I do introduce, I will need to create the
    testing strategy for the same.
  - I will go through all the work done by Shourya in his patch, and try
    to understand it properly. I will also see the mistakes that were
    caught in all the reviews for previous submodule conversion patches
    and try to learn from them before I jump to the code.
  - Deliverable: I will create a checklist for all the work that needs
    to be done with as much detail as I can with the help of inputs from
    my mentor and all the knowledge I have gained in the process.

  Phase 2: 14/06 to 28/06 -- Convert `add' to builtin in C
  - I will work on completing `git submodule add'. One strategy would be
    to either reimplement the whole thing using what was learnt in
    Shourya's attempt, but it is probably wiser to just take his patch
    and modify it. I would know what to do by the time I reach this
    phase.
  - I will also add tests for this functionality. I will also document
    my changes when required. These would be unit tests for the helpers
    introduced, and integration of `add' with the other commands.
  - Deliverable: Completely port `add' to C!

  Phase 3: 28/06 to 16/08 -- Convert `update' to builtin
  - Some work has already been done by Stephan Beller that moves the
    functionality of `update' to `submodule--helper.c':
    <https://github.com/git/git/commit/48308681b072a1d32e1361c255347324a8ad151e>,
    but a lot of the business logic of going into the submodule and
    checking out or merging or rebasing needs to still be converted.
    Plenty to do here.
  - As with `add', all of the appropriate tests need to be written and
    the changes documented. As I have learnt from the Pro Git Book,
    there are a lot of subtleties with how update does its work that I
    need to watch out for.
  - Deliverable: Completely port `update' to C!

  Bonus Phase: If I am ahead of time -- Remove the need for a
  `submodule--helper', and make it a proper C builtin.
  - Once all the submodule functionality is ported, the shell script is
    not really doing much more than parsing the arguments and passing it
    to the helper. We won't need this anymore if it is implemented.


8 Beyond GSoC
=============

  I love the process of working as a community more than anything else,
  and I already felt very welcomed by the Git community the moment I
  started sending in my microproject patch series. Whether I am selected
  or not, I will continue giving back to Git wherever I can. Since my
  final year is light on coursework, I will be able to mentor people and
  help expand the Git developer community through all the ways I can (be
  it code review, helping people find the right resources or evangelism
  of Git).


9 Blogging
==========

  I will be blogging about my progress on a weekly basis and either post
  it on my website at <https://atharvaraykar.me> (probably will tuck it
  away in a /gsoc path). Technical blogging is not particularly new to
  me, and I hope my posts can help future contributors of Git.


10 Final Remarks: A little more about me
========================================

  These are some of my core values that I believe will be important to
  pull off this project and make the most of my time in GSoC:
  - Hard problems don't frustrate me, rather they excite me. Bugs make
    my brain perk up. I love the process of learning.
  - I am pro-transparency. If I am having some trouble, I will be open
    about it. I don't hesitate to ask questions and dig deep if I need
    to.
  - At the same time, when I ask a question, I only do so after I have
    struggled with the problem for enough time and done my due diligence
    in trying to solve it. Clear communication is very important to make
    this work.
  - I am also very comfortable with learning things all on my own (I
    have barely known any other way), and working in a remote,
    asynchronous setting.
  I hope to make the world better in my own small way by contributing to
  a tool that everyone uses and I like. It's more rewarding than any
  internship that my peers are doing this year. I look forward to
  learning more.


^ permalink raw reply	[relevance 5%]

* Re: [GSoC] Draft Proposal (Convert submodule to builtin)
  2021-04-08  9:11  5%         ` Chinmoy Chakraborty
@ 2021-04-10 12:03  4%           ` Christian Couder
  0 siblings, 0 replies; 200+ results
From: Christian Couder @ 2021-04-10 12:03 UTC (permalink / raw)
  To: Chinmoy Chakraborty; +Cc: git, Kaartic Sivaraam

On Thu, Apr 8, 2021 at 11:10 AM Chinmoy Chakraborty
<chinmoy12c@gmail.com> wrote:
>
> This is the V2 of the draft proposal after applying the
>
> changes suggested by Christian Couder and Kaartik Sivaraam.

Please add all the reviewers in Cc. I added Kaartic.

> ##Git Contributions##
>
> [Microproject] Replace instances of `the_repository` with ‘r’. (Learning
> the ropes)
> Pull request: https://github.com/gitgitgadget/git/pull/915
> Mailing List:
> https://lore.kernel.org/git/pull.915.git.1616701733901.gitgitgadget@gmail.com/
>
>
> [column, range-diff] downcase option description
> Pull request: https://github.com/gitgitgadget/git/pull/920
> Mailing List:
> https://lore.kernel.org/git/pull.920.git.1616913298624.gitgitgadget@gmail.com/
>
>
> [Documentation] updated documentation for git commit --date
> Pull request: https://github.com/gitgitgadget/git/pull/918
> Mailing List:
> https://lore.kernel.org/git/pull.918.git.1616926790227.gitgitgadget@gmail.com/

Adding a status to let us know if each of your contributions have been
merged to seen, next or master, or even already released (in which
version?) would be nice. You could also add a GitHub or GitLab link to
the merge commit that merged your contribution.

> ##Project Outline##
>
> A few components of git, like `git-submodule.sh`
> are in the form of shell scripts. This causes
> problems in production code in multiple platforms
> like windows. The goal of this project is to
> convert the shell script version of `git-submodule.sh`
> to portable c code. The end goal would be

s/c/C/

> to completely remove `git-submodule.sh` and rename
> `builtin/submodule--helper.c` to `builtin/submodule.c`
> so that the `git submodule` is fully implemented using C.
> =================================================
>
> ##Why is the project required?##
>
> "Issues with the portability of code"
>
> The submodule shell script uses shell commands like
> `echo`, `grep`, `test`, `printf` etc. When switching
> to non-POSIX compliant systems, one will have
> to re-implement these commands specifically for the
> system. There are also POSIX-to-Windows path conversion
> issues. To fix these issues, it was decided to convert
> these scripts into portable C code.
>
> "Large overhead in calling the command"
>
> The commands implemented in shell scripts are not builtins, so
> they call `fork()` and `exec()` multiple times, hence creating
> additional shells.

s/shells/processes/

> This adds to the overhead in using the
> commands in terms of time and memory.
>
> "No access to low-level API"
>
> The shell commands don’t have access to low level commands
> like `git hash-object`, `git cat-file` etc.

I am not sure it's correct to say that they don't have access to such
low level commands. I think it would be better to say that they don't
have direct access to the internal functions behind such low level
commands.

> As these commands
> are internally required for submodule commands to work, the shell
> script needs to spawn a separate shell to execute these commands.

s/separate shell/separate process/

> =================================================
>
> ##How have I prepared?##
>
> I have gone through all the previous works and read through their
> code to make myself accustomed to the intricacies of the code.
> I have also structured my workflow based on the observation of
> the previous discussions on those patches, and taken into
> consideration the issues faced previously.
>
> =================================================
>
> ##Previous Work##
>
> A large part of the `git submodule--helper.c` has already been

I would say that it's 'git-submodule.sh' that has been converted. 'git
submodule--helper.c' is the result of that conversion.

> converted by Stefan Beller, Prathamesh Chavan in his GSoC project
> in 2017, and Shourya Shukla in his GSoC project in 2020. This is
> the list of already ported commands.
>
> set-branch
> set-url
> summary
> status
> init
> deinit
> update
> foreach
> sync
> absorbgitdirs
> =================================================
>
> ##Work to be done##
>
> The only command that is left to be ported is `git submodule add`.
> The previous work on this by Shourya Shukla in GSoC 2020, did
> not reach a successful merge due to some issues in design and
> the patch was dropped as it had been stale for long.
> See:
> https://github.com/git/git/blob/1861aa482a38ae84f597cede48167ab43e7e50a3/whats-cooking.txt#L1158-L1169
> The first and foremost aim of the project will be to finish
> porting the `add` command. Thereafter, the end goal would be to
> completely replace the shell script (git-submodule.sh) with
> an efficient c code.

s/c/C/

> Before porting the `git submodule add` command the initial work
> would be dedicated to the implementation of small helper functions
> in the form of small patches, which would be directly used by the
> `add` command. This workflow is based on the suggestion by
> Junio C Hamano on the thread:
> https://lore.kernel.org/git/xmqqd01sugrg.fsf@gitster.c.googlers.com/.
>
> This workflow would help in the following ways:
>
> - It would help in sending patches in a small digestible format.
> - It would help the reviewers easily review those small units
>    of patches in a single sitting.
> - It would help keep small logical units of code in different clean commits.
>
> An additional test tweak would also be required in
> `t7400-submodule-basic.sh`,
> to prepend the keyword ‘fatal’ since the command dies out in case
> of absence of commits as pointed out by Kaartic Sivaraam on the thread:
> https://lore.kernel.org/git/ce151a1408291bb0991ce89459e36ee13ccdfa52.camel@gmail.com/.

Ok.

> The following helper functions would be required to be implemented -
>
> - A function to guess the path name from the repository string.
>    Example prototype: static char *guess_dir_name(const char *repo)
>    Returns the path name.
>
> - A function to assure repo is absolute or relative to parent.
>    Example prototype: static char *get_real_repo(const char *repo)
>    Returns the correct repo name.
>
> - A function for normalizing path, that is, removing multiple
>    //; leading ./; /./; /../; trailing / .
>    Example prototype: static char *normalize_path(const char *path)
>
> - A function to check if the path exists and is already a git
>    repo, else clone it.
>    Example prototype: static int add_submodule(struct add_data *info)
>    `add_data` is a struct which stores the config of the submodule.
>
> - A function to set the submodule config properly.
>    Example prototype: static void config_added_submodule(struct add_data
> *info)

How would you test these helper functions? Would they be used by any
code in 'builtin/submodule--helper.c'?

> - After implementation of all these helper methods, the main
>    `module_add()` function would be implemented using the helper
>    functions listed above as well as those helper functions which
>    are predefined.
> =================================================
>
> ##Project Timeline##
>
> "Present Day - May 17"
> I’ll utilize this time in exploring the codebase more properly and
> solving more issues, which would help me properly familiarize
> myself with the codebase. I’ll also try to structure a more
> solidified, detailed workflow and come up with a draft patch

A draft patch of what? I thought that you wanted to create many
patches, each one implementing a small step, maybe a single function
that you described above.

> based on the previous work and discussions.
>
> "May 17 - June 7 (Community bonding period)"
> - Get familiar with the community.
> - Discuss proper workflow with mentors.
> - Make changes in the timeline, if necessary.
> - Discuss the structure of the series of patches.
>
> "June 7 - June 25 (Initial coding phase)"
> - Finish implementation of the helper functions.
> - Work on a proper structure of the implementation of the
>    `submodule add` command

I am not sure what this means.

> and implement additional helper
>    functions if required.
> - Update proper documentation of the helper functions.
>
> "June 25 - July 5 (Binding the code)"
> This time would be used to code the main `submodule add`
> command using all the helper functions implemented in the
> initial phase of coding.

So how would the helper functions be useful and tested before this step?

> This includes binding all the code
> together and then completing the command through incremental
> reviews. Also, the necessary documentation would be updated
> parallelly.
>
> "July 5 - July 12 (Initiate porting of command)"
> - Discuss how to go about porting the entire submodule script.
> - Initiate porting of the `git-submodule.sh` script.
>
> "July 12 - July 16 (Phase 1 evaluation)"
>
> "July 16 - July 26 (Semester exams)"
> I will be taking my semester examinations during this
> time. As such, I’ll try to be in touch with the mentors
> and take out as much time as possible (around 20 hours a week).
>
> "July 26 - August 10 (Porting the complete script)"
> This period would be utilized in the complete conversion of
> `git-submodule.sh` into c code and combine it with

s/c code/C code/

> `submodule--helper.c` to make a single `builtin/submodule.c`.
> As I’ll be completely free from academics during this period,
> I’ll try to compensate as much time as possible for the above
> period of July 16 - July 26.

^ permalink raw reply	[relevance 4%]

* Re: [GSoC][Draft Proposal v2] Finish converting git submodule to builtin
  2021-04-03 14:08  4% [GSoC][Draft Proposal] Finish converting git submodule to builtin Atharva Raykar
@ 2021-04-08 10:19  5% ` Atharva Raykar
  2021-04-11 10:17  5%   ` [GSoC][Draft Proposal v3] " Atharva Raykar
  2021-05-14 16:00  2%   ` [GSoC][Draft Proposal v2] " Atharva Raykar
  0 siblings, 2 replies; 200+ results
From: Atharva Raykar @ 2021-04-08 10:19 UTC (permalink / raw)
  To: git; +Cc: christian.couder, shouryashukla.oo, periperidip

Here's my updated draft. Changes since v1:

- Elaborated more on example porting strategy, stating how the patches
   could be broken up.
- Made language at the end of section 6 less ambiguous.
- Updated status of microproject.
- s/git/Git in several places.

Markdown version: https://gist.github.com/tfidfwastaken/0c6ca9ef2a452f110a416351541e0f19

--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<--
                          ___________________

                           GSOC GIT PROPOSAL

                             Atharva Raykar
                          ___________________


Table of Contents
_________________

1. Personal Details
2. Background
3. Me and Git
.. 1. Current knowledge of Git
4. The Project: Finish converting `git submodule' to builtin
5. Prior work
6. General implementation strategy
7. Timeline (using the format dd/mm)
8. Beyond GSoC
9. Blogging
10. Final Remarks: A little more about me


1 Personal Details
==================

  Name : Atharva Raykar
  Major : Computer Science and Engineering
  Email : raykar.ath@gmail.com
  IRC nick : atharvaraykar on #git and #git-devel
  Address : RB 103, Purva Riviera, Marathahalli, Bangalore
  Postal Code : 560037
  Time Zone : IST (UTC+5:30)
  GitHub : github.com/tfidfwastaken


2 Background
============

  I am Atharva Raykar, currently in my third year of studying Computer
  Science and Engineering at PES University, Bangalore. I have always
  enjoyed programming since a young age, but my deep appreciation for
  good program design and creating the right abstractions came during my
  exploration of the various rabbitholes of knowledge originating from
  communities around the internet. I have personally enjoyed learning
  about Functional Programming, Database Architecture and Operating
  Systems, and my interests keep expanding as I explore more in this
  field.

  I owe my appreciation of this rich field to these communities, and I
  always wanted to give back. With that goal, I restarted the [PES Open
  Source] community in our campus, with the goal of creating spaces
  where members could share knowledge, much in the same spirit as the
  communities that kickstarted my journey in Computer Science. I learnt
  a lot about collaborating in the open, maintainership, and reviewing
  code. While I have made many small contributions to projects in the
  past, I am hoping GSoC will help me make the leap to a larger and more
  substantial contribution to one of my favourite projects that made it
  all possible in my journey with Open Source.


[PES Open Source] <https://pesos.github.io>


3 Me and Git
============

  Here are the various forms of contributions that I have made to Git:

  - [Microproject] userdiff: userdiff: add support for Scheme Status: In
    progress, patch v3 requiring a review List:
    <https://lore.kernel.org/git/20210408091442.22740-1-raykar.ath@gmail.com/>

  - [Git Education] Conducted a workshop with attendance of hundreds of
    students new to git, and increased the prevalence of of git's usage
    in my campus.
    Photos: <https://photos.app.goo.gl/T7CPk1zkHdK7mx6v7> and
    <https://photos.app.goo.gl/bzTgdHMttxDen6z9A>

  I intend to continue helping people out on the mailing list and IRC
  and tending to patches wherever possible in the meantime.


3.1 Current knowledge of Git
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  I use Git almost daily in some form, and I am fairly comfortable with
  it. I have already read and understood the chapters from the Git Book
  about submodules along with the one on objects, references, packfiles
  and the refspec.


4 The Project: Finish converting `git submodule' to builtin
===========================================================

  Git has historically had many components implemented in the form of
  shell scripts. This was less than ideal for several reasons:
  - Portability: Non-POSIX systems like Windows don't play nice with
    shell script commands like grep, cd and printf, to name a few, and
    these commands have to be reimplemented for the system. There are
    also POSIX to Windows path conversion issues.
  - No direct access to plumbing: Shell commands do not have direct
    access to the low level Git API, and a separate shell is spawned to
    just to carry out their operations.
  - Performance: Shell scripts tend to create a lot of child processes
    which slows down the functioning of these commands, especially with
    large repositories.
  Over the years, many GSoC students have converted the shell versions
  of these commands to C. Git `submodule' is the last of these to be
  converted.


5 Prior work
============

  I will be taking advantage of the knowledge that was gained in the
  process of the converting the previous scripts and avoiding all the
  gotchas that may be present in the process. There may be a bunch of
  useful helper functions in the previous patches that can be reused as
  well (more investigation needed to determine what exactly is
  reusable).

  Currently the only other commands left to be completed for `submodule'
  are `add' and `update'. Work for `add' has already been started by a
  previous GSoCer, Shourya Shukla, and needs to picked up from there.
  `update' has had some of its functionality moved over to
  `submodule--helper.c' where Stefan Beller added the helper functions
  `update-clone', `update-module-mode', `remote-branch' and more.

  References:
  <https://github.com/gitgitgadget/git/issues/541#issuecomment-769245064>
  <https://github.com/git/git/commit/4d6d6ef1fc>
  <https://github.com/git/git/commit/48308681b072a1d32e1361c255347324a8ad151e>
  <https://github.com/git/git/commit/ee69b2a90c5031bffb3341c5e50653a6ecca89ac>
  <https://github.com/git/git/commit/92bbe7ccf1fedac825f2c6ab4c8de91dc5370fd2>

  I'll have these as my references when I am working on the project:
  His blog about his progress:
  <https://shouryashukla.blogspot.com/2020/08/the-final-report.html>
  (more has been implemented since)
  Shourya's latest patch for `submodule add':
  <https://lore.kernel.org/git/20201007074538.25891-1-shouryashukla.oo@gmail.com/>

  For the most part, the implementation looks fairly complete, but there
  seems to be a segfault occurring, along with a few changes suggested
  by the reviewers. It will be helpful to contact Shourya to fully
  understand what needs to be done.

  Prathamesh's previous conversion work:
  <https://lore.kernel.org/git/20170724203454.13947-1-pc44800@gmail.com/#t>

  The ultimate goal would be to get rid of `git-submodules.sh'
  altogether -- which will complete the porting efforts of `submodule'
  to C.


6 General implementation strategy
=================================

  The way to port the shell to C code for `submodule' will largely
  remain the same. There already exists the builtin
  `submodule--helper.c' which contains most of the previous commands'
  ports. All that the shell script for `git-submodule.sh' is doing for
  the previously completed ports is parsing the flags and then calling
  the helper, which does all the business logic.

  So I will be moving out all the business logic that the shell script
  is performing to `submodule--helper.c'. Any reusable functionality
  that is introduced during the port will be added to `submodule.c' in
  the top level.

      For example: The general strategy for converting `cmd_update()' would
      be to have a call to `submodule--helper' in the shell script to a
      function which would resemble something like `module_update()'. This
      would perform the work being done by the shell script past the flags
      being parsed and make the necessary call to `update_clone()', which
      returns information about the cloned modules. For each cloned module,
      it will find out the update mode through `module_update_mode()', and
      run the appropriate operation according to that mode (like a rebase,
      if that was the update mode).

      One possible way this work can be broken up into multiple patches, is
      by moving over the shell code into C in a bottom-up manner.
      For example: The shell part which retrieves the latest revision in the
      remote (if --remote is specified) can be wrapped into a command of
      `submodule--helper.c'. Then we can move the part where we run the
      update method (ie the `case' on line 611 onwards) into a C function.
      Eventually, the shell part will just look like a bunch of invocations
      to `submodule--helper', at which point, the whole thing can be
      encapsulated in a single command called `git submodule--helper update'
      (Bonus: Move the whole functionality to C, including the parsing of
      flags, to work towards getting rid of `git-submodule.sh'). I believe
      this is a fairly non-destructive and incremental way to work, and the
      porting efforts by Stefan seem to follow this same kind of philosophy.
      I will most likely end up tuning the size of these increments when I
      get around to planning in my first phase of the project.

  After this process, I will be adding the `add' and `update' command to
  the commands array in `submodule--helper.c'. And since these two
  functions are the last bit of functionality left to convert in
  submodules, an extended goal can be to get rid of the shell script
  altogether, and make the helper into the actual builtin [1].

  [1]
  <https://lore.kernel.org/git/nycvar.QRO.7.76.6.2011191327320.56@tvgsbejvaqbjf.bet/>


7 Timeline (using the format dd/mm)
===================================

  Periods of limited availability (read: hectic chaos):
  - From 13/04 to 20/04 I will be having project evaluations and lab
    assessments for five of my courses.
  - From 20/04 to 01/05 I have my in-semester exams.
  - For a period of two weeks in the range of 08/05 to 29/05 I will be
    having my end-semester exams.
  My commitment: I will still have time during my finals to help people
  out on the mailing list, get acquainted with the community and its
  processes, and even review patches if I can. This is because we get
  holidays between each exam, and my grades are good enough to that I
  can prioritise Git over my studies ;-)

  And on the safe side, I will still engage with the community from now
  till 07/06 so that the community bonding period is not compromised in
  any way.

  Periods of abundant availability: After 29/05 all the way to the first
  week of August, I will be having my summer break, so I can dedicate
  myself to Git full-time :-)

  I would have also finished all my core courses, so even after that, I
  will have enough of time to give back to Git past my GSoC period.

  Phase 1: 07/06 to 14/06 -- Investigate and devise a strategy to port
  the submodule functions
  - This phase will be more diagrams in my notebook than code in my
    editor -- I will go through all the methods used to port the other
    submodule functions and see how to do the same for what is left.
  - I will find the C equivalents of all the shell invocations in
    `git-submodule.sh', and see what invocations have /no/ equivalent
    and need to be created as helpers in C (Eg: What is the equivalent
    to the `ensure-core-worktree' invocation in C?). For all the helpers
    and new functionality that I do introduce, I will need to create the
    testing strategy for the same.
  - I will go through all the work done by Shourya in his patch, and try
    to understand it properly. I will also see the mistakes that were
    caught in all the reviews for previous submodule conversion patches
    and try to learn from them before I jump to the code.
  - Deliverable: I will create a checklist for all the work that needs
    to be done with as much detail as I can with the help of inputs from
    my mentor and all the knowledge I have gained in the process.

  Phase 2: 14/06 to 28/06 -- Convert `add' to builtin in C
  - I will work on completing `git submodule add'. One strategy would be
    to either reimplement the whole thing using what was learnt in
    Shourya's attempt, but it is probably wiser to just take his patch
    and modify it. I would know what to do by the time I reach this
    phase.
  - I will also add tests for this functionality. I will also document
    my changes when required. These would be unit tests for the helpers
    introduced, and integration of `add' with the other commands.
  - Deliverable: Completely port `add' to C!

  Phase 3: 28/06 to 16/08 -- Convert `update' to builtin
  - Some work has already been done by Stephan Beller that moves the
    functionality of `update' to `submodule--helper.c':
    <https://github.com/git/git/commit/48308681b072a1d32e1361c255347324a8ad151e>,
    but a lot of the business logic of going into the submodule and
    checking out or merging or rebasing needs to still be converted.
    Plenty to do here.
  - As with `add', all of the appropriate tests need to be written and
    the changes documented. As I have learnt from the Pro Git Book,
    there are a lot of subtleties with how update does its work that I
    need to watch out for.
  - Deliverable: Completely port `update' to C!

  Bonus Phase: If I am ahead of time -- Remove the need for a
  `submodule--helper', and make it a proper C builtin.
  - Once all the submodule functionality is ported, the shell script is
    not really doing much more than parsing the arguments and passing it
    to the helper. We won't need this anymore if it is implemented.


8 Beyond GSoC
=============

  I love the process of working as a community more than anything else,
  and I already felt very welcomed by the Git community the moment I
  started sending in my microproject patch series. Whether I am selected
  or not, I will continue giving back to Git wherever I can. Since my
  final year is light on coursework, I will be able to mentor people and
  help expand the Git developer community through all the ways I can (be
  it code review, helping people find the right resources or evangelism
  of Git).


9 Blogging
==========

  I will be blogging about my progress on a weekly basis and either post
  it on my website at <https://atharvaraykar.me> (probably will tuck it
  away in a /gsoc path). Technical blogging is not particularly new to
  me, and I hope my posts can help future contributors of Git.


10 Final Remarks: A little more about me
========================================

  These are some of my core values that I believe will be important to
  pull off this project and make the most of my time in GSoC:
  - Hard problems don't frustrate me, rather they excite me. Bugs make
    my brain perk up. I love the process of learning.
  - I am pro-transparency. If I am having some trouble, I will be open
    about it. I don't hesitate to ask questions and dig deep if I need
    to.
  - At the same time, when I ask a question, I only do so after I have
    struggled with the problem for enough time and done my due diligence
    in trying to solve it. Clear communication is very important to make
    this work.
  - I am also very comfortable with learning things all on my own (I
    have barely known any other way), and working in a remote,
    asynchronous setting.
  I hope to make the world better in my own small way by contributing to
  a tool that everyone uses and I like. It's more rewarding than any
  internship that my peers are doing this year. I look forward to
  learning more.


^ permalink raw reply	[relevance 5%]

* Re: [GSoC] Draft Proposal (Convert submodule to builtin)
  2021-04-05 14:44  4%       ` Christian Couder
@ 2021-04-08  9:11  5%         ` Chinmoy Chakraborty
  2021-04-10 12:03  4%           ` Christian Couder
  0 siblings, 1 reply; 200+ results
From: Chinmoy Chakraborty @ 2021-04-08  9:11 UTC (permalink / raw)
  To: Christian Couder, git

This is the V2 of the draft proposal after applying the

changes suggested by Christian Couder and Kaartik Sivaraam.

Thank you for you reviews :).

==================================================

Convert submodule to builtin
March 2021

==================================================
##Personal Information##


Name - Chinmoy Chakraborty
E-mail - chinmoy12c@gmail.com
Github - https://github.com/chinmoy12c
Linkedin - https://www.linkedin.com/in/chinmoy12c/
Major - Information Technology
Time Zone - IST (UTC+05:30)
=================================================

##Work Environment##

I am fluent in C, Java, Python, and Shell script. I use Git
as my VCS, Visual Studio Code as my primary code editor, and
Kali Linux as my primary OS.
=================================================

##Git Contributions##

[Microproject] Replace instances of `the_repository` with ‘r’. (Learning 
the ropes)
Pull request: https://github.com/gitgitgadget/git/pull/915
Mailing List: 
https://lore.kernel.org/git/pull.915.git.1616701733901.gitgitgadget@gmail.com/


[column, range-diff] downcase option description
Pull request: https://github.com/gitgitgadget/git/pull/920
Mailing List: 
https://lore.kernel.org/git/pull.920.git.1616913298624.gitgitgadget@gmail.com/


[Documentation] updated documentation for git commit --date
Pull request: https://github.com/gitgitgadget/git/pull/918
Mailing List: 
https://lore.kernel.org/git/pull.918.git.1616926790227.gitgitgadget@gmail.com/
=================================================

##Project Outline##

A few components of git, like `git-submodule.sh`
are in the form of shell scripts. This causes
problems in production code in multiple platforms
like windows. The goal of this project is to
convert the shell script version of `git-submodule.sh`
to portable c code. The end goal would be
to completely remove `git-submodule.sh` and rename
`builtin/submodule--helper.c` to `builtin/submodule.c`
so that the `git submodule` is fully implemented using C.
=================================================

##Why is the project required?##

"Issues with the portability of code"

The submodule shell script uses shell commands like
`echo`, `grep`, `test`, `printf` etc. When switching
to non-POSIX compliant systems, one will have
to re-implement these commands specifically for the
system. There are also POSIX-to-Windows path conversion
issues. To fix these issues, it was decided to convert
these scripts into portable C code.

"Large overhead in calling the command"

The commands implemented in shell scripts are not builtins, so
they call `fork()` and `exec()` multiple times, hence creating
additional shells. This adds to the overhead in using the
commands in terms of time and memory.

"No access to low-level API"

The shell commands don’t have access to low level commands
like `git hash-object`, `git cat-file` etc. As these commands
are internally required for submodule commands to work, the shell
script needs to spawn a separate shell to execute these commands.
=================================================

##How have I prepared?##

I have gone through all the previous works and read through their
code to make myself accustomed to the intricacies of the code.
I have also structured my workflow based on the observation of
the previous discussions on those patches, and taken into
consideration the issues faced previously.

=================================================

##Previous Work##

A large part of the `git submodule--helper.c` has already been
converted by Stefan Beller​, Prathamesh Chavan​ in his GSoC project
in 2017, and Shourya Shukla in his GSoC project in 2020. This is
the list of already ported commands.

set-branch
set-url
summary
status
init
deinit
update
foreach
sync
absorbgitdirs
=================================================

##Work to be done##

The only command that is left to be ported is `git submodule add`.
The previous work on this by Shourya Shukla in GSoC 2020, did
not reach a successful merge due to some issues in design and
the patch was dropped as it had been stale for long.
See: 
https://github.com/git/git/blob/1861aa482a38ae84f597cede48167ab43e7e50a3/whats-cooking.txt#L1158-L1169
The first and foremost aim of the project will be to finish
porting the `add` command. Thereafter, the end goal would be to
completely replace the shell script (git-submodule.sh) with
an efficient c code.

Before porting the `git submodule add` command the initial work
would be dedicated to the implementation of small helper functions
in the form of small patches, which would be directly used by the
`add` command. This workflow is based on the suggestion by
Junio C Hamano on the thread:
https://lore.kernel.org/git/xmqqd01sugrg.fsf@gitster.c.googlers.com/.

This workflow would help in the following ways:

- It would help in sending patches in a small digestible format.
- It would help the reviewers easily review those small units
   of patches in a single sitting.
- It would help keep small logical units of code in different clean commits.

An additional test tweak would also be required in 
`t7400-submodule-basic.sh`,
to prepend the keyword ‘fatal’ since the command dies out in case
of absence of commits as pointed out by Kaartic Sivaraam on the thread:
https://lore.kernel.org/git/ce151a1408291bb0991ce89459e36ee13ccdfa52.camel@gmail.com/.


The following helper functions would be required to be implemented -

- A function to guess the path name from the repository string.
   Example prototype: static char *guess_dir_name(const char *repo)
   Returns the path name.

- A function to assure repo is absolute or relative to parent.
   Example prototype: static char *get_real_repo(const char *repo)
   Returns the correct repo name.

- A function for normalizing path, that is, removing multiple
   //; leading ./; /./; /../; trailing / .
   Example prototype: static char *normalize_path(const char *path)

- A function to check if the path exists and is already a git
   repo, else clone it.
   Example prototype: static int add_submodule(struct add_data *info)
   `add_data` is a struct which stores the config of the submodule.

- A function to set the submodule config properly.
   Example prototype: static void config_added_submodule(struct add_data 
*info)

- After implementation of all these helper methods, the main
   `module_add()` function would be implemented using the helper
   functions listed above as well as those helper functions which
   are predefined.
=================================================

##Project Timeline##

"Present Day - May 17"
I’ll utilize this time in exploring the codebase more properly and
solving more issues, which would help me properly familiarize
myself with the codebase. I’ll also try to structure a more
solidified, detailed workflow and come up with a draft patch
based on the previous work and discussions.

"May 17 - June 7 (Community bonding period)"
- Get familiar with the community.
- Discuss proper workflow with mentors.
- Make changes in the timeline, if necessary.
- Discuss the structure of the series of patches.

"June 7 - June 25 (Initial coding phase)"
- Finish implementation of the helper functions.
- Work on a proper structure of the implementation of the
   `submodule add` command and implement additional helper
   functions if required.
- Update proper documentation of the helper functions.

"June 25 - July 5 (Binding the code)"
This time would be used to code the main `submodule add`
command using all the helper functions implemented in the
initial phase of coding. This includes binding all the code
together and then completing the command through incremental
reviews. Also, the necessary documentation would be updated
parallelly.

"July 5 - July 12 (Initiate porting of command)"
- Discuss how to go about porting the entire submodule script.
- Initiate porting of the `git-submodule.sh` script.

"July 12 - July 16 (Phase 1 evaluation)"

"July 16 - July 26 (Semester exams)"
I will be taking my semester examinations during this
time. As such, I’ll try to be in touch with the mentors
and take out as much time as possible (around 20 hours a week).

"July 26 - August 10 (Porting the complete script)"
This period would be utilized in the complete conversion of
`git-submodule.sh` into c code and combine it with
`submodule--helper.c` to make a single `builtin/submodule.c`.
As I’ll be completely free from academics during this period,
I’ll try to compensate as much time as possible for the above
period of July 16 - July 26.

"August 10 - August 16 (Final review and evaluation)"
- Final review by the mentors.
- Apply necessary changes and touch-ups.
- Updating documentation, if any left.

"August 16 - August 23 (Submission of final report)"

Additionally: There are places in the original shell script
and c code tagged as `NEEDSWORK`. My aim would be to resolve
these issues within the GSoC period if time permits.
=================================================

##Post GSoC##

After the GSoC period, I plan to continue my contributions
for git and look for other issues to work on. I’d look into
the conversion of other commands which are pending conversion,
as well as work on the `NEEDSWORK` part of the code (If I’m
unable to finish it within the GSoC period itself). I plan on
mentoring new contributors to git and help the contributors
by doing code reviews and solving their doubts and helping
them out.

Regards,
Chinmoy Chakraborty.



^ permalink raw reply	[relevance 5%]

* Re: [GSoC] Draft Proposal (Convert submodule to builtin)
  2021-04-03 14:14  5%     ` Chinmoy Chakraborty
@ 2021-04-05 14:44  4%       ` Christian Couder
  2021-04-08  9:11  5%         ` Chinmoy Chakraborty
  0 siblings, 1 reply; 200+ results
From: Christian Couder @ 2021-04-05 14:44 UTC (permalink / raw)
  To: Chinmoy Chakraborty; +Cc: git

On Sat, Apr 3, 2021 at 4:13 PM Chinmoy Chakraborty <chinmoy12c@gmail.com> wrote:
>
> Here is a textual format of the draft proposal.
>
>
> Convert submodule to builtin
> March 2021
>
> ==================================================
> ##Personal Information##
>
>
> Name - Chinmoy Chakraborty
> E-mail - chinmoy12c@gmail.com
> Github - https://github.com/chinmoy12c
> Linkedin - https://www.linkedin.com/in/chinmoy12c/
> Major - Information Technology
> Time Zone - IST (UTC+05:30)
> =================================================
>
> ##Work Environment##
>
> I am fluent in C, Java, Python, and Shell script. I use Git as my VCS,
> Visual Studio Code
> as my primary code editor, and Kali Linux as my primary OS.
> =================================================
>
> ##Git Contributions##
>
> [Microproject] Replace instances of `the_repository` with ‘r’. (Learning
> the ropes)
> Pull request: https://github.com/gitgitgadget/git/pull/915
> Mailing List:
> https://lore.kernel.org/git/pull.915.git.1616701733901.gitgitgadget@gmail.com/
>
>
> [column, range-diff] downcase option description
> Pull request: https://github.com/gitgitgadget/git/pull/920
> Mailing List:
> https://lore.kernel.org/git/pull.920.git.1616913298624.gitgitgadget@gmail.com/
>
>
> [Documentation] updated documentation for git commit --date
> Pull request: https://github.com/gitgitgadget/git/pull/918
> Mailing List:
> https://lore.kernel.org/git/pull.918.git.1616926790227.gitgitgadget@gmail.com/
> =================================================

Ok.

> ##Project Outline##
>
> A few components of git, like `git-submodule.sh`
> are in the form of shell scripts. This causes
> problems in production code in multiple platforms
> like windows. The goal of this project is to
> convert the shell script version of `git-submodule.sh`
> to portable c code. The end goal would be

s/c/C/

> to completely remove `git-submodule.sh` and rename
> `builtin/submodule--helper.c` to `builtin/submodule.c`.

You could add something like "so that the `git submodule` is fully
implemented using C".

> =================================================
>
> ##Why is the project required?##
>
> "Issues with the portability of code"
>
> The submodule shell script uses shell commands like
> `echo`, `grep`, `test`, `printf` etc. When switching
> to non-POSIX compliant systems, one will have
> to re-implement these commands specifically for the
> system. There are also POSIX-to-Windows path conversion
> issues. To fix these issues, it was decided to convert
> these scripts into portable C code.
>
> "Large overhead in calling the command"
>
> The commands implemented in shell scripts are not builtins, so
> they call `fork()` and `exec()` multiple times, hence creating
> additional shells. This adds to the overhead in using the
> commands in terms of time and memory.
>
> "No access to low-level API"
>
> The shell commands don’t have access to low level commands
> like `git hash-object`, `git cat-file` etc. As these commands
> are internally required for submodule commands to work, the shell
> script needs to spawn a separate shell to execute these commands.
> =================================================

Ok.

> ##How have I prepared?##
>
> I have gone through all the previous works and read through their
> code to make myself accustomed to the intricacies of the code.
> I have also structured my workflow based on the observation of
> the previous discussions on those patches, and taken into
> consideration the issues faced previously.
>
> =================================================
>
> ##Previous Work##
>
> A large part of the `git submodule--helper.c` has already been
> converted by Stefan Beller, Prathamesh Chavan in his GSoC project
> in 2017, and Shourya Shukla in his GSoC project in 2020. This is
> the list of already ported commands.
>
> set-branch
> set-url
> summary
> status
> init
> deinit
> update
> foreach
> sync
> absorbgitdirs
> =================================================
>
> ##Work to be done##
>
> The only command that is left to be ported is `git submodule add`.
> The previous work on this by Shourya Shukla in GSoC 2020, did
> not reach a successful merge due to some issues in design and
> was kicked out because it has been stale for so long.

Maybe you could explain a bit what "kicked out" means, or replace it
with something more explicit, for people who don't know well how Git
development works.

> The first
> and foremost aim of the project will be to finish porting this
> command.

You mean the "add" sub-command, or the full "submodule" command?

> Thereafter, the end goal would be to completely replace
> the shell script (git-submodule.sh) with an efficient c code.

s/c/C/

> Before porting the `git submodule add` command the initial work
> would be dedicated to the implementation of small helper functions
> in the form of small patches, which would be directly used by the
> `add` command. This workflow is based on the suggestion by
> Junio C Hamano on the thread:
> https://lore.kernel.org/git/xmqqd01sugrg.fsf@gitster.c.googlers.com/.
>
> This workflow would help in the following ways:
>
> - It would help in sending patches in a small digestible format.
> - It would help the reviewers easily review those small units
>    of patches in a single sitting.
> - It would help keep small logical units of code in different clean commits.

Yeah, nice!

How does this compare with Shourya's work? Will this avoid the design
issues in Shourya's work?

> An additional test tweak would also be required in
> `t7400-submodule-basic.sh`,
> to prepend the keyword ‘fatal’ since the command dies out in case
> of absence of commits.
>
>
> The following helper functions would be required to be implemented -
>
> - A function to guess the directory name from the repository string.
> - A function for normalizing path, that is, removing multiple
>    //; leading ./; /./; /../; trailing / .
>
> - A function to check for tracked directories properly as pointed
>    out by Kaartic Sivaraam on the thread:
> https://lore.kernel.org/git/ce151a1408291bb0991ce89459e36ee13ccdfa52.camel@gmail.com/.
>
> - A function to check if the path exists and is already a git
>    repo, else clone it.
>
> - A function to set the submodule config properly.

Nice! Maybe you could give an example and tell:
- how you would name one of the above function,
- what would be its arguments,
- perhaps how you would test it
...

> - After implementation of all these helper methods, the main
>    `module_add()` function would be implemented using the helper
>    functions listed above as well as those helper functions which
>    are predefined.
> =================================================

Ok, I will review the other parts later.

Thanks!

^ permalink raw reply	[relevance 4%]

* Re: [GSoC] Draft Proposal (Convert submodule to builtin)
  @ 2021-04-03 14:14  5%     ` Chinmoy Chakraborty
  2021-04-05 14:44  4%       ` Christian Couder
  0 siblings, 1 reply; 200+ results
From: Chinmoy Chakraborty @ 2021-04-03 14:14 UTC (permalink / raw)
  To: Christian Couder, git

Here is a textual format of the draft proposal.


Convert submodule to builtin
March 2021

==================================================
##Personal Information##


Name - Chinmoy Chakraborty
E-mail - chinmoy12c@gmail.com
Github - https://github.com/chinmoy12c
Linkedin - https://www.linkedin.com/in/chinmoy12c/
Major - Information Technology
Time Zone - IST (UTC+05:30)
=================================================

##Work Environment##

I am fluent in C, Java, Python, and Shell script. I use Git as my VCS, 
Visual Studio Code
as my primary code editor, and Kali Linux as my primary OS.
=================================================

##Git Contributions##

[Microproject] Replace instances of `the_repository` with ‘r’. (Learning 
the ropes)
Pull request: https://github.com/gitgitgadget/git/pull/915
Mailing List: 
https://lore.kernel.org/git/pull.915.git.1616701733901.gitgitgadget@gmail.com/


[column, range-diff] downcase option description
Pull request: https://github.com/gitgitgadget/git/pull/920
Mailing List: 
https://lore.kernel.org/git/pull.920.git.1616913298624.gitgitgadget@gmail.com/


[Documentation] updated documentation for git commit --date
Pull request: https://github.com/gitgitgadget/git/pull/918
Mailing List: 
https://lore.kernel.org/git/pull.918.git.1616926790227.gitgitgadget@gmail.com/
=================================================

##Project Outline##

A few components of git, like `git-submodule.sh`
are in the form of shell scripts. This causes
problems in production code in multiple platforms
like windows. The goal of this project is to
convert the shell script version of `git-submodule.sh`
to portable c code. The end goal would be
to completely remove `git-submodule.sh` and rename
`builtin/submodule--helper.c` to `builtin/submodule.c`.
=================================================

##Why is the project required?##

"Issues with the portability of code"

The submodule shell script uses shell commands like
`echo`, `grep`, `test`, `printf` etc. When switching
to non-POSIX compliant systems, one will have
to re-implement these commands specifically for the
system. There are also POSIX-to-Windows path conversion
issues. To fix these issues, it was decided to convert
these scripts into portable C code.

"Large overhead in calling the command"

The commands implemented in shell scripts are not builtins, so
they call `fork()` and `exec()` multiple times, hence creating
additional shells. This adds to the overhead in using the
commands in terms of time and memory.

"No access to low-level API"

The shell commands don’t have access to low level commands
like `git hash-object`, `git cat-file` etc. As these commands
are internally required for submodule commands to work, the shell
script needs to spawn a separate shell to execute these commands.
=================================================

##How have I prepared?##

I have gone through all the previous works and read through their
code to make myself accustomed to the intricacies of the code.
I have also structured my workflow based on the observation of
the previous discussions on those patches, and taken into
consideration the issues faced previously.

=================================================

##Previous Work##

A large part of the `git submodule--helper.c` has already been
converted by Stefan Beller​, Prathamesh Chavan​ in his GSoC project
in 2017, and Shourya Shukla in his GSoC project in 2020. This is
the list of already ported commands.

set-branch
set-url
summary
status
init
deinit
update
foreach
sync
absorbgitdirs
=================================================

##Work to be done##

The only command that is left to be ported is `git submodule add`.
The previous work on this by Shourya Shukla in GSoC 2020, did
not reach a successful merge due to some issues in design and
was kicked out because it has been stale for so long. The first
and foremost aim of the project will be to finish porting this
command. Thereafter, the end goal would be to completely replace
the shell script (git-submodule.sh) with an efficient c code.

Before porting the `git submodule add` command the initial work
would be dedicated to the implementation of small helper functions
in the form of small patches, which would be directly used by the
`add` command. This workflow is based on the suggestion by
Junio C Hamano on the thread:
https://lore.kernel.org/git/xmqqd01sugrg.fsf@gitster.c.googlers.com/.

This workflow would help in the following ways:

- It would help in sending patches in a small digestible format.
- It would help the reviewers easily review those small units
   of patches in a single sitting.
- It would help keep small logical units of code in different clean commits.

An additional test tweak would also be required in 
`t7400-submodule-basic.sh`,
to prepend the keyword ‘fatal’ since the command dies out in case
of absence of commits.


The following helper functions would be required to be implemented -

- A function to guess the directory name from the repository string.
- A function for normalizing path, that is, removing multiple
   //; leading ./; /./; /../; trailing / .

- A function to check for tracked directories properly as pointed
   out by Kaartic Sivaraam on the thread:
https://lore.kernel.org/git/ce151a1408291bb0991ce89459e36ee13ccdfa52.camel@gmail.com/.

- A function to check if the path exists and is already a git
   repo, else clone it.

- A function to set the submodule config properly.

- After implementation of all these helper methods, the main
   `module_add()` function would be implemented using the helper
   functions listed above as well as those helper functions which
   are predefined.
=================================================

##Project Timeline##

"Present Day - May 17"
I’ll utilize this time in exploring the codebase more properly and
solving more issues, which would help me properly familiarize
myself with the codebase. I’ll also try to structure a more
solidified, detailed workflow and come up with a draft patch
based on the previous work and discussions.

"May 17 - June 7 (Community bonding period)"
- Get familiar with the community.
- Discuss proper workflow with mentors.
- Make changes in the timeline, if necessary.
- Discuss the structure of the series of patches.

"June 7 - June 25 (Initial coding phase)"
- Finish implementation of the helper functions.
- Work on a proper structure of the implementation of the
   `submodule add` command and implement additional helper
   functions if required.
- Update proper documentation of the helper functions.

"June 25 - June 5 (Binding the code)"
This time would be used to code the main `submodule add`
command using all the helper functions implemented in the
initial phase of coding. This includes binding all the code
together and then completing the command through incremental
reviews. Also, the necessary documentation would be updated
parallelly.

"July 5 - July 12 (Initiate porting of command)"
This time would be utilized in initiating the step-by-step
conversion of the `git submodule add` command.

"July 12 - July 16 (Phase 1 evaluation)"

"July 16 - July 26 (Semester exams)"
I will be taking my semester examinations during this
time. As such, I’ll try to be in touch with the mentors
and take out as much time as possible (around 20 hours a week).

"July 26 - August 10 (Porting the complete script)"
This period would be utilized in the complete conversion of
`git-submodule.sh` into c code and combine it with
`submodule--helper.c` to make a single `builtin/submodule.c`.
As I’ll be completely free from academics during this period,
I’ll try to compensate as much time as possible for the above
period of July 16 - July 26.

"August 10 - August 16 (Final review and evaluation)"
- Final review by the mentors.
- Apply necessary changes and touch-ups.
- Updating documentation, if any left.

"August 16 - August 23 (Submission of final report)"

Additionally: There are places in the original shell script
and c code tagged as `NEEDSWORK`. My aim would be to resolve
these issues within the GSoC period if time permits.
=================================================

##Post GSoC##

After the GSoC period, I plan to continue my contributions
for git and look for other issues to work on. I’d look into
the conversion of other commands which are pending conversion,
as well as work on the `NEEDSWORK` part of the code (If I’m
unable to finish it within the GSoC period itself). I plan on
mentoring new contributors to git and help the contributors
by doing code reviews and solving their doubts and helping
them out.

Regards,
Chinmoy Chakraborty.

=================================================



Thanks,

Chinmoy


^ permalink raw reply	[relevance 5%]

* [GSoC][Draft Proposal] Finish converting git submodule to builtin
@ 2021-04-03 14:08  4% Atharva Raykar
  2021-04-08 10:19  5% ` [GSoC][Draft Proposal v2] " Atharva Raykar
  0 siblings, 1 reply; 200+ results
From: Atharva Raykar @ 2021-04-03 14:08 UTC (permalink / raw)
  To: git; +Cc: christian.couder, shouryashukla.oo, periperidip

Hi all,

Below is my draft of my GSoC proposal. I have noticed that Chinmoy has already
submitted a proposal for the same idea before me, so would that be considered
"taken"? (I don't think I can submit another proposal for the other idea either,
because someone has already sent one for that as well)

Since I have already put my effort into this for a while, I thought I might as
well send it, but I'll accept whatever the mentors say about the eligibility of
this proposal.

Here is a prettier markdown version:
https://gist.github.com/tfidfwastaken/0c6ca9ef2a452f110a416351541e0f19


--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<--

                          ___________________

                           GSOC GIT PROPOSAL

                             Atharva Raykar
                          ___________________


Table of Contents
_________________

1. Personal Details
2. Background
3. Me and Git
.. 1. Current knowledge of git
4. The Project: Finish converting `git submodule' to builtin
5. Prior work
6. General implementation strategy
7. Timeline (using the format dd/mm)
8. Beyond GSoC
9. Blogging
10. Final Remarks: A little more about me


1 Personal Details
==================

  Name        : Atharva Raykar
  Major       : Computer Science and Engineering
  Email       : raykar.ath@gmail.com
  IRC nick    : atharvaraykar on #git and #git-devel
  Address     : RB 103, Purva Riviera, Marathahalli, Bangalore
  Postal Code : 560037
  Time Zone   : IST (UTC+5:30)
  GitHub      : http://github.com/tfidfwastaken


2 Background
============

  I am Atharva Raykar, currently in my third year of studying Computer
  Science and Engineering at PES University, Bangalore. I have always
  enjoyed programming since a young age, but my deep appreciation for
  good program design and creating the right abstractions came during my
  exploration of the various rabbitholes of knowledge originating from
  communities around the internet. I have personally enjoyed learning
  about Functional Programming, Database Architecture and Operating
  Systems, and my interests keep expanding as I explore more in this
  field.

  I owe my appreciation of this rich field to these communities, and I
  always wanted to give back. With that goal, I restarted the [PES Open
  Source] community in our campus, with the goal of creating spaces
  where members could share knowledge, much in the same spirit as the
  communities that kickstarted my journey in Computer Science. I learnt
  a lot about collaborating in the open, maintainership, and reviewing
  code. While I have made many small contributions to projects in the
  past, I am hoping GSoC will help me make the leap to a larger and more
  substantial contribution to one of my favourite projects that made it
  all possible in my journey with Open Source.


[PES Open Source] <https://pesos.github.io>


3 Me and Git
============

  Here are the various forms of contributions that I have made to Git:

  - [Microproject] userdiff: userdiff: add support for Scheme Status: In
    progress, patch v2 pending List:
    <https://public-inbox.org/git/20210327173938.59391-1-raykar.ath@gmail.com/>

  - [Git Education] Conducted a workshop with attendance of hundreds of
    students new to git, and increased the prevalence of of git's usage
    in my campus.
    Photos: <https://photos.app.goo.gl/T7CPk1zkHdK7mx6v7> and
    <https://photos.app.goo.gl/bzTgdHMttxDen6z9A>

  I intend to continue helping people out on the mailing list and IRC
  and tending to patches wherever possible in the meantime.


3.1 Current knowledge of git
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  I use git almost daily in some form, and I am fairly comfortable with
  it. I have already read and understood the chapters from the Git
  Book about submodules along with the one on objects, references,
  packfiles and the refspec.


4 The Project: Finish converting `git submodule' to builtin
===========================================================

  Git has historically had many components implemented in the form of
  shell scripts. This was less than ideal for several reasons:
  - Portability: Non-POSIX systems like Windows don't play nice with
    shell script commands like grep, cd and printf, to name a few, and
    these commands have to be reimplemented for the system. There are
    also POSIX to Windows path conversion issues.
  - No direct access to plumbing: Shell commands do not have direct
    access to the low level git API, and a separate shell is spawned to
    just to carry out their operations.
  - Performance: Shell scripts tend to create a lot of child processes
    which slows down the functioning of these commands, especially with
    large repositories.
  Over the years, many GSoC students have converted the shell versions
  of these commands to C. Git `submodule' is the last of these to be
  converted.


5 Prior work
============

  I will be taking advantage of the knowledge that was gained in the
  process of the converting the previous scripts and avoiding all the
  gotchas that may be present in the process. There may be a bunch of
  useful helper functions in the previous patches that can be reused as
  well (more investigation needed to determine what exactly is
  reusable).

  Currently the only other commands left to be completed for `submodule'
  are `add' and `update'. Work for `add' has already been started by a
  previous GSoCer, Shourya Shukla, and needs to picked up from there.

  Reference:
  <https://github.com/gitgitgadget/git/issues/541#issuecomment-769245064>

  I'll have these as my references when I am working on the project:
  His blog about his progress:
  <https://shouryashukla.blogspot.com/2020/08/the-final-report.html>
  (more has been implemented since)
  Shourya's latest patch for `submodule add':
  <https://lore.kernel.org/git/20201007074538.25891-1-shouryashukla.oo@gmail.com/>

  For the most part, the implementation looks fairly complete, but there
  seems to be a segfault occurring, along with a few changes suggested
  by the reviewers. It will be helpful to contact Shourya to fully
  understand what needs to be done.

  Prathamesh's previous conversion work:
  <https://lore.kernel.org/git/20170724203454.13947-1-pc44800@gmail.com/#t>


6 General implementation strategy
=================================

  The way to port the shell to C code for `submodule' will largely
  remain the same. There already exists the builtin
  `submodule--helper.c' which contains most of the previous commands'
  ports. All that the shell script for `git-submodule.sh' is doing for
  the previously completed ports is parsing the flags and then calling
  the helper, which does all the business logic.

  So I will be moving out all the business logic that the shell script
  is performing to `submodule--helper.c'. Any reusable functionality
  that is introduced during the port will be added to `submodule.c' in
  the top level.

  For example: The general strategy for converting `cmd_update()' would
  be to have a call to `submodule--helper' in the shell script to a
  function which would resemble something like `module_update()' which
  would perform the work being done by the shell script past the flags
  being parsed and make the necessary calls to `update_clone()', and the
  git interface in C for performing the merging, checkout and rebase
  where necessary.

  After this process, the builtin is added to the commands array in
  `submodule--helper.c'. And since these two functions are the last bit
  of functionality left to convert in submodules, an extended goal can
  be to get rid of the shell script altogether, and make the helper into
  the actual builtin [1].

  [1]
  <https://lore.kernel.org/git/nycvar.QRO.7.76.6.2011191327320.56@tvgsbejvaqbjf.bet/>


7 Timeline (using the format dd/mm)
===================================

  Periods of limited availability (read: hectic chaos):
  - From 13/04 to 20/04 I will be having project evaluations and lab
    assessments for five of my courses.
  - From 20/04 to 01/05 I have my in-semester exams.
  - For a period of two weeks in the range of 08/05 to 29/05 I will be
    having my end-semester exams.
  My commitment: I will still have time during my finals to help people
  out on the mailing list, get acquainted with the community and its
  processes, and even review patches if I can. This is because we get
  holidays between each exam, and my grades are good enough to that I
  can prioritise git over my studies ;-)

  And on the safe side, I will still engage with the community from now
  till 07/06 so that the community bonding period is not compromised in
  any way.

  Periods of abundant availability: After 29/05 all the way to the first
  week of August, I will be having my summer break, so I can dedicate
  myself to git full-time :-)

  I would have also finished all my core courses, so even after that, I
  will have enough of time to give back to git past my GSoC period.

  Phase 1: 07/06 to 14/06 -- Investigate and devise a strategy to port
  the submodule functions
  - This phase will be more diagrams in my notebook than code in my
    editor -- I will go through all the methods used to port the other
    submodule functions and see how to do the same for what is left.
  - I will find the C equivalents of all the shell invocations in
    `git-submodule.sh', and see what invocations have /no/ equivalent
    and need to be created as helpers in C (Eg: What is the equivalent
    to the `ensure-core-worktree' invocation in C?). For all the helpers
    and new functionality that I do introduce, I will need to create the
    testing strategy for the same.
  - I will go through all the work done by Shourya in his patch, and try
    to understand it properly. I will also see the mistakes that were
    caught in all the reviews for previous submodule conversion patches
    and try to learn from them before I jump to the code.
  - Deliverable: I will create a checklist for all the work that needs
    to be done with as much detail as I can with the help of inputs from
    my mentor and all the knowledge I have gained in the process.

  Phase 2: 14/06 to 28/06 -- Convert `add' to builtin in C
  - I will work on completing `git submodule add'. One strategy would be
    to either reimplement the whole thing using what was learnt in
    Shourya's attempt, but it is probably wiser to just take his patch
    and modify it. I would know what to do by the time I reach this
    phase.
  - I will also add tests for this functionality. I will also document
    my changes when required. These would be unit tests for the helpers
    introduced, and integration of `add' with the other commands.
  - Deliverable: Completely port `add' to C!

  Phase 3: 28/06 to 16/08 -- Convert `update' to builtin
  - Some work has already been done by Stephan Beller that moves the
    functionality of `update' to `submodule--helper.c':
    <https://github.com/git/git/commit/48308681b072a1d32e1361c255347324a8ad151e>,
    but a lot of the business logic of going into the submodule and
    checking out or merging or rebasing needs to still be converted.
    Plenty to do here.
  - As with `add', all of the appropriate tests need to be written and
    the changes documented. As I have learnt from the Pro Git Book,
    there are a lot of subtleties with how update does its work that I
    need to watch out for.
  - Deliverable: Completely port `update' to C!

  Bonus Phase: If I am ahead of time -- Remove the need for a
  `submodule--helper', and make it a proper C builtin.
  - Once all the submodule functionality is ported, the shell script is
    not really doing much more than parsing the arguments and passing it
    to the helper. We won't need this anymore if it is implemented.


8 Beyond GSoC
=============

  I love the process of working as a community more than anything else,
  and I already felt very welcomed by the git community the moment I
  started sending in my microproject patch series. Whether I am selected
  or not, I will continue giving back to git wherever I can. Since my
  final year is light on coursework, I will be able to mentor people and
  help expand the git developer community through all the ways I can (be
  it code review, helping people find the right resources or evangelism
  of git).


9 Blogging
==========

  I will be blogging about my progress on a weekly basis and either post
  it on my website at <https://atharvaraykar.me> (probably will tuck it
  away in a /gsoc path). Technical blogging is not particularly new to
  me, and I hope my posts can help future contributors of git.


10 Final Remarks: A little more about me
========================================

  These are some of my core values that I believe will be important to
  pull off this project and make the most of my time in GSoC:
  - Hard problems don't frustrate me, rather they excite me. Bugs make
    my brain perk up (this sentence best left with context). I love
    learning.
  - I am pro-transparency. If I am having some trouble, I will be open
    about it. I don't hesitate to ask questions and dig deep if I need
    to.
  - At the same time, when I ask a question, I only do so after I have
    struggled with the problem for enough time and done my due diligence
    in trying to solve it. Clear communication is very important to make
    this work.
  - I am also very comfortable with learning things all on my own (I
    have barely known any other way), and working in a remote,
    asynchronous setting.
  I hope to make the world better in my own small way by contributing to
  a tool that everyone uses and I like. It's more rewarding than any
  internship that my peers are doing this year. I look forward to
  learning more.


^ permalink raw reply	[relevance 4%]

* [PATCH v3 2/3] submodule: port submodule subcommand 'add' from shell to C
  @ 2020-12-14 23:19 19% ` Shourya Shukla
  0 siblings, 0 replies; 200+ results
From: Shourya Shukla @ 2020-12-14 23:19 UTC (permalink / raw)
  To: git
  Cc: gitster, Johannes.Schindelin, liu.denton, christian.couder,
	kaartic.sivaraam, Shourya Shukla, Christian Couder, Stefan Beller,
	Prathamesh Chavan

Convert submodule subcommand 'add' to a builtin and call it via
'git-submodule.sh'.

Also, since the command die()s out in case of absence of commits in the
submodule, the keyword 'fatal' is prefixed in the error messages.
Therefore, prepend the keyword in the expected output of test t7400.6.

While at it, eliminate the extra preprocessor directive
`#include "dir.h"` at the start of 'submodule--helper.c'.

Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Mentored-by: Stefan Beller <stefanbeller@gmail.com>
Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Signed-off-by: Shourya Shukla <periperidip@gmail.com>
---
 builtin/submodule--helper.c |   2 +-
 git-submodule.sh            | 161 +-----------------------------------
 t/t7400-submodule-basic.sh  |   2 +-
 3 files changed, 3 insertions(+), 162 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 4dfad35d77..4f1d892b9a 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -19,7 +19,6 @@
 #include "diffcore.h"
 #include "diff.h"
 #include "object-store.h"
-#include "dir.h"
 #include "advice.h"
 
 #define OPT_QUIET (1 << 0)
@@ -3185,6 +3184,7 @@ static struct cmd_struct commands[] = {
 	{"config", module_config, 0},
 	{"set-url", module_set_url, 0},
 	{"set-branch", module_set_branch, 0},
+	{"add", module_add, SUPPORT_SUPER_PREFIX},
 };
 
 int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
diff --git a/git-submodule.sh b/git-submodule.sh
index eb90f18229..b586f9532d 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -145,166 +145,7 @@ cmd_add()
 		shift
 	done
 
-	if ! git submodule--helper config --check-writeable >/dev/null 2>&1
-	then
-		 die "$(eval_gettext "please make sure that the .gitmodules file is in the working tree")"
-	fi
-
-	if test -n "$reference_path"
-	then
-		is_absolute_path "$reference_path" ||
-		reference_path="$wt_prefix$reference_path"
-
-		reference="--reference=$reference_path"
-	fi
-
-	repo=$1
-	sm_path=$2
-
-	if test -z "$sm_path"; then
-		sm_path=$(printf '%s\n' "$repo" |
-			sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
-	fi
-
-	if test -z "$repo" || test -z "$sm_path"; then
-		usage
-	fi
-
-	is_absolute_path "$sm_path" || sm_path="$wt_prefix$sm_path"
-
-	# assure repo is absolute or relative to parent
-	case "$repo" in
-	./*|../*)
-		test -z "$wt_prefix" ||
-		die "$(gettext "Relative path can only be used from the toplevel of the working tree")"
-
-		# dereference source url relative to parent's url
-		realrepo=$(git submodule--helper resolve-relative-url "$repo") || exit
-		;;
-	*:*|/*)
-		# absolute url
-		realrepo=$repo
-		;;
-	*)
-		die "$(eval_gettext "repo URL: '\$repo' must be absolute or begin with ./|../")"
-	;;
-	esac
-
-	# normalize path:
-	# multiple //; leading ./; /./; /../; trailing /
-	sm_path=$(printf '%s/\n' "$sm_path" |
-		sed -e '
-			s|//*|/|g
-			s|^\(\./\)*||
-			s|/\(\./\)*|/|g
-			:start
-			s|\([^/]*\)/\.\./||
-			tstart
-			s|/*$||
-		')
-	if test -z "$force"
-	then
-		git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
-		die "$(eval_gettext "'\$sm_path' already exists in the index")"
-	else
-		git ls-files -s "$sm_path" | sane_grep -v "^160000" > /dev/null 2>&1 &&
-		die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
-	fi
-
-	if test -d "$sm_path" &&
-		test -z $(git -C "$sm_path" rev-parse --show-cdup 2>/dev/null)
-	then
-	    git -C "$sm_path" rev-parse --verify -q HEAD >/dev/null ||
-	    die "$(eval_gettext "'\$sm_path' does not have a commit checked out")"
-	fi
-
-	if test -z "$force"
-	then
-	    dryerr=$(git add --dry-run --ignore-missing --no-warn-embedded-repo "$sm_path" 2>&1 >/dev/null)
-	    res=$?
-	    if test $res -ne 0
-	    then
-		 echo >&2 "$dryerr"
-		 exit $res
-	    fi
-	fi
-
-	if test -n "$custom_name"
-	then
-		sm_name="$custom_name"
-	else
-		sm_name="$sm_path"
-	fi
-
-	if ! git submodule--helper check-name "$sm_name"
-	then
-		die "$(eval_gettext "'$sm_name' is not a valid submodule name")"
-	fi
-
-	# perhaps the path exists and is already a git repo, else clone it
-	if test -e "$sm_path"
-	then
-		if test -d "$sm_path"/.git || test -f "$sm_path"/.git
-		then
-			eval_gettextln "Adding existing repo at '\$sm_path' to the index"
-		else
-			die "$(eval_gettext "'\$sm_path' already exists and is not a valid git repo")"
-		fi
-
-	else
-		if test -d ".git/modules/$sm_name"
-		then
-			if test -z "$force"
-			then
-				eval_gettextln >&2 "A git directory for '\$sm_name' is found locally with remote(s):"
-				GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^,"  ", -e s,' (fetch)',, >&2
-				die "$(eval_gettextln "\
-If you want to reuse this local git directory instead of cloning again from
-  \$realrepo
-use the '--force' option. If the local git directory is not the correct repo
-or you are unsure what this means choose another name with the '--name' option.")"
-			else
-				eval_gettextln "Reactivating local git directory for submodule '\$sm_name'."
-			fi
-		fi
-		git submodule--helper clone ${GIT_QUIET:+--quiet} ${progress:+"--progress"} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${dissociate:+"--dissociate"} ${depth:+"$depth"} || exit
-		(
-			sanitize_submodule_env
-			cd "$sm_path" &&
-			# ash fails to wordsplit ${branch:+-b "$branch"...}
-			case "$branch" in
-			'') git checkout -f -q ;;
-			?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
-			esac
-		) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")"
-	fi
-	git config submodule."$sm_name".url "$realrepo"
-
-	git add --no-warn-embedded-repo $force "$sm_path" ||
-	die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
-
-	git submodule--helper config submodule."$sm_name".path "$sm_path" &&
-	git submodule--helper config submodule."$sm_name".url "$repo" &&
-	if test -n "$branch"
-	then
-		git submodule--helper config submodule."$sm_name".branch "$branch"
-	fi &&
-	git add --force .gitmodules ||
-	die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
-
-	# NEEDSWORK: In a multi-working-tree world, this needs to be
-	# set in the per-worktree config.
-	if git config --get submodule.active >/dev/null
-	then
-		# If the submodule being adding isn't already covered by the
-		# current configured pathspec, set the submodule's active flag
-		if ! git submodule--helper is-active "$sm_path"
-		then
-			git config submodule."$sm_name".active "true"
-		fi
-	else
-		git config submodule."$sm_name".active "true"
-	fi
+	git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper add ${force:+--force} ${GIT_QUIET:+--quiet} ${progress:+--progress} ${branch:+--branch "$branch"} ${reference_path:+--reference "$reference_path"} ${dissociate:+--dissociate} ${custom_name:+--name "$custom_name"} ${depth:+"$depth"} -- "$@"
 }
 
 #
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index fec7e0299d..4ab8298385 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -48,7 +48,7 @@ test_expect_success 'submodule update aborts on missing gitmodules url' '
 
 test_expect_success 'add aborts on repository with no commits' '
 	cat >expect <<-\EOF &&
-	'"'repo-no-commits'"' does not have a commit checked out
+	fatal: '"'repo-no-commits'"' does not have a commit checked out
 	EOF
 	git init repo-no-commits &&
 	test_must_fail git submodule add ../a ./repo-no-commits 2>actual &&
-- 
2.25.1


^ permalink raw reply related	[relevance 19%]

* Re: [PATCH v2 2/3] submodule: port submodule subcommand 'add' from shell to C
  2020-10-07  7:45 18% ` [PATCH v2 2/3] submodule: port submodule subcommand 'add' " Shourya Shukla
@ 2020-10-07 18:37  2%   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2020-10-07 18:37 UTC (permalink / raw)
  To: Shourya Shukla
  Cc: git, christian.couder, kaartic.sivaraam, Johannes.Schindelin,
	liu.denton, Prathamesh Chavan, Christian Couder, Stefan Beller

Shourya Shukla <shouryashukla.oo@gmail.com> writes:

> From: Prathamesh Chavan <pc44800@gmail.com>
>
> Convert submodule subcommand 'add' to a builtin and call it via
> 'git-submodule.sh'.
>
> Also, since the command die()s out in case of absence of commits in the
> submodule, the keyword 'fatal' is prefixed in the error messages.
> Therefore, prepend the keyword in the expected output of test t7400.6.
>
> While at it, eliminate the extra preprocessor directive
> `#include "dir.h"` at the start of 'submodule--helper.c'.
>
> Mentored-by: Christian Couder <chriscool@tuxfamily.org>
> Mentored-by: Stefan Beller <stefanbeller@gmail.com>
> Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
> Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
> Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
> ---
>  builtin/submodule--helper.c | 391 +++++++++++++++++++++++++++++++++++-
>  git-submodule.sh            | 161 +--------------
>  t/t7400-submodule-basic.sh  |   2 +-
>  3 files changed, 392 insertions(+), 162 deletions(-)

Whoa.  That looks like a huge change.  Makes me wonder if we want
this split into multiple pieces, but let's read on.

> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index de5ad73bb8..ec0a50d032 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -19,7 +19,6 @@
>  #include "diffcore.h"
>  #include "diff.h"
>  #include "object-store.h"
> -#include "dir.h"
>  #include "advice.h"
>  
>  #define OPT_QUIET (1 << 0)
> @@ -2744,6 +2743,395 @@ static int module_set_branch(int argc, const char **argv, const char *prefix)
>  	return !!ret;
>  }
>  
> +struct add_data {
> +	const char *prefix;
> +	const char *branch;
> +	const char *reference_path;
> +	const char *sm_path;
> +	const char *sm_name;
> +	const char *repo;
> +	const char *realrepo;
> +	int depth;
> +	unsigned int force: 1;
> +	unsigned int quiet: 1;
> +	unsigned int progress: 1;
> +	unsigned int dissociate: 1;
> +};
> +#define ADD_DATA_INIT { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }

This is used in a context like this:

	struct add_data data = ADD_DATA_INIT;

It is a tangent, but wouldn't

	#define ADD_DATA_INIT { 0 }

be a more appropriate way to express that there is nothing other
than the initialization to zero values going on?

> +/*
> + * Guess dir name from repository: strip leading '.*[/:]',
> + * strip trailing '[:/]*.git'.
> + */

The original also strips trailing '/'.  The original does these in
order:

 - if $repo ends with '/', remove that.  The above description does
   not mention it.

 - if the result of the above ends with zero or more ':', followed
   by zero or more '/', followed by ".git", drop the matching part.
   The above description sounds as if it will remove ":/:/:.git"
   from the end (and the code seems to have the same bug, as
   after_slash_or_colon won't allow the code to know if the previous
   character before ".git" was slash or colon).

 - if the result of the above has '/' or ':' in it, remove everything
   before it and '/' or ':' itself.

> +static char *guess_dir_name(const char *repo)
> +{
> +	const char *p, *start, *end, *limit;
> +	int after_slash_or_colon;
> +
> +	after_slash_or_colon = 0;
> +	limit = repo + strlen(repo);
> +	start = repo;
> +	end = limit;
> +	for (p = repo; p < limit; p++) {
> +		if (starts_with(p, ".git")) {
> +			/* strip trailing '[:/]*.git' */
> +			if (!after_slash_or_colon)
> +				end = p;
> +			p += 3;
> +		} else if (*p == '/' || *p == ':') {
> +			/* strip leading '.*[/:]' */
> +			if (end == limit)
> +				end = p;
> +			after_slash_or_colon = 1;
> +		} else if (after_slash_or_colon) {
> +			start = p;
> +			end = limit;
> +			after_slash_or_colon = 0;
> +		}
> +	}
> +	return xstrndup(start, end - start);

So, this looks quite bogus and unnatural.  Checking for ".git" at
every position in the string is meaningless.

I wonder if something along the following (beware: not even compile
tested or checked for off-by-ones) would be easier to follow and
more faithful conversion to the original.

	ep = repo + strlen(repo);

        /*
         * eat trailing slashes - a conversion less faithful to
         * the original may want to loop to cull duplicated trailing
	 * slashes, but we can leave it as user-error for now.
	 */
	if (repo < ep - 1 && ep[-1] == '/')
		ep--;

	/* eat ":*/*\.git" at the tail */
	if (repo < ep - 4 && !memcmp(".git", ep - 4, 4)) {
		ep -= 4;
		while (repo < ep - 1 && ep[-1] == '/')
			ep--;
		while (repo < ep - 1 && ep[-1] == ':')
			ep--;
	}

	/* find the last ':' or '/' */
	for (sp = ep - 1; repo <= sp; sp--) {
		if (*sp == '/' || *sp == ':')
			break;
	}
        sp++; /* exclude '/' or ':' itself */

        /* sp point at the beginning, and ep points at the end */
	return xmemdupz(sp, ep - sp);

> +}

That's it for now; I didn't look at the remainder of this patch
during this sitting before I have to move on, but I may revisit the
rest at some other time.

Thanks.

^ permalink raw reply	[relevance 2%]

* [PATCH v2 2/3] submodule: port submodule subcommand 'add' from shell to C
  2020-10-07  7:45  6% [PATCH v2 0/3] submodule: port subcommand add from shell to C Shourya Shukla
@ 2020-10-07  7:45 18% ` Shourya Shukla
  2020-10-07 18:37  2%   ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-10-07  7:45 UTC (permalink / raw)
  To: git
  Cc: gitster, christian.couder, kaartic.sivaraam, Johannes.Schindelin,
	liu.denton, Prathamesh Chavan, Christian Couder, Stefan Beller,
	Shourya Shukla

From: Prathamesh Chavan <pc44800@gmail.com>

Convert submodule subcommand 'add' to a builtin and call it via
'git-submodule.sh'.

Also, since the command die()s out in case of absence of commits in the
submodule, the keyword 'fatal' is prefixed in the error messages.
Therefore, prepend the keyword in the expected output of test t7400.6.

While at it, eliminate the extra preprocessor directive
`#include "dir.h"` at the start of 'submodule--helper.c'.

Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Mentored-by: Stefan Beller <stefanbeller@gmail.com>
Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
---
 builtin/submodule--helper.c | 391 +++++++++++++++++++++++++++++++++++-
 git-submodule.sh            | 161 +--------------
 t/t7400-submodule-basic.sh  |   2 +-
 3 files changed, 392 insertions(+), 162 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index de5ad73bb8..ec0a50d032 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -19,7 +19,6 @@
 #include "diffcore.h"
 #include "diff.h"
 #include "object-store.h"
-#include "dir.h"
 #include "advice.h"
 
 #define OPT_QUIET (1 << 0)
@@ -2744,6 +2743,395 @@ static int module_set_branch(int argc, const char **argv, const char *prefix)
 	return !!ret;
 }
 
+struct add_data {
+	const char *prefix;
+	const char *branch;
+	const char *reference_path;
+	const char *sm_path;
+	const char *sm_name;
+	const char *repo;
+	const char *realrepo;
+	int depth;
+	unsigned int force: 1;
+	unsigned int quiet: 1;
+	unsigned int progress: 1;
+	unsigned int dissociate: 1;
+};
+#define ADD_DATA_INIT { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }
+
+/*
+ * Guess dir name from repository: strip leading '.*[/:]',
+ * strip trailing '[:/]*.git'.
+ */
+static char *guess_dir_name(const char *repo)
+{
+	const char *p, *start, *end, *limit;
+	int after_slash_or_colon;
+
+	after_slash_or_colon = 0;
+	limit = repo + strlen(repo);
+	start = repo;
+	end = limit;
+	for (p = repo; p < limit; p++) {
+		if (starts_with(p, ".git")) {
+			/* strip trailing '[:/]*.git' */
+			if (!after_slash_or_colon)
+				end = p;
+			p += 3;
+		} else if (*p == '/' || *p == ':') {
+			/* strip leading '.*[/:]' */
+			if (end == limit)
+				end = p;
+			after_slash_or_colon = 1;
+		} else if (after_slash_or_colon) {
+			start = p;
+			end = limit;
+			after_slash_or_colon = 0;
+		}
+	}
+	return xstrndup(start, end - start);
+}
+
+static void fprintf_submodule_remote(const char *str)
+{
+	const char *p = str;
+	const char *start;
+	const char *end;
+	char *name, *url;
+
+	start = p;
+	while (*p != ' ')
+		p++;
+	end = p;
+	name = xstrndup(start, end - start);
+
+	while(*p == ' ')
+		p++;
+	start = p;
+	while (*p != ' ')
+		p++;
+	end = p;
+	url = xstrndup(start, end - start);
+
+	fprintf(stderr, "  %s\t%s\n", name, url);
+	free(name);
+	free(url);
+}
+
+static int check_sm_exists(unsigned int force, const char *path) {
+
+	int cache_pos, dir_in_cache = 0;
+	if (read_cache() < 0)
+		die(_("index file corrupt"));
+
+	cache_pos = cache_name_pos(path, strlen(path));
+	if(cache_pos < 0 && (directory_exists_in_index(&the_index,
+	   path, strlen(path)) == index_directory))
+		dir_in_cache = 1;
+
+	if (!force) {
+		if (cache_pos >= 0 || dir_in_cache)
+			die(_("'%s' already exists in the index"), path);
+	} else {
+		struct cache_entry *ce = NULL;
+		if (cache_pos >= 0)
+			ce = the_index.cache[cache_pos];
+		if (dir_in_cache || (ce && !S_ISGITLINK(ce->ce_mode)))
+			die(_("'%s' already exists in the index and is not a "
+			      "submodule"), path);
+	}
+	return 0;
+}
+
+static void modify_remote_v(struct strbuf *sb)
+{
+	int i;
+	for (i = 0; i < sb->len; i++) {
+		const char *start = sb->buf + i;
+		const char *end = start;
+		while (sb->buf[i++] != '\n')
+			end++;
+		if (!strcmp("fetch", xstrndup(end - 6, 5)))
+			fprintf_submodule_remote(xstrndup(start, end - start - 7));
+	}
+}
+
+static int add_submodule(struct add_data *info)
+{
+	/* perhaps the path exists and is already a git repo, else clone it */
+	if (is_directory(info->sm_path)) {
+		char *sub_git_path = xstrfmt("%s/.git", info->sm_path);
+		if (is_directory(sub_git_path) || file_exists(sub_git_path))
+			printf(_("Adding existing repo at '%s' to the index\n"),
+				 info->sm_path);
+		else
+			die(_("'%s' already exists and is not a valid git repo"),
+			      info->sm_path);
+		free(sub_git_path);
+	} else {
+		struct strvec clone_args = STRVEC_INIT;
+		struct child_process cp = CHILD_PROCESS_INIT;
+		char *submodule_git_dir = xstrfmt(".git/modules/%s", info->sm_name);
+
+		if (is_directory(submodule_git_dir)) {
+			if (!info->force) {
+				struct child_process cp_rem = CHILD_PROCESS_INIT;
+				struct strbuf sb_rem = STRBUF_INIT;
+				cp_rem.git_cmd = 1;
+				fprintf(stderr, _("A git directory for '%s' is "
+					"found locally with remote(s):\n"),
+					info->sm_name);
+				strvec_pushf(&cp_rem.env_array,
+					     "GIT_DIR=%s", submodule_git_dir);
+				strvec_push(&cp_rem.env_array, "GIT_WORK_TREE=.");
+				strvec_pushl(&cp_rem.args, "remote", "-v", NULL);
+				if (!capture_command(&cp_rem, &sb_rem, 0)) {
+					modify_remote_v(&sb_rem);
+				}
+				error(_("If you want to reuse this local git "
+				      "directory instead of cloning again from\n "
+				      "  %s\n"
+				      "use the '--force' option. If the local "
+				      "git directory is not the correct repo\n"
+				      "or you are unsure what this means choose "
+				      "another name with the '--name' option."),
+				      info->realrepo);
+				return 1;
+			} else {
+				printf(_("Reactivating local git directory for "
+					 "submodule '%s'."), info->sm_path);
+			}
+		}
+		free(submodule_git_dir);
+
+		strvec_push(&clone_args, "clone");
+
+		if (info->quiet)
+			strvec_push(&clone_args, "--quiet");
+
+		if (info->progress)
+			strvec_push(&clone_args, "--progress");
+
+		if (info->prefix)
+			strvec_pushl(&clone_args, "--prefix", info->prefix, NULL);
+		strvec_pushl(&clone_args, "--path", info->sm_path, "--name",
+			     info->sm_name, "--url", info->realrepo, NULL);
+		if (info->reference_path)
+			strvec_pushl(&clone_args, "--reference",
+				     info->reference_path, NULL);
+		if (info->dissociate)
+			strvec_push(&clone_args, "--dissociate");
+
+		if (info->depth >= 0)
+			strvec_pushf(&clone_args, "--depth=%d", info->depth);
+
+		if (module_clone(clone_args.nr, clone_args.v, info->prefix)) {
+			strvec_clear(&clone_args);
+			return -1;
+		}
+
+		prepare_submodule_repo_env(&cp.env_array);
+		cp.git_cmd = 1;
+		cp.dir = info->sm_path;
+		strvec_pushl(&cp.args, "checkout", "-f", "-q", NULL);
+
+		if (info->branch) {
+			strvec_pushl(&cp.args, "-B", info->branch, NULL);
+			strvec_pushf(&cp.args, "origin/%s", info->branch);
+		}
+
+		if (run_command(&cp))
+			die(_("unable to checkout submodule '%s'"), info->sm_path);
+	}
+	return 0;
+}
+
+static void config_added_submodule(struct add_data *info)
+{
+	char *key, *var = NULL;
+	struct child_process cp = CHILD_PROCESS_INIT;
+
+	key = xstrfmt("submodule.%s.url", info->sm_name);
+	git_config_set_gently(key, info->realrepo);
+	free(key);
+
+	cp.git_cmd = 1;
+	strvec_pushl(&cp.args, "add", "--no-warn-embedded-repo", NULL);
+	if (info->force)
+		strvec_push(&cp.args, "--force");
+	strvec_pushl(&cp.args, "--", info->sm_path, ".gitmodules", NULL);
+
+	key = xstrfmt("submodule.%s.path", info->sm_name);
+	git_config_set_in_file_gently(".gitmodules", key, info->sm_path);
+	free(key);
+	key = xstrfmt("submodule.%s.url", info->sm_name);
+	git_config_set_in_file_gently(".gitmodules", key, info->repo);
+	free(key);
+	key = xstrfmt("submodule.%s.branch", info->sm_name);
+	if (info->branch)
+		git_config_set_in_file_gently(".gitmodules", key, info->branch);
+	free(key);
+
+	if (run_command(&cp))
+		die(_("failed to add submodule '%s'"), info->sm_path);
+
+	/*
+	 * NEEDSWORK: In a multi-working-tree world, this needs to be
+	 * set in the per-worktree config.
+	 */
+	if (!git_config_get_string("submodule.active", &var) && var) {
+
+		/*
+		 * If the submodule being adding isn't already covered by the
+		 * current configured pathspec, set the submodule's active flag
+		 */
+		if (!is_submodule_active(the_repository, info->sm_path)) {
+			key = xstrfmt("submodule.%s.active", info->sm_name);
+			git_config_set_gently(key, "true");
+			free(key);
+		}
+	} else {
+		key = xstrfmt("submodule.%s.active", info->sm_name);
+		git_config_set_gently(key, "true");
+		free(key);
+	}
+}
+
+static int module_add(int argc, const char **argv, const char *prefix)
+{
+	const char *branch = NULL, *custom_name = NULL, *realrepo = NULL;
+	const char *reference_path = NULL, *repo = NULL, *name = NULL;
+	char *path;
+	int force = 0, quiet = 0, depth = -1, progress = 0, dissociate = 0;
+	struct add_data info = ADD_DATA_INIT;
+	struct strbuf sb = STRBUF_INIT;
+
+	struct option options[] = {
+		OPT_STRING('b', "branch", &branch, N_("branch"),
+			   N_("branch of repository to add as submodule")),
+		OPT_BOOL('f', "force", &force, N_("allow adding an otherwise "
+						  "ignored submodule path")),
+		OPT__QUIET(&quiet, N_("print only error messages")),
+		OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
+		OPT_STRING(0, "reference", &reference_path, N_("repository"),
+			   N_("reference repository")),
+		OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
+		OPT_STRING(0, "name", &custom_name, N_("name"),
+			   N_("sets the submodule’s name to the given string "
+			      "instead of defaulting to its path")),
+		OPT_INTEGER(0, "depth", &depth, N_("depth for shallow clones")),
+		OPT_END()
+	};
+
+	const char *const usage[] = {
+		N_("git submodule--helper add [<options>] [--] [<path>]"),
+		NULL
+	};
+
+	argc = parse_options(argc, argv, prefix, options, usage, 0);
+
+	if (!is_writing_gitmodules_ok())
+		die(_("please make sure that the .gitmodules file is in the working tree"));
+
+	if (reference_path && !is_absolute_path(reference_path) && prefix)
+		reference_path = xstrfmt("%s%s", prefix, reference_path);
+
+	if (argc == 0 || argc > 2) {
+		usage_with_options(usage, options);
+	} else if (argc == 1) {
+		repo = argv[0];
+		path = guess_dir_name(repo);
+	} else {
+		repo = argv[0];
+		path = xstrdup(argv[1]);
+	}
+
+	if (!is_absolute_path(path) && prefix)
+		path = xstrfmt("%s%s", prefix, path);
+
+	/* assure repo is absolute or relative to parent */
+	if (starts_with_dot_dot_slash(repo) || starts_with_dot_slash(repo)) {
+		char *remote = get_default_remote();
+		char *remoteurl;
+		struct strbuf sb = STRBUF_INIT;
+
+		if (prefix)
+			die(_("relative path can only be used from the toplevel "
+			      "of the working tree"));
+		/* dereference source url relative to parent's url */
+		strbuf_addf(&sb, "remote.%s.url", remote);
+		if (git_config_get_string(sb.buf, &remoteurl))
+			remoteurl = xgetcwd();
+		realrepo = relative_url(remoteurl, repo, NULL);
+
+		free(remoteurl);
+		free(remote);
+	} else if (is_dir_sep(repo[0]) || strchr(repo, ':')) {
+		realrepo = repo;
+	} else {
+		die(_("repo URL: '%s' must be absolute or begin with ./|../"),
+		      repo);
+	}
+
+	/*
+	 * normalize path:
+	 * multiple //; leading ./; /./; /../;
+	 */
+	normalize_path_copy(path, path);
+	/* strip trailing '/' */
+	if (is_dir_sep(path[strlen(path) -1]))
+		path[strlen(path) - 1] = '\0';
+
+	if (check_sm_exists(force, path))
+		return 1;
+
+	strbuf_addstr(&sb, path);
+	if (is_nonbare_repository_dir(&sb)) {
+		struct object_id oid;
+		if (resolve_gitlink_ref(path, "HEAD", &oid) < 0)
+			die(_("'%s' does not have a commit checked out"), path);
+	}
+
+	if (!force) {
+		struct strbuf sb = STRBUF_INIT;
+		struct child_process cp = CHILD_PROCESS_INIT;
+		cp.git_cmd = 1;
+		cp.no_stdout = 1;
+		strvec_pushl(&cp.args, "add", "--dry-run", "--ignore-missing",
+			     "--no-warn-embedded-repo", path, NULL);
+		if (pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0)) {
+			fprintf(stderr, _("%s"), sb.buf);
+			return 1;
+		}
+		strbuf_release(&sb);
+	}
+
+	name = custom_name ? custom_name : path;
+	if (check_submodule_name(name))
+		die(_("'%s' is not a valid submodule name"), name);
+
+	info.prefix = prefix;
+	info.sm_name = name;
+	info.sm_path = path;
+	info.repo = repo;
+	info.realrepo = realrepo;
+	info.reference_path = reference_path;
+	info.branch = branch;
+	info.depth = depth;
+	info.progress = !!progress;
+	info.dissociate = !!dissociate;
+	info.force = !!force;
+	info.quiet = !!quiet;
+
+	if (add_submodule(&info))
+		return 1;
+	config_added_submodule(&info);
+
+	free(path);
+
+	return 0;
+}
+
 #define SUPPORT_SUPER_PREFIX (1<<0)
 
 struct cmd_struct {
@@ -2777,6 +3165,7 @@ static struct cmd_struct commands[] = {
 	{"config", module_config, 0},
 	{"set-url", module_set_url, 0},
 	{"set-branch", module_set_branch, 0},
+	{"add", module_add, SUPPORT_SUPER_PREFIX},
 };
 
 int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
diff --git a/git-submodule.sh b/git-submodule.sh
index 7ce52872b7..f1cbe4934a 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -146,166 +146,7 @@ cmd_add()
 		shift
 	done
 
-	if ! git submodule--helper config --check-writeable >/dev/null 2>&1
-	then
-		 die "$(eval_gettext "please make sure that the .gitmodules file is in the working tree")"
-	fi
-
-	if test -n "$reference_path"
-	then
-		is_absolute_path "$reference_path" ||
-		reference_path="$wt_prefix$reference_path"
-
-		reference="--reference=$reference_path"
-	fi
-
-	repo=$1
-	sm_path=$2
-
-	if test -z "$sm_path"; then
-		sm_path=$(printf '%s\n' "$repo" |
-			sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
-	fi
-
-	if test -z "$repo" || test -z "$sm_path"; then
-		usage
-	fi
-
-	is_absolute_path "$sm_path" || sm_path="$wt_prefix$sm_path"
-
-	# assure repo is absolute or relative to parent
-	case "$repo" in
-	./*|../*)
-		test -z "$wt_prefix" ||
-		die "$(gettext "Relative path can only be used from the toplevel of the working tree")"
-
-		# dereference source url relative to parent's url
-		realrepo=$(git submodule--helper resolve-relative-url "$repo") || exit
-		;;
-	*:*|/*)
-		# absolute url
-		realrepo=$repo
-		;;
-	*)
-		die "$(eval_gettext "repo URL: '\$repo' must be absolute or begin with ./|../")"
-	;;
-	esac
-
-	# normalize path:
-	# multiple //; leading ./; /./; /../; trailing /
-	sm_path=$(printf '%s/\n' "$sm_path" |
-		sed -e '
-			s|//*|/|g
-			s|^\(\./\)*||
-			s|/\(\./\)*|/|g
-			:start
-			s|\([^/]*\)/\.\./||
-			tstart
-			s|/*$||
-		')
-	if test -z "$force"
-	then
-		git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
-		die "$(eval_gettext "'\$sm_path' already exists in the index")"
-	else
-		git ls-files -s "$sm_path" | sane_grep -v "^160000" > /dev/null 2>&1 &&
-		die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
-	fi
-
-	if test -d "$sm_path" &&
-		test -z $(git -C "$sm_path" rev-parse --show-cdup 2>/dev/null)
-	then
-	    git -C "$sm_path" rev-parse --verify -q HEAD >/dev/null ||
-	    die "$(eval_gettext "'\$sm_path' does not have a commit checked out")"
-	fi
-
-	if test -z "$force"
-	then
-	    dryerr=$(git add --dry-run --ignore-missing --no-warn-embedded-repo "$sm_path" 2>&1 >/dev/null)
-	    res=$?
-	    if test $res -ne 0
-	    then
-		 echo >&2 "$dryerr"
-		 exit $res
-	    fi
-	fi
-
-	if test -n "$custom_name"
-	then
-		sm_name="$custom_name"
-	else
-		sm_name="$sm_path"
-	fi
-
-	if ! git submodule--helper check-name "$sm_name"
-	then
-		die "$(eval_gettext "'$sm_name' is not a valid submodule name")"
-	fi
-
-	# perhaps the path exists and is already a git repo, else clone it
-	if test -e "$sm_path"
-	then
-		if test -d "$sm_path"/.git || test -f "$sm_path"/.git
-		then
-			eval_gettextln "Adding existing repo at '\$sm_path' to the index"
-		else
-			die "$(eval_gettext "'\$sm_path' already exists and is not a valid git repo")"
-		fi
-
-	else
-		if test -d ".git/modules/$sm_name"
-		then
-			if test -z "$force"
-			then
-				eval_gettextln >&2 "A git directory for '\$sm_name' is found locally with remote(s):"
-				GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^,"  ", -e s,' (fetch)',, >&2
-				die "$(eval_gettextln "\
-If you want to reuse this local git directory instead of cloning again from
-  \$realrepo
-use the '--force' option. If the local git directory is not the correct repo
-or you are unsure what this means choose another name with the '--name' option.")"
-			else
-				eval_gettextln "Reactivating local git directory for submodule '\$sm_name'."
-			fi
-		fi
-		git submodule--helper clone ${GIT_QUIET:+--quiet} ${progress:+"--progress"} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${dissociate:+"--dissociate"} ${depth:+"$depth"} || exit
-		(
-			sanitize_submodule_env
-			cd "$sm_path" &&
-			# ash fails to wordsplit ${branch:+-b "$branch"...}
-			case "$branch" in
-			'') git checkout -f -q ;;
-			?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
-			esac
-		) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")"
-	fi
-	git config submodule."$sm_name".url "$realrepo"
-
-	git add --no-warn-embedded-repo $force "$sm_path" ||
-	die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
-
-	git submodule--helper config submodule."$sm_name".path "$sm_path" &&
-	git submodule--helper config submodule."$sm_name".url "$repo" &&
-	if test -n "$branch"
-	then
-		git submodule--helper config submodule."$sm_name".branch "$branch"
-	fi &&
-	git add --force .gitmodules ||
-	die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
-
-	# NEEDSWORK: In a multi-working-tree world, this needs to be
-	# set in the per-worktree config.
-	if git config --get submodule.active >/dev/null
-	then
-		# If the submodule being adding isn't already covered by the
-		# current configured pathspec, set the submodule's active flag
-		if ! git submodule--helper is-active "$sm_path"
-		then
-			git config submodule."$sm_name".active "true"
-		fi
-	else
-		git config submodule."$sm_name".active "true"
-	fi
+	git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper add ${force:+--force} ${GIT_QUIET:+--quiet} ${progress:+--progress} ${branch:+--branch "$branch"} ${reference_path:+--reference "$reference_path"} ${dissociate:+--dissociate} ${custom_name:+--name "$custom_name"} ${depth:+"$depth"} -- "$@"
 }
 
 #
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index fec7e0299d..4ab8298385 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -48,7 +48,7 @@ test_expect_success 'submodule update aborts on missing gitmodules url' '
 
 test_expect_success 'add aborts on repository with no commits' '
 	cat >expect <<-\EOF &&
-	'"'repo-no-commits'"' does not have a commit checked out
+	fatal: '"'repo-no-commits'"' does not have a commit checked out
 	EOF
 	git init repo-no-commits &&
 	test_must_fail git submodule add ../a ./repo-no-commits 2>actual &&
-- 
2.28.0


^ permalink raw reply related	[relevance 18%]

* [PATCH v2 0/3] submodule: port subcommand add from shell to C
@ 2020-10-07  7:45  6% Shourya Shukla
  2020-10-07  7:45 18% ` [PATCH v2 2/3] submodule: port submodule subcommand 'add' " Shourya Shukla
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-10-07  7:45 UTC (permalink / raw)
  To: git
  Cc: gitster, christian.couder, kaartic.sivaraam, Johannes.Schindelin,
	liu.denton, Shourya Shukla

Hello all,

This is the v2 of the patch with the same title, delivered more than a
month ago as a part of my GSoC. Link to v1:
https://lore.kernel.org/git/20200824090359.403944-1-shouryashukla.oo@gmail.com/

The changelog is as follows:

    1. Introduce PATCH[1/3](dir: change the scope of function
       'directory_exists_in_index()', 2020-10-06). This was done since
       the above mentioned function will be used in the patch that
       follows.

    2. There are multiple changes in this commit:

            A. Improve the part which checks if the 'path' given as
               argument exists or not. Implementing Kaartic's
               suggestions on the patch, I had to make sure that the
               case for checking if the path has tracked contents or
               not also works.

            B. Also, wrap the aforementioned segment in a function
               since it became very long. The function is called
               'check_sm_exists()'.

            C. Also, use the function 'is_nonbare_repository_dir()'
               instead of 'is_directory()' when trying to resolve
               gitlink.

            D. Append keyword 'fatal' in front of the expected output of
               test t7400.6 since the command die()s out in case of
               absence of commits in a submodule.

            E. Remove the extra `#include "dir.h"` from
               'submodule--helper.c'.

    3. Introduce PATCH[3/3] (t7400: add test to check 'submodule add'
       for tracked paths, 2020-10-07). Kaartic pointed out that a test
       for path with tracked contents did not exist and hence it was
       necessary to write one. Therefore, this commit introduces a new
       test 't7400.18: submodule add to path with tracked contents
       fails'.

Comments and feedback are appreciated. Sorry for the month long delay, I
was on a vacation.

I am attaching a range-diff between v1 and v2 at the end of this mail.

Regards,
Shourya Shukla
-----

-:  ---------- > 1:  bdac00494e dir: change the scope of function 'directory_exists_in_index()'
1:  b08d81e179 ! 2:  3e20d0fe04 submodule: port submodule subcommand 'add' from shell to C
    @@ Commit message
         'git-submodule.sh'.

         Also, since the command die()s out in case of absence of commits in the
    -    submodule and exits with exit status 1 when we try adding a submodule
    -    which is mentioned in .gitignore, the keyword 'fatal' is prefixed in the
    -    error messages. Therefore, prepend the keyword in the expected outputs
    -    of tests t7400.6 and t7400.16.
    +    submodule, the keyword 'fatal' is prefixed in the error messages.
    +    Therefore, prepend the keyword in the expected output of test t7400.6.
    +
    +    While at it, eliminate the extra preprocessor directive
    +    `#include "dir.h"` at the start of 'submodule--helper.c'.

         Mentored-by: Christian Couder <chriscool@tuxfamily.org>
         Mentored-by: Stefan Beller <stefanbeller@gmail.com>
    @@ Commit message
         Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>

      ## builtin/submodule--helper.c ##
    +@@
    + #include "diffcore.h"
    + #include "diff.h"
    + #include "object-store.h"
    +-#include "dir.h"
    + #include "advice.h"
    +
    + #define OPT_QUIET (1 << 0)
     @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char **argv, const char *prefix)
        return !!ret;
      }
    @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char *
     +  free(url);
     +}
     +
    ++static int check_sm_exists(unsigned int force, const char *path) {
    ++
    ++  int cache_pos, dir_in_cache = 0;
    ++  if (read_cache() < 0)
    ++          die(_("index file corrupt"));
    ++
    ++  cache_pos = cache_name_pos(path, strlen(path));
    ++  if(cache_pos < 0 && (directory_exists_in_index(&the_index,
    ++     path, strlen(path)) == index_directory))
    ++          dir_in_cache = 1;
    ++
    ++  if (!force) {
    ++          if (cache_pos >= 0 || dir_in_cache)
    ++                  die(_("'%s' already exists in the index"), path);
    ++  } else {
    ++          struct cache_entry *ce = NULL;
    ++          if (cache_pos >= 0)
    ++                  ce = the_index.cache[cache_pos];
    ++          if (dir_in_cache || (ce && !S_ISGITLINK(ce->ce_mode)))
    ++                  die(_("'%s' already exists in the index and is not a "
    ++                        "submodule"), path);
    ++  }
    ++  return 0;
    ++}
    ++
     +static void modify_remote_v(struct strbuf *sb)
     +{
     +  int i;
    @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char *
     +  if (is_dir_sep(path[strlen(path) -1]))
     +          path[strlen(path) - 1] = '\0';
     +
    -+  if (!force) {
    -+          if (is_directory(path) && submodule_from_path(the_repository, &null_oid, path))
    -+                  die(_("'%s' already exists in the index"), path);
    -+  } else {
    -+          int err;
    -+          if (index_name_pos(&the_index, path, strlen(path)) >= 0 &&
    -+              !is_submodule_populated_gently(path, &err))
    -+                  die(_("'%s' already exists in the index and is not a "
    -+                        "submodule"), path);
    -+  }
    ++  if (check_sm_exists(force, path))
    ++          return 1;
     +
     +  strbuf_addstr(&sb, path);
    -+  if (is_directory(path)) {
    ++  if (is_nonbare_repository_dir(&sb)) {
     +          struct object_id oid;
     +          if (resolve_gitlink_ref(path, "HEAD", &oid) < 0)
     +                  die(_("'%s' does not have a commit checked out"), path);
    @@ builtin/submodule--helper.c: static int module_set_branch(int argc, const char *
     +          cp.no_stdout = 1;
     +          strvec_pushl(&cp.args, "add", "--dry-run", "--ignore-missing",
     +                       "--no-warn-embedded-repo", path, NULL);
    -+          if (pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0))
    -+                  die(_("%s"), sb.buf);
    ++          if (pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0)) {
    ++                  fprintf(stderr, _("%s"), sb.buf);
    ++                  return 1;
    ++          }
     +          strbuf_release(&sb);
     +  }
     +
    @@ t/t7400-submodule-basic.sh: test_expect_success 'submodule update aborts on miss
        EOF
        git init repo-no-commits &&
        test_must_fail git submodule add ../a ./repo-no-commits 2>actual &&
    -@@ t/t7400-submodule-basic.sh: test_expect_success 'submodule add to .gitignored path fails' '
    -   (
    -           cd addtest-ignore &&
    -           cat <<-\EOF >expect &&
    --          The following paths are ignored by one of your .gitignore files:
    -+          fatal: The following paths are ignored by one of your .gitignore files:
    -           submod
    -           hint: Use -f if you really want to add them.
    -           hint: Turn this message off by running
    -           hint: "git config advice.addIgnoredFile false"
    -+
    -           EOF
    -           # Does not use test_commit due to the ignore
    -           echo "*" > .gitignore &&
-:  ---------- > 3:  98b05eb46d t7400: add test to check 'submodule add' for tracked paths
-----

Prathamesh Chavan (1):
  submodule: port submodule subcommand 'add' from shell to C

Shourya Shukla (2):
  dir: change the scope of function 'directory_exists_in_index()'
  t7400: add test to check 'submodule add' for tracked paths

 builtin/submodule--helper.c | 391 +++++++++++++++++++++++++++++++++++-
 dir.c                       |  10 +-
 dir.h                       |   9 +
 git-submodule.sh            | 161 +--------------
 t/t7400-submodule-basic.sh  |  13 +-
 5 files changed, 414 insertions(+), 170 deletions(-)

-- 
2.28.0


^ permalink raw reply	[relevance 6%]

* Git Test Coverage Report (v2.29.0-rc0)
@ 2020-10-06 20:38  2% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2020-10-06 20:38 UTC (permalink / raw)
  To: Git List

Here is the test coverage report for v2.29.0-rc0. I haven't sent a test-coverage report
in a while due to some issues with the 'seen' branch timing out, and then I got out of
the habit.

Here is the uncovered code introduced in v2.29.0-rc0 that was edited since v2.28.0.

Thanks,
-Stolee

[1] https://derrickstolee.github.io/git-test-coverage/reports/v2.29.0-rc0-commits.txt
[2] https://derrickstolee.github.io/git-test-coverage/reports/v2.29.0-rc0.txt
[3] https://derrickstolee.github.io/git-test-coverage/reports/v2.29.0-rc0.htm

---

Uncovered code in 'v2.29.0-rc0' not in 'v2.28.0'
--------------------------------------------------------

Commits introducing uncovered code:
Aaron Lipman	be5fe200 cmd_bisect__helper: defer parsing no-checkout flag
builtin/bisect--helper.c
be5fe200 906) res = bisect_next_all(the_repository, prefix);

Ævar Arnfjörð Bjarmason	6a83d902 coccinelle: make use of the "type" FREE_AND_NULL() rule
builtin/fast-import.c
6a83d902 995) FREE_AND_NULL(delta);

Brandon Williams	debca9d2 object: rename function 'typename' to 'type_name'
builtin/fast-import.c
debca9d2 2500) type_name(oe->type), command_buf.buf);

brian m. carlson	d7e6b6a8 fast-import: convert internal structs to struct object_id
builtin/fast-import.c
d7e6b6a8 892) fprintf(pack_edges, " %s",
d7e6b6a8 893) oid_to_hex(&t->oid));
d7e6b6a8 2639) oidcpy(&n->oid, &s->oid);

brian m. carlson	ddddf8d7 fast-import: permit reading multiple marks files
builtin/fast-import.c
ddddf8d7 1145) insert_mark(marks, mark, e);

brian m. carlson	912c13d5 fast-import: convert to struct object_id
builtin/fast-import.c
912c13d5 2471) oidcpy(&commit_oid, &s->oid);
912c13d5 2646) } else if (!get_oid(from, &n->oid)) {
912c13d5 2811) oidcpy(&oid, &s->oid);
912c13d5 2939) strbuf_addf(&line, "%s missing\n", oid_to_hex(oid));
912c13d5 3045)     get_oid_hex(buf + strlen("object "), oid))

brian m. carlson	1bdca816 fast-import: add options for rewriting submodules
builtin/fast-import.c
1bdca816 2193) return -1;
1bdca816 3068) return;
1bdca816 3328) die_errno("cannot read '%s'", f);

brian m. carlson	cd85b447 remote-curl: make --force-with-lease work with non-ASCII ref names
remote-curl.c
cd85b447 130) return -1;

brian m. carlson	e6a492b7 pack: convert struct pack_idx_entry to struct object_id
builtin/fast-import.c
e6a492b7 3103) oidcpy(&oid, &e->idx.oid);

brian m. carlson	28d055bd fast-import: make hash-size independent
builtin/fast-import.c
28d055bd 986) && (pack_size + PACK_SIZE_THRESHOLD + s.total_out) > max_packsize)
28d055bd 1083) && (pack_size + PACK_SIZE_THRESHOLD + len) > max_packsize)
28d055bd 2652) if (!buf || size < the_hash_algo->hexsz + 6)
28d055bd 3044) if (size < hexsz + strlen("object ") ||

Clemens Buchacher	98c2924c credentials: unable to connect to cache daemon
builtin/credential-cache.c
98c2924c 79) die_errno("unable to connect to cache daemon");

David Barr	8dc6a373 fast-import: add 'ls' command
builtin/fast-import.c
8dc6a373 3033) buf = gfi_unpack_entry(oe, &size);
8dc6a373 3047) break;
8dc6a373 3101) if (!e)

David Barr	85c62395 fast-import: let importers retrieve blobs
builtin/fast-import.c
85c62395 2917) die_errno("Write to frontend failed");
85c62395 2938) strbuf_reset(&line);
85c62395 2940) cat_blob_write(line.buf, line.len);
85c62395 2941) strbuf_release(&line);
85c62395 2942) free(buf);
85c62395 2943) return;

Derrick Stolee	663b2b1b maintenance: add commit-graph task
builtin/gc.c
663b2b1b 813) return 1;

Derrick Stolee	3103e984 maintenance: initialize task array
builtin/gc.c
3103e984 933) result = 1;

Derrick Stolee	d7514f6e maintenance: take a lock on the objects directory
builtin/gc.c
d7514f6e 904) if (!opts->auto_flag && !opts->quiet)
d7514f6e 907) free(lock_path);
d7514f6e 908) return 0;

Derrick Stolee	4ddc79b2 maintenance: add auto condition for commit-graph task
builtin/gc.c
4ddc79b2 722) static int dfs_on_ref(const char *refname,
4ddc79b2 726) struct cg_auto_data *data = (struct cg_auto_data *)cb_data;
4ddc79b2 727) int result = 0;
4ddc79b2 729) struct commit_list *stack = NULL;
4ddc79b2 732) if (!peel_ref(refname, &peeled))
4ddc79b2 733) oid = &peeled;
4ddc79b2 734) if (oid_object_info(the_repository, oid, NULL) != OBJ_COMMIT)
4ddc79b2 735) return 0;
4ddc79b2 737) commit = lookup_commit(the_repository, oid);
4ddc79b2 738) if (!commit)
4ddc79b2 739) return 0;
4ddc79b2 740) if (parse_commit(commit))
4ddc79b2 741) return 0;
4ddc79b2 743) commit_list_append(commit, &stack);
4ddc79b2 745) while (!result && stack) {
4ddc79b2 748) commit = pop_commit(&stack);
4ddc79b2 750) for (parent = commit->parents; parent; parent = parent->next) {
4ddc79b2 751) if (parse_commit(parent->item) ||
4ddc79b2 752)     commit_graph_position(parent->item) != COMMIT_NOT_FROM_GRAPH ||
4ddc79b2 753)     parent->item->object.flags & SEEN)
4ddc79b2 754) continue;
4ddc79b2 756) parent->item->object.flags |= SEEN;
4ddc79b2 757) data->num_not_in_graph++;
4ddc79b2 759) if (data->num_not_in_graph >= data->limit) {
4ddc79b2 760) result = 1;
4ddc79b2 761) break;
4ddc79b2 764) commit_list_append(parent->item, &stack);
4ddc79b2 768) free_commit_list(stack);
4ddc79b2 769) return result;
4ddc79b2 772) static int should_write_commit_graph(void)
4ddc79b2 777) data.num_not_in_graph = 0;
4ddc79b2 778) data.limit = 100;
4ddc79b2 779) git_config_get_int("maintenance.commit-graph.auto",
4ddc79b2 782) if (!data.limit)
4ddc79b2 783) return 0;
4ddc79b2 784) if (data.limit < 0)
4ddc79b2 785) return 1;
4ddc79b2 787) result = for_each_ref(dfs_on_ref, &data);
4ddc79b2 789) clear_commit_marks_all(SEEN);
4ddc79b2 791) return result;

Dmitry Ivankov	4b4963c0 fast-import: check committer name more strictly
builtin/fast-import.c
4b4963c0 1975) if (strcmp("now", ltgt))

Dmitry Potapov	8db751a8 fast-import: tag may point to any object type
builtin/fast-import.c
8db751a8 2812) type = OBJ_COMMIT;

Elijah Newren	3164e6bd fast-import: fix handling of deleted tags
builtin/fast-import.c
3164e6bd 2904) first_tag = t->next_tag;

Elijah Newren	44c7e1a7 mem-pool: use more standard initialization and finalization
read-cache.c
44c7e1a7 2076) istate->ce_mem_pool = xmalloc(sizeof(*istate->ce_mem_pool));
44c7e1a7 2077) mem_pool_init(istate->ce_mem_pool, 0);
44c7e1a7 2106) mem_pool_init(p->ce_mem_pool,
44c7e1a7 2109) mem_pool_init(p->ce_mem_pool,

Elijah Newren	b8f50e5b fast-import: add support for new 'alias' command
builtin/fast-import.c
b8f50e5b 2623) return 0;

Elijah Newren	a762c8c1 mem-pool: add convenience functions for strdup and strndup
mem-pool.c
a762c8c1 108) char *mem_pool_strndup(struct mem_pool *pool, const char *str, size_t len)
a762c8c1 110) char *p = memchr(str, '\0', len);
a762c8c1 111) size_t actual_len = (p ? p - str : len);
a762c8c1 112) char *ret = mem_pool_alloc(pool, actual_len+1);
a762c8c1 114) ret[actual_len] = '\0';
a762c8c1 115) return memcpy(ret, str, actual_len);

Elijah Newren	f87bf284 mem-pool: use consistent pool variable name
mem-pool.c
f87bf284 118) int mem_pool_contains(struct mem_pool *pool, void *mem)
f87bf284 123) for (p = pool->mp_block; p; p = p->next_block)

Elijah Newren	253fb5f8 fast-import: Improve robustness when D->F changes provided in wrong order
builtin/fast-import.c
253fb5f8 1513) return 1;

Elijah Newren	7ffde293 fast-import: only allow cat-blob requests where it makes sense
builtin/fast-import.c
7ffde293 2329) parse_cat_blob(v);

Emily Shaffer	1411914a bugreport: add uname info
builtin/bugreport.c
1411914a 21) strbuf_addf(sys_info, _("uname() failed with error '%s' (%d)\n"),
1411914a 23)     errno);

Eric Sunshine	b214ab5a worktree: teach "repair" to fix outgoing links to worktrees
worktree.c
b214ab5a 663) fn = repair_noop;

Eric Sunshine	59d876cc init: make --separate-git-dir work from within linked worktree
builtin/init-db.c
59d876cc 664) die_errno(_("cannot chdir to %s"), mainwt.buf);

Eric Sunshine	07a7f8de format-patch: use 'origin' as start of current-series-range when known
builtin/log.c
07a7f8de 1689) else if (prev_is_range)

Eric Wong	d9545c7f fast-import: implement unpack limit
builtin/fast-import.c
d9545c7f 827) die_errno("Failed seeking to start of '%s'", p->pack_name);
d9545c7f 3465) unpack_limit = limit;

Han-Wen Nienhuys	4441f427 refs: add GIT_TRACE_REFS debugging mechanism
refs/debug.c
4441f427 22) res = xmalloc(sizeof(struct debug_ref_store));
4441f427 23) be_copy = xmalloc(sizeof(*be_copy));
4441f427 24) *be_copy = refs_be_debug;
4441f427 26) be_copy->name = store->be->name;
4441f427 27) trace_printf_key(&trace_refs, "ref_store for %s\n", gitdir);
4441f427 28) res->refs = store;
4441f427 29) base_ref_store_init((struct ref_store *)res, be_copy);
4441f427 30) return (struct ref_store *)res;
4441f427 33) static int debug_init_db(struct ref_store *refs, struct strbuf *err)
4441f427 35) struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
4441f427 36) int res = drefs->refs->be->init_db(drefs->refs, err);
4441f427 37) trace_printf_key(&trace_refs, "init_db: %d\n", res);
4441f427 38) return res;
4441f427 41) static int debug_transaction_prepare(struct ref_store *refs,
4441f427 45) struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
4441f427 47) transaction->ref_store = drefs->refs;
4441f427 48) res = drefs->refs->be->transaction_prepare(drefs->refs, transaction,
4441f427 50) trace_printf_key(&trace_refs, "transaction_prepare: %d\n", res);
4441f427 51) return res;
4441f427 54) static void print_update(int i, const char *refname,
4441f427 59) char o[GIT_MAX_HEXSZ + 1] = "null";
4441f427 60) char n[GIT_MAX_HEXSZ + 1] = "null";
4441f427 61) if (old_oid)
4441f427 62) oid_to_hex_r(o, old_oid);
4441f427 63) if (new_oid)
4441f427 64) oid_to_hex_r(n, new_oid);
4441f427 66) type &= 0xf; /* see refs.h REF_* */
4441f427 67) flags &= REF_HAVE_NEW | REF_HAVE_OLD | REF_NO_DEREF |
4441f427 69) trace_printf_key(&trace_refs, "%d: %s %s -> %s (F=0x%x, T=0x%x) \"%s\"\n", i, refname,
4441f427 71) }
4441f427 73) static void print_transaction(struct ref_transaction *transaction)
4441f427 76) trace_printf_key(&trace_refs, "transaction {\n");
4441f427 77) for (i = 0; i < transaction->nr; i++) {
4441f427 78) struct ref_update *u = transaction->updates[i];
4441f427 79) print_update(i, u->refname, &u->old_oid, &u->new_oid, u->flags,
4441f427 80)      u->type, u->msg);
4441f427 82) trace_printf_key(&trace_refs, "}\n");
4441f427 83) }
4441f427 85) static int debug_transaction_finish(struct ref_store *refs,
4441f427 89) struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
4441f427 91) transaction->ref_store = drefs->refs;
4441f427 92) res = drefs->refs->be->transaction_finish(drefs->refs, transaction,
4441f427 94) print_transaction(transaction);
4441f427 95) trace_printf_key(&trace_refs, "finish: %d\n", res);
4441f427 96) return res;
4441f427 99) static int debug_transaction_abort(struct ref_store *refs,
4441f427 103) struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
4441f427 105) transaction->ref_store = drefs->refs;
4441f427 106) res = drefs->refs->be->transaction_abort(drefs->refs, transaction, err);
4441f427 107) return res;
4441f427 110) static int debug_initial_transaction_commit(struct ref_store *refs,
4441f427 114) struct debug_ref_store *drefs = (struct debug_ref_store *)refs;
4441f427 116) transaction->ref_store = drefs->refs;
4441f427 117) res = drefs->refs->be->initial_transaction_commit(drefs->refs,
4441f427 119) return res;
4441f427 122) static int debug_pack_refs(struct ref_store *ref_store, unsigned int flags)
4441f427 124) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 125) int res = drefs->refs->be->pack_refs(drefs->refs, flags);
4441f427 126) trace_printf_key(&trace_refs, "pack_refs: %d\n", res);
4441f427 127) return res;
4441f427 130) static int debug_create_symref(struct ref_store *ref_store,
4441f427 134) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 135) int res = drefs->refs->be->create_symref(drefs->refs, ref_name, target,
4441f427 137) trace_printf_key(&trace_refs, "create_symref: %s -> %s \"%s\": %d\n", ref_name,
4441f427 139) return res;
4441f427 142) static int debug_delete_refs(struct ref_store *ref_store, const char *msg,
4441f427 145) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 146) int res =
4441f427 147) drefs->refs->be->delete_refs(drefs->refs, msg, refnames, flags);
4441f427 149) trace_printf_key(&trace_refs, "delete_refs {\n");
4441f427 150) for (i = 0; i < refnames->nr; i++)
4441f427 151) trace_printf_key(&trace_refs, "%s\n", refnames->items[i].string);
4441f427 152) trace_printf_key(&trace_refs, "}: %d\n", res);
4441f427 153) return res;
4441f427 156) static int debug_rename_ref(struct ref_store *ref_store, const char *oldref,
4441f427 159) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 160) int res = drefs->refs->be->rename_ref(drefs->refs, oldref, newref,
4441f427 162) trace_printf_key(&trace_refs, "rename_ref: %s -> %s \"%s\": %d\n", oldref, newref,
4441f427 164) return res;
4441f427 167) static int debug_copy_ref(struct ref_store *ref_store, const char *oldref,
4441f427 170) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 171) int res =
4441f427 172) drefs->refs->be->copy_ref(drefs->refs, oldref, newref, logmsg);
4441f427 173) trace_printf_key(&trace_refs, "copy_ref: %s -> %s \"%s\": %d\n", oldref, newref,
4441f427 175) return res;
4441f427 183) static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator)
4441f427 185) struct debug_ref_iterator *diter =
4441f427 187) int res = diter->iter->vtable->advance(diter->iter);
4441f427 188) if (res)
4441f427 189) trace_printf_key(&trace_refs, "iterator_advance: (%d)\n", res);
4441f427 191) trace_printf_key(&trace_refs, "iterator_advance: %s (0)\n",
4441f427 194) diter->base.ordered = diter->iter->ordered;
4441f427 195) diter->base.refname = diter->iter->refname;
4441f427 196) diter->base.oid = diter->iter->oid;
4441f427 197) diter->base.flags = diter->iter->flags;
4441f427 198) return res;
4441f427 201) static int debug_ref_iterator_peel(struct ref_iterator *ref_iterator,
4441f427 204) struct debug_ref_iterator *diter =
4441f427 206) int res = diter->iter->vtable->peel(diter->iter, peeled);
4441f427 207) trace_printf_key(&trace_refs, "iterator_peel: %s: %d\n", diter->iter->refname, res);
4441f427 208) return res;
4441f427 211) static int debug_ref_iterator_abort(struct ref_iterator *ref_iterator)
4441f427 213) struct debug_ref_iterator *diter =
4441f427 215) int res = diter->iter->vtable->abort(diter->iter);
4441f427 216) trace_printf_key(&trace_refs, "iterator_abort: %d\n", res);
4441f427 217) return res;
4441f427 226) debug_ref_iterator_begin(struct ref_store *ref_store, const char *prefix,
4441f427 229) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 230) struct ref_iterator *res =
4441f427 231) drefs->refs->be->iterator_begin(drefs->refs, prefix, flags);
4441f427 232) struct debug_ref_iterator *diter = xcalloc(1, sizeof(*diter));
4441f427 233) base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable, 1);
4441f427 234) diter->iter = res;
4441f427 235) trace_printf_key(&trace_refs, "ref_iterator_begin: %s (0x%x)\n", prefix, flags);
4441f427 236) return &diter->base;
4441f427 239) static int debug_read_raw_ref(struct ref_store *ref_store, const char *refname,
4441f427 243) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 244) int res = 0;
4441f427 246) oidcpy(oid, &null_oid);
4441f427 247) res = drefs->refs->be->read_raw_ref(drefs->refs, refname, oid, referent,
4441f427 250) if (res == 0) {
4441f427 251) trace_printf_key(&trace_refs, "read_raw_ref: %s: %s (=> %s) type %x: %d\n",
4441f427 254) trace_printf_key(&trace_refs, "read_raw_ref: %s: %d\n", refname, res);
4441f427 256) return res;
4441f427 260) debug_reflog_iterator_begin(struct ref_store *ref_store)
4441f427 262) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 263) struct ref_iterator *res =
4441f427 264) drefs->refs->be->reflog_iterator_begin(drefs->refs);
4441f427 265) trace_printf_key(&trace_refs, "for_each_reflog_iterator_begin\n");
4441f427 266) return res;
4441f427 275) static int debug_print_reflog_ent(struct object_id *old_oid,
4441f427 280) struct debug_reflog *dbg = (struct debug_reflog *)cb_data;
4441f427 282) char o[GIT_MAX_HEXSZ + 1] = "null";
4441f427 283) char n[GIT_MAX_HEXSZ + 1] = "null";
4441f427 284) if (old_oid)
4441f427 285) oid_to_hex_r(o, old_oid);
4441f427 286) if (new_oid)
4441f427 287) oid_to_hex_r(n, new_oid);
4441f427 289) ret = dbg->fn(old_oid, new_oid, committer, timestamp, tz, msg,
4441f427 291) trace_printf_key(&trace_refs, "reflog_ent %s (ret %d): %s -> %s, %s %ld \"%s\"\n",
4441f427 293) return ret;
4441f427 296) static int debug_for_each_reflog_ent(struct ref_store *ref_store,
4441f427 300) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 301) struct debug_reflog dbg = {
4441f427 307) int res = drefs->refs->be->for_each_reflog_ent(
4441f427 309) trace_printf_key(&trace_refs, "for_each_reflog: %s: %d\n", refname, res);
4441f427 310) return res;
4441f427 313) static int debug_for_each_reflog_ent_reverse(struct ref_store *ref_store,
4441f427 318) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 319) struct debug_reflog dbg = {
4441f427 324) int res = drefs->refs->be->for_each_reflog_ent_reverse(
4441f427 326) trace_printf_key(&trace_refs, "for_each_reflog_reverse: %s: %d\n", refname, res);
4441f427 327) return res;
4441f427 330) static int debug_reflog_exists(struct ref_store *ref_store, const char *refname)
4441f427 332) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 333) int res = drefs->refs->be->reflog_exists(drefs->refs, refname);
4441f427 334) trace_printf_key(&trace_refs, "reflog_exists: %s: %d\n", refname, res);
4441f427 335) return res;
4441f427 338) static int debug_create_reflog(struct ref_store *ref_store, const char *refname,
4441f427 341) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 342) int res = drefs->refs->be->create_reflog(drefs->refs, refname,
4441f427 344) trace_printf_key(&trace_refs, "create_reflog: %s: %d\n", refname, res);
4441f427 345) return res;
4441f427 348) static int debug_delete_reflog(struct ref_store *ref_store, const char *refname)
4441f427 350) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 351) int res = drefs->refs->be->delete_reflog(drefs->refs, refname);
4441f427 352) trace_printf_key(&trace_refs, "delete_reflog: %s: %d\n", refname, res);
4441f427 353) return res;
4441f427 356) static int debug_reflog_expire(struct ref_store *ref_store, const char *refname,
4441f427 363) struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
4441f427 364) int res = drefs->refs->be->reflog_expire(drefs->refs, refname, oid,
4441f427 368) trace_printf_key(&trace_refs, "reflog_expire: %s: %d\n", refname, res);
4441f427 369) return res;

Hariom Verma	b82445dc ref-filter: support different email formats
ref-filter.c
b82445dc 398) return strbuf_addf_ret(err, -1, _("unrecognized email option: %s"), arg);
b82445dc 1087) eoemail = strchr(email, '>');

Hariom Verma	e7601eb5 ref-filter: modify error messages in `grab_objectname()`
ref-filter.c
e7601eb5 384) return strbuf_addf_ret(err, -1, _("unrecognized argument '%s' in %%(%s)"), arg, atom->name);

Hariom Verma	2c22e102 ref-filter: 'contents:trailers' show error if `:` is missing
ref-filter.c
2c22e102 356) return -1;

Hariom Verma	905f0a4e ref-filter: add `sanitize` option for 'subject' atom
ref-filter.c
905f0a4e 309) return strbuf_addf_ret(err, -1, _("unrecognized %%(subject) argument: %s"), arg);

Hariom Verma	47d4676a pretty: refactor `format_sanitized_subject()`
pretty.c
47d4676a 857) i++;

Hariom Verma	26bc0aaf ref-filter: add `short` modifier to 'parent' atom
ref-filter.c
26bc0aaf 1023) struct object_id *oid = &parents->item->object.oid;
26bc0aaf 1026) strbuf_addstr(&s, do_grab_oid("parent", oid, &used_atom[i]));

Jacob Keller	7efba5fa format-patch: teach format.useAutoBase "whenAble" option
builtin/log.c
7efba5fa 1505) if (die_on_failure)
7efba5fa 1524) if (die_on_failure)
7efba5fa 1529) return NULL;
7efba5fa 1547) if (die_on_failure) {
7efba5fa 1550) free(rev);
7efba5fa 1551) return NULL;
7efba5fa 1567) free(rev);
7efba5fa 1568) return NULL;
7efba5fa 1577) free(rev);
7efba5fa 1578) return NULL;

Jacob Keller	c0192df6 refspec: add support for negative refspecs
refspec.c
c0192df6 45) return 0;
c0192df6 87) return 0; /* negative refspecs must not be empty */
c0192df6 93) return 0;

remote.c
c0192df6 812) return -1;

Jeff King	f5e3c0b9 credential-cache: close stderr in daemon process
builtin/credential-cache--daemon.c
f5e3c0b9 216) die_errno("unable to point stderr to /dev/null");

Jeff King	d8410a81 fast-import: replace custom hash with hashmap.c
builtin/fast-import.c
d8410a81 60) e2 = container_of(entry_or_key, const struct object_entry, ent);
d8410a81 61) return oidcmp(&e1->idx.oid, &e2->idx.oid);

Jeff King	c33ddc2e date: use strbufs in date-formatting functions
builtin/fast-import.c
c33ddc2e 1977) datestamp(&ident);

Jeff King	22f9b7f3 strvec: convert builtin/ callers away from argv_array name
builtin/am.c
22f9b7f3 1697) strvec_push(&cp.args, am_path(state, "patch"));

builtin/bisect--helper.c
22f9b7f3 228) strvec_clear(&argv);

builtin/bundle.c
22f9b7f3 89) strvec_push(&pack_opts, "--progress");
22f9b7f3 91) strvec_push(&pack_opts, "--all-progress");
22f9b7f3 93) strvec_push(&pack_opts, "--all-progress-implied");

builtin/clone.c
22f9b7f3 832) strvec_push(&args, "--progress");

builtin/describe.c
22f9b7f3 604) strvec_push(&args, "--always");

builtin/fetch.c
22f9b7f3 1562) strvec_push(argv, "-v");

builtin/gc.c
22f9b7f3 580) strvec_push(&repack, "-f");
22f9b7f3 582) strvec_pushf(&repack, "--depth=%d", aggressive_depth);
22f9b7f3 584) strvec_pushf(&repack, "--window=%d", aggressive_window);

builtin/pull.c
22f9b7f3 534) strvec_push(&args, opt_progress);
22f9b7f3 540) strvec_push(&args, opt_append);
22f9b7f3 542) strvec_push(&args, opt_upload_pack);
22f9b7f3 547) strvec_push(&args, opt_prune);
22f9b7f3 557) strvec_push(&args, "--recurse-submodules=on-demand");
22f9b7f3 563) strvec_push(&args, max_children);
22f9b7f3 567) strvec_push(&args, opt_keep);
22f9b7f3 571) strvec_push(&args, opt_unshallow);
22f9b7f3 573) strvec_push(&args, opt_update_shallow);
22f9b7f3 575) strvec_push(&args, opt_refmap);
22f9b7f3 577) strvec_push(&args, opt_ipv4);
22f9b7f3 579) strvec_push(&args, opt_ipv6);
22f9b7f3 581) strvec_push(&args, "--show-forced-updates");
22f9b7f3 583) strvec_push(&args, "--no-show-forced-updates");
22f9b7f3 672) strvec_push(&args, opt_progress);
22f9b7f3 676) strvec_push(&args, opt_diffstat);
22f9b7f3 682) strvec_push(&args, opt_squash);
22f9b7f3 684) strvec_push(&args, opt_commit);
22f9b7f3 686) strvec_push(&args, opt_edit);
22f9b7f3 688) strvec_pushf(&args, "--cleanup=%s", cleanup_arg);
22f9b7f3 696) strvec_push(&args, opt_gpg_sign);
22f9b7f3 877) strvec_push(&args, "--rebase-merges");
22f9b7f3 883) strvec_push(&args, opt_diffstat);
22f9b7f3 887) strvec_push(&args, opt_gpg_sign);
22f9b7f3 889) strvec_push(&args, "--no-autostash");

builtin/rebase.c
22f9b7f3 826) strvec_push(&am.args, opts->gpg_sign_opt);
22f9b7f3 861) strvec_clear(&am.args);
22f9b7f3 872) strvec_split(&format_patch.args,
22f9b7f3 883) strvec_clear(&am.args);
22f9b7f3 905) strvec_clear(&am.args);
22f9b7f3 914) strvec_push(&am.args, "--rerere-autoupdate");
22f9b7f3 916) strvec_push(&am.args, "--no-rerere-autoupdate");
22f9b7f3 918) strvec_push(&am.args, opts->gpg_sign_opt);

builtin/receive-pack.c
22f9b7f3 782) strvec_pushf(&proc->env_array,
22f9b7f3 826) strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT");
22f9b7f3 2202) strvec_push(&child.args, "--show-resolving-progress");

builtin/remote.c
22f9b7f3 1467) strvec_push(&fetch_argv, "-v");

builtin/repack.c
22f9b7f3 162) strvec_pushf(&cmd->args, "--window=%s", args->window);
22f9b7f3 164) strvec_pushf(&cmd->args, "--window-memory=%s", args->window_memory);
22f9b7f3 166) strvec_pushf(&cmd->args, "--depth=%s", args->depth);
22f9b7f3 168) strvec_pushf(&cmd->args, "--threads=%s", args->threads);
22f9b7f3 170) strvec_pushf(&cmd->args, "--max-pack-size=%s", args->max_pack_size);
22f9b7f3 174) strvec_pushf(&cmd->args, "--no-reuse-object");

builtin/replace.c
22f9b7f3 234) strvec_push(&cmd.args, type_name(type));

builtin/submodule--helper.c
22f9b7f3 859) strvec_push(&cpr.args, "--quiet");
22f9b7f3 1454) strvec_push(&cpr.args, "--quiet");
22f9b7f3 2147) strvec_push(&child->args, "--progress");
22f9b7f3 2151) strvec_pushl(&child->args, "--prefix", suc->prefix, NULL);

builtin/worktree.c
22f9b7f3 626) strvec_push(&cp.args, "--quiet");

Jeff King	47beb37b shortlog: match commit trailers with --group
builtin/shortlog.c
47beb37b 243) return;

Jeff King	fe4a0a28 argv-array: add pop function
strvec.c
fe4a0a28 63) return;

Jeff King	f17b0b99 shortlog: de-duplicate trailer values
builtin/shortlog.c
f17b0b99 194) b = container_of(entry_or_key, const struct strset_item, ent);
f17b0b99 195) return strcmp(a->value, b->value);

Jeff King	63d24fa0 shortlog: allow multiple groups to be specified
builtin/shortlog.c
63d24fa0 303)     !strset_check_and_add(&dups, ident.buf))

Jeff King	01968302 fast-import: delay creating leading directories for export-marks
builtin/fast-import.c
01968302 1692) failure |= error_errno("unable to create leading directories of %s",
01968302 1694) return;

Jeff King	ec91ffca verify_repository_format(): complain about new extensions in v0 repo
setup.c
ec91ffca 472) return config_error_nonbool(var);
ec91ffca 517) return -1;
ec91ffca 526) return -1;

Jeff King	fcd12db6 prefer git_pathdup to git_path in some possibly-dangerous cases
builtin/fast-import.c
fcd12db6 321) free(loc);

Jeff King	d70a9eb6 strvec: rename struct fields
daemon.c
d70a9eb6 495) strvec_pushv(&cld.env_array, env->v);

run-command.c
d70a9eb6 852) execve(argv.v[0], (char *const *) argv.v,

t/helper/test-run-command.c
d70a9eb6 251) arg_offset = args.nr;
d70a9eb6 278) cp.argv = args.v;
d70a9eb6 284) const char *arg = args.v[j + arg_offset];
d70a9eb6 301) (int)j, args.v[j + arg_offset]);

Jeff King	8d2aa8df assert PARSE_OPT_NONEG in parse-options callbacks
parse-options-cb.c
8d2aa8df 108) BUG_ON_OPT_NEG(unset);

Jeff King	b992657e argv-array: add detach function
strvec.c
b992657e 103) return xcalloc(1, sizeof(const char *));

Jeff King	3c078b9c fast-import: clean up pack_data pointer in end_packfile
builtin/fast-import.c
3c078b9c 844) return;

Jeff King	ef8d7ac4 strvec: convert more callers away from argv_array name
column.c
ef8d7ac4 372) strvec_pushf(argv, "--width=%d", opts->width);
ef8d7ac4 374) strvec_pushf(argv, "--indent=%s", opts->indent);

compat/terminal.c
ef8d7ac4 276) strvec_pushl(&cp.args, "infocmp", "-L", "-1", NULL);

connect.c
ef8d7ac4 1236) strvec_push(args, "-6");

daemon.c
ef8d7ac4 490) static int upload_archive(const struct strvec *env)
ef8d7ac4 493) strvec_push(&cld.args, "upload-archive");
ef8d7ac4 803) strvec_clear(&env);
ef8d7ac4 924) strvec_pushf(&cld.env_array, "REMOTE_ADDR=[%s]", buf);
ef8d7ac4 925) strvec_pushf(&cld.env_array, "REMOTE_PORT=%d",

exec-cmd.c
ef8d7ac4 342) strvec_clear(&nargv);

imap-send.c
ef8d7ac4 979) strvec_push(&tunnel.args, srvc->tunnel);

Jeff King	957876f1 combine-diff: handle --find-object in multitree code path
combine-diff.c
957876f1 1464) return 0;
957876f1 1482) free(p);

Jeff King	e2770979 credentials: add "cache" helper
builtin/credential-cache--daemon.c
e2770979 89) return 0;
e2770979 113) return -1;
e2770979 169) return 0;
e2770979 174) if (errno != EINTR)
e2770979 175) die_errno("poll failed");
e2770979 176) return 1;
e2770979 186) return 1;
e2770979 191) close(client);
e2770979 192) return 1;
e2770979 210) die_errno("unable to bind to '%s'", socket_path);
e2770979 222) close(fd);
e2770979 223) }
e2770979 299) return 0;

builtin/credential-cache.c
e2770979 23) die_errno("unable to write to cache daemon");
e2770979 34) die_errno("read error from cache daemon");
e2770979 56) die_errno("unable to start cache daemon");
e2770979 59) die_errno("unable to read result code from cache daemon");
e2770979 74) die_errno("unable to relay credential");

Jeff King	6479ea4a xrealloc: do not reuse pointer freed by zero-length realloc()
wrapper.c
6479ea4a 121) free(ptr);
6479ea4a 122) return xmalloc(0);

Jeff King	f0939a0e trailer: add interface for iterating over commit trailers
trailer.c
f0939a0e 1204) continue; /* not a real trailer */

Jeff King	ae021d87 use skip_prefix to avoid magic numbers
builtin/fast-import.c
ae021d87 3337) if (!git_parse_ulong(option, &v))

Jeff King	8ec6c8d7 credential-cache: report more daemon connection errors
builtin/credential-cache.c
8ec6c8d7 83) die_errno("unable to connect to cache daemon");

Jeff King	71e1b4b6 credentials: add "store" helper
builtin/credential-store.c
71e1b4b6 22) die_errno("unable to open %s", fn);
71e1b4b6 62) die_errno("unable to get credential storage lock");

Jeff King	c972bf4c strvec: convert remaining callers away from argv_array name
midx.c
c972bf4c 1441) strvec_push(&cmd.args, "--delta-islands");

pager.c
c972bf4c 71) static void setup_pager_env(struct strvec *env)
c972bf4c 91) strvec_push(env, argv[i]);
c972bf4c 100) strvec_push(&pager_process->args, pager);
c972bf4c 129) strvec_push(&pager_process.env_array, "GIT_PAGER_IN_USE");

remote-curl.c
c972bf4c 1157) strvec_pushl(&args, "-v", "-v", NULL);
c972bf4c 1163) strvec_push(&args, "--update-shallow");
c972bf4c 1169) strvec_pushf(&args, "--shallow-since=%s", options.deepen_since);
c972bf4c 1171) strvec_pushf(&args, "--shallow-exclude=%s",
c972bf4c 1174) strvec_push(&args, "--deepen-relative");
c972bf4c 1176) strvec_push(&args, "--from-promisor");
c972bf4c 1178) strvec_pushf(&args, "--filter=%s", options.filter);
c972bf4c 1274) strvec_push(&child.args, "--dry-run");
c972bf4c 1302) strvec_push(&args, "--dry-run");
c972bf4c 1306) strvec_push(&args, "--signed=if-asked");
c972bf4c 1310) strvec_push(&args, "--quiet");

sequencer.c
c972bf4c 3680) strvec_push(&cmd.args, opts->gpg_sign);

submodule.c
c972bf4c 690) strvec_pushf(&cp.args, "--src-prefix=%s%s/",
c972bf4c 692) strvec_pushf(&cp.args, "--dst-prefix=%s%s/",
c972bf4c 1790) strvec_push(&cp.args, "-uno");
c972bf4c 1795) strvec_push(&cp.args, "--ignored");

t/helper/test-run-command.c
c972bf4c 75) strvec_pushl(&cp->args, "sh", test, NULL);
c972bf4c 77) strvec_push(&cp->args, "--quiet");
c972bf4c 79) strvec_push(&cp->args, "-i");
c972bf4c 81) strvec_push(&cp->args, "-v");
c972bf4c 83) strvec_push(&cp->args, "-V");
c972bf4c 85) strvec_push(&cp->args, "-x");
c972bf4c 87) strvec_push(&cp->args, "--write-junit-xml");
c972bf4c 223) struct strvec args = STRVEC_INIT;
c972bf4c 244) strvec_clear(&args);
c972bf4c 246) strvec_pushl(&args, "sh", "-c",
c972bf4c 249) strvec_pushl(&args, "test-tool", "run-command",
c972bf4c 257) strvec_push(&args, argv[j]);
c972bf4c 271) strvec_push(&args, buf);
c972bf4c 304) strvec_clear(&args);
c972bf4c 314) strvec_clear(&args);
c972bf4c 341) strvec_pushl(&cp.args,

tmp-objdir.c
c972bf4c 102) strvec_pushf(env, "%s=%s%c%s", key, old, PATH_SEP, val);

transport-helper.c
c972bf4c 448) strvec_pushf(&fastimport->args, "--cat-blob-fd=%d", cat_blob_fd);

upload-pack.c
c972bf4c 309) strvec_pushf(&pack_objects.args, "--filter=%s", buf.buf);

Jeff King	fbff95b6 index-pack: adjust default threading cap
builtin/index-pack.c
fbff95b6 1855) else if (nr_threads < 6)
fbff95b6 1856) nr_threads = 3; /* historic cap */
fbff95b6 1857) else if (nr_threads < 40)
fbff95b6 1858) nr_threads /= 2;
fbff95b6 1860) nr_threads = 20; /* hard cap */

Jeff King	e885a84f drop unused argc parameters
t/helper/test-submodule-nested-repo-config.c
e885a84f 4) static void die_usage(const char **argv, const char *msg)
e885a84f 17) die_usage(argv, "Wrong number of arguments.");
e885a84f 23) die_usage(argv, "Submodule not found.");

Jeff King	f6d8942b strvec: fix indentation in renamed calls
builtin/rebase.c
f6d8942b 873)      opts->git_format_patch_opt.buf);

daemon.c
f6d8942b 926)      ntohs(sin6_addr->sin6_port));

remote-curl.c
f6d8942b 1172)      options.deepen_not.items[i].string);

Jiang Xin	63518a57 New capability "report-status-v2" for git-push
send-pack.c
63518a57 183) if (!once++)
63518a57 185) ret = -1;
63518a57 186) continue;
63518a57 223) ret = -1;
63518a57 224) break;
63518a57 241)     hint->status != REF_STATUS_OK &&
63518a57 242)     hint->status != REF_STATUS_REMOTE_REJECT) {
63518a57 440) else if (server_supports("report-status"))

transport-helper.c
63518a57 839) state->hint = find_ref_by_name(remote_refs, refname);
63518a57 895) continue;
63518a57 900) for (report = ref->report; report; report = report->next) {
63518a57 901) private = apply_refspecs(&data->rs,
63518a57 902)  report->ref_name
63518a57 905) if (!private)
63518a57 906) continue;
63518a57 907) update_ref("update by helper", private,
63518a57 908)    report->new_oid
63518a57 912) free(private);

Jiang Xin	31e8595a receive-pack: new config receive.procReceiveRefs
builtin/receive-pack.c
31e8595a 246) return config_error_nonbool(var);
31e8595a 394) return 0;
31e8595a 1911) continue;

Jiang Xin	15d3af5e receive-pack: add new proc-receive hook
builtin/receive-pack.c
15d3af5e 1124) return code;
15d3af5e 1132) if (use_sideband)
15d3af5e 1133) finish_async(&muxer);
15d3af5e 1134) return code;

t/helper/test-proc-receive.c
15d3af5e 136) usage_msg_opt("Too many arguments.", proc_receive_usage, options);

Jim Meyering	5a7b1b57 fast-import: Don't use a maybe-clobbered errno value
builtin/fast-import.c
5a7b1b57 1705) int saved_errno = errno;

Johan Herland	a8dd2e7d fast-import: Add support for importing commit notes
builtin/fast-import.c
a8dd2e7d 2504) if (type < 0)
a8dd2e7d 2506) if (type != OBJ_BLOB)

Johannes Schindelin	40db58b8 fast-import: Fix compile warnings
builtin/fast-import.c
40db58b8 1892) (unsigned long)(length - n));

Johannes Schindelin	c5aa6db6 argv_array: offer to split a string by whitespace
strvec.c
c5aa6db6 72) to_split++;

Jon Griffiths	a6e5e286 credential-cache--daemon: refactor check_socket_directory
builtin/credential-cache--daemon.c
a6e5e286 247) die_errno("unable to create directories for '%s'", dir);
a6e5e286 249) die_errno("unable to mkdir '%s'", dir);

Jonathan Nieder	dc01f59d fast-import: treat SIGUSR1 as a request to access objects early
builtin/fast-import.c
dc01f59d 430) static void checkpoint_signal(int signo)
dc01f59d 432) checkpoint_requested = 1;
dc01f59d 433) }

Jonathan Nieder	5edde510 fast-import: filemodify after M 040000 <tree> "" crashes
builtin/fast-import.c
5edde510 1495) load_tree(root);

Jonathan Nieder	c27e559d fast-import: leakfix for 'ls' of dirty trees
builtin/fast-import.c
c27e559d 3182) release_tree_content_recursive(leaf.tree);

Jonathan Tan	f08cbf60 index-pack: make quantum of work smaller
builtin/index-pack.c
f08cbf60 424) list_for_each_prev(pos, &done_head) {
f08cbf60 425) struct base_data *b = list_entry(pos, struct base_data, list);
f08cbf60 426) if (b->retain_data || b == retain)
f08cbf60 427) continue;
f08cbf60 428) if (b->data) {
f08cbf60 429) free_base_data(b);
f08cbf60 430) if (base_cache_used <= base_cache_limit)
f08cbf60 431) return;
f08cbf60 435) list_for_each_prev(pos, &work_head) {
f08cbf60 436) struct base_data *b = list_entry(pos, struct base_data, list);
f08cbf60 437) if (b->retain_data || b == retain)
f08cbf60 438) continue;
f08cbf60 439) if (b->data) {
f08cbf60 440) free_base_data(b);
f08cbf60 441) if (base_cache_used <= base_cache_limit)
f08cbf60 442) return;
f08cbf60 925) base_cache_used += c->size;
f08cbf60 941) base_cache_used += c->size;

Jonathan Tan	ee47243d pack-objects: no fetch when allow-{any,promisor}
builtin/pack-objects.c
ee47243d 3065) if (!has_object(the_repository, &obj->oid, 0) && is_promisor_object(&obj->oid))

Jonathan Tan	f24c30e0 wt-status: tolerate dangling marks
builtin/show-branch.c
f24c30e0 744) if (!dwim_ref(*av, strlen(*av), &oid, &ref, 0))

Jonathan Tan	1d8d9cb6 sha1-file: introduce no-lazy-fetch has_object()
sha1-file.c
1d8d9cb6 2000) return 0;

Jonathan Tan	7ca3c0ac promisor-remote: lazy-fetch objects in subprocess
promisor-remote.c
7ca3c0ac 35) die_errno(_("promisor-remote: could not write to fetch subprocess"));
7ca3c0ac 37) die_errno(_("promisor-remote: could not write to fetch subprocess"));
7ca3c0ac 41) die_errno(_("promisor-remote: could not close stdin to fetch subprocess"));

Jonathan Tan	cbe566a0 negotiator/noop: add noop fetch negotiator
negotiator/noop.c
cbe566a0 6) static void known_common(struct fetch_negotiator *n, struct commit *c)
cbe566a0 9) }
cbe566a0 21) static int ack(struct fetch_negotiator *n, struct commit *c)

Jonathan Tan	5c3b801d fetch-pack: do not lazy-fetch during ref iteration
fetch-pack.c
5c3b801d 126) return NULL;

Jonathan Tan	e5b94213 fetch: avoid reading submodule config until needed
submodule-config.c
e5b94213 780) if (config->max_children)
e5b94213 781) *(config->max_children) =
e5b94213 782) parse_submodule_fetchjobs(var, value);
e5b94213 785) if (config->recurse_submodules)
e5b94213 786) *(config->recurse_submodules) =
e5b94213 787) parse_fetch_recurse_submodules_arg(var, value);

Junio C Hamano	6c526148 csum-file: introduce sha1file_checkpoint
builtin/fast-import.c
6c526148 1157) truncate_pack(&checkpoint);

Junio C Hamano	e0ad9574 Merge branch 'bc/sha-256-part-3'
builtin/verify-pack.c
e0ad9574 22) strvec_push(argv, "--verify-stat-only");

setup.c
e0ad9574 497) return config_error_nonbool(var);

Junio C Hamano	6854689e Merge branch 'ar/fetch-ipversion-in-all'
builtin/fetch.c
6854689e 1568) strvec_push(argv, "--ipv4");
6854689e 1570) strvec_push(argv, "--ipv6");

Junio C Hamano	ebcfb379 write_idx_file: introduce a struct to hold idx customization options
builtin/fast-import.c
ebcfb379 3455) if (pack_idx_opts.version > 2)

Junio C Hamano	9ed104e5 ident: say whose identity is missing when giving user.name hint
ident.c
9ed104e5 359) break;
9ed104e5 401) ident_env_hint(whose_ident);
9ed104e5 418) ident_env_hint(whose_ident);
9ed104e5 424) ident_env_hint(whose_ident);

Junio C Hamano	55bb5c91 zlib: wrap deflate side of the API
builtin/fast-import.c
55bb5c91 997) git_deflate_init(&s, pack_compression_level);
55bb5c91 1002) while (git_deflate(&s, Z_FINISH) == Z_OK)
55bb5c91 1004) git_deflate_end(&s);

Junio C Hamano	76ea93cc fast-import.c: Fix big-file-threshold parsing bug
builtin/fast-import.c
76ea93cc 3350) return 0;

Junio C Hamano	88910c99 quote_path: give flags parameter to quote_path()
builtin/clean.c
88910c99 217) quote_path(path->buf, prefix, &quoted, 0);
88910c99 241) quote_path(path->buf, prefix, &quoted, 0);
88910c99 1057) qname = quote_path(item->string, NULL, &buf, 0);

Junio C Hamano	225a6f10 zlib: wrap deflateBound() too
builtin/fast-import.c
225a6f10 1000) s.avail_out = git_deflate_bound(&s, s.avail_in);

Junio C Hamano	6e6029a8 fmt-merge-msg: allow merge destination to be omitted again
fmt-merge-msg.c
6e6029a8 29) return config_error_nonbool(key);

Junio C Hamano	4d0cc224 fast-import: count --max-pack-size in bytes
builtin/fast-import.c
4d0cc224 3338) return 0;
4d0cc224 3339) if (v < 8192) {
4d0cc224 3341) v *= 1024 * 1024;
4d0cc224 3342) } else if (v < 1024 * 1024) {
4d0cc224 3344) v = 1024 * 1024;
4d0cc224 3346) max_packsize = v;

Lin Sun	dbd8c09b mergetool: allow auto-merge for meld to follow the vim-diff behavior
builtin/config.c
dbd8c09b 99) new_type = TYPE_BOOL_OR_STR;
dbd8c09b 258) int v = git_parse_maybe_bool(value_);
dbd8c09b 259) if (v < 0)
dbd8c09b 260) strbuf_addstr(buf, value_);
dbd8c09b 262) strbuf_addstr(buf, v ? "true" : "false");
dbd8c09b 425) int v = git_parse_maybe_bool(value);
dbd8c09b 426) if (v < 0)
dbd8c09b 427) return xstrdup(value);
dbd8c09b 429) return xstrdup(v ? "true" : "false");

Martin Ågren	8f7e3de0 wt-status: print to s->fp, not stdout
wt-status.c
8f7e3de0 1859) fprintf(s->fp, " %s%c", it->string, 0);

Matheus Tavares	bda959c4 packfile: fix memory leak in add_delta_base_cache()
packfile.c
bda959c4 1487) free(base);

Michael Forney	ea3f7e59 revision: use repository from rev_info when parsing commits
revision.c
ea3f7e59 1058) if (repo_parse_commit(revs->repo, p) < 0)

Michael Haggerty	9e903316 credential-cache--daemon: use tempfile module
builtin/credential-cache--daemon.c
9e903316 297) delete_tempfile(&socket_file);

Mike Hommey	0df32457 fast-import: do less work when given "from" matches current branch head
builtin/fast-import.c
0df32457 2600) release_tree_content_recursive(b->branch_tree.tree);
0df32457 2601) b->branch_tree.tree = NULL;

Miriam Rubio	7b4de74b bisect--helper: introduce new `write_in_file()` function
builtin/bisect--helper.c
7b4de74b 97) return error_errno(_("cannot open file '%s' in mode '%s'"), path, mode);
7b4de74b 101) int saved_errno = errno;
7b4de74b 102) fclose(fp);
7b4de74b 103) errno = saved_errno;
7b4de74b 104) return error_errno(_("could not write to file '%s'"), path);

Nguyễn Thái Ngọc Duy	26604f9f credential-cache--daemon.c: use warning_errno()
builtin/credential-cache--daemon.c
26604f9f 185) warning_errno("accept failed");
26604f9f 190) warning_errno("dup failed");

Nguyễn Thái Ngọc Duy	d3b4705a sha1-file.c: remove the_repo from read_object_with_reference()
builtin/fast-import.c
d3b4705a 2648) char *buf = read_object_with_reference(the_repository,
d3b4705a 2649)        &n->oid,

Nguyễn Thái Ngọc Duy	6c223e49 fast-import.c: use error_errno()
builtin/fast-import.c
6c223e49 320) error_errno("can't write crash report %s", loc);
6c223e49 1698) failure |= error_errno("Unable to write marks file %s",
6c223e49 1714) failure |= error_errno("Unable to write file %s",

Nicolas Pitre	3fc366bd fast-import: start using struct pack_idx_entry
builtin/fast-import.c
3fc366bd 1155) e->idx.offset = 1; /* just not zero! */

Noam Postavsky	7f4d4746 credential-cache: new option to ignore sighup
builtin/credential-cache--daemon.c
7f4d4746 294) signal(SIGHUP, SIG_IGN);

Paul Tan	cb2c2796 git-credential-store: support multiple credential files
builtin/credential-store.c
cb2c2796 103) return;
cb2c2796 131) return;
cb2c2796 170) string_list_append(&fns, file);

Phillip Wood	a3894aad rebase -i: support --ignore-date
sequencer.c
a3894aad 1448) goto out;
a3894aad 1453) goto out;
a3894aad 1479) goto out;

Phillip Wood	7573cec5 rebase -i: support --committer-date-is-author-date
sequencer.c
7573cec5 4498) return -1;
7573cec5 5395) goto cleanup;

Phillip Wood	ce910287 add -p: fix checking of user input
add-patch.c
ce910287 1508) if (permitted & ALLOW_GOTO_PREVIOUS_HUNK)
ce910287 1513) if (permitted & ALLOW_GOTO_NEXT_HUNK)
ce910287 1518) if (permitted & ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK)
ce910287 1523) if (permitted & ALLOW_GOTO_NEXT_UNDECIDED_HUNK)

Phillip Wood	75a009dc add -p: fix editing of intent-to-add paths
add-patch.c
75a009dc 1398) undecided_previous = i;
75a009dc 1399) break;
75a009dc 1421) permitted |= ALLOW_GOTO_PREVIOUS_UNDECIDED_HUNK;
75a009dc 1422) strbuf_addstr(&s->buf, ",k");
75a009dc 1484) if (file_diff->hunk_nr) {
75a009dc 1485) for (; hunk_index < file_diff->hunk_nr; hunk_index++) {
75a009dc 1486) hunk = file_diff->hunk + hunk_index;
75a009dc 1487) if (hunk->use == UNDECIDED_HUNK)
75a009dc 1488) hunk->use = USE_HUNK;
75a009dc 1490) } else if (hunk->use == UNDECIDED_HUNK) {
75a009dc 1491) hunk->use = USE_HUNK;
75a009dc 1500) } else if (hunk->use == UNDECIDED_HUNK) {
75a009dc 1501) hunk->use = SKIP_HUNK;

Pierre Habouzit	eec813cf fast-import was using dbuf's, replace them with strbuf's.
builtin/fast-import.c
eec813cf 998) s.next_in = (void *)dat->buf;
eec813cf 999) s.avail_in = dat->len;

Pranit Bauva	517ecb31 bisect--helper: reimplement `bisect_next` and `bisect_auto_next` shell functions in C
builtin/bisect--helper.c
517ecb31 529) return res;
517ecb31 533) return error_errno(_("could not open '%s' for appending"),
517ecb31 537) return error_errno(_("failed to write to '%s'"), git_path_bisect_log());
517ecb31 586) return BISECT_FAILED;

Pranit Bauva	09535f05 bisect--helper: reimplement `bisect_autostart` shell function in C
builtin/bisect--helper.c
09535f05 827) fprintf_ln(stderr, _("You need to start by \"git bisect "
09535f05 830) if (!isatty(STDIN_FILENO))
09535f05 831) return -1;
09535f05 838) yesno = git_prompt(_("Do you want me to do it for you "
09535f05 840) res = tolower(*yesno) == 'n' ?
09535f05 841) -1 : bisect_start(terms, empty_strvec, 0);
09535f05 843) return res;

Prathamesh Chavan	e83e3333 submodule: port submodule subcommand 'summary' from shell to C
builtin/submodule--helper.c
e83e3333 1091) missing_dst = 1;
e83e3333 1142) strbuf_addf(&errmsg_str, "  Warn: %s doesn't contain commits %s and %s\n",
e83e3333 1143)     displaypath, oid_to_hex(&p->oid_src),
e83e3333 1144)     oid_to_hex(&p->oid_dst));
e83e3333 1149)     oid_to_hex(&p->oid_dst));
e83e3333 1271) return -1;
e83e3333 1275) return -1;
e83e3333 1319) return 0;

Randall S. Becker	f64b6a1f bugreport.c: replace strbuf_write_fd with write_in_full
builtin/bugreport.c
f64b6a1f 178) die_errno(_("unable to write to %s"), report_path.buf);

René Scharfe	24b75faf connected: use buffered I/O to talk to rev-list
connected.c
24b75faf 143) if (errno != EPIPE && errno != EINVAL)
24b75faf 144) error_errno(_("failed write to rev-list"));
24b75faf 145) err = -1;

René Scharfe	bcd2c5ee read-cache: fix mem-pool allocation for multi-threaded index loading
read-cache.c
bcd2c5ee 2104) p->ce_mem_pool = xmalloc(sizeof(*istate->ce_mem_pool));

René Scharfe	2947a793 archive: add --add-file
archive.c
2947a793 345) err = error_errno(_("could not read '%s'"), path);
2947a793 352) break;
2947a793 513) string_list_clear_func(&args->extra_files,
2947a793 515) return 0;
2947a793 519) return -1;

René Scharfe	a698d67b upload-pack: use buffered I/O to talk to rev-list
upload-pack.c
a698d67b 661) if (cmd_in)
a698d67b 662) fclose(cmd_in);

Ronnie Sahlberg	3f09ba75 fast-import.c: use a ref transaction when dumping tags
builtin/fast-import.c
3f09ba75 1662) goto cleanup;
3f09ba75 1671) goto cleanup;

Ronnie Sahlberg	de7e86f5 fast-import.c: change update_branch to use ref transactions
builtin/fast-import.c
de7e86f5 1630) ref_transaction_free(transaction);
de7e86f5 1632) strbuf_release(&err);
de7e86f5 1633) return -1;

Ryan Zoeller	a0abe5e3 parse-options: add --git-completion-helper-all
parse-options.c
a0abe5e3 736) return show_gitcomp(options, 1);

Sergey Organov	d01141de diff: get rid of redundant 'dense' argument
diff-lib.c
d01141de 362) show_combined_diff(p, 2, revs);

Shawn O. Pearce	d9ee53ce Implemented automatic checkpoints within fast-import.
builtin/fast-import.c
d9ee53ce 990) e->pack_id = pack_id + 1;
d9ee53ce 994) if (delta) {

Shawn O. Pearce	820b9310 Dump all refs and marks during a checkpoint in fast-import.
builtin/fast-import.c
820b9310 991) cycle_packfile();

Shawn O. Pearce	60b9004c Use atomic updates to the fast-import mark file
builtin/fast-import.c
60b9004c 1700) return;
60b9004c 1706) rollback_lock_file(&mark_lock);
60b9004c 1709) return;

Shawn O. Pearce	5eef828b fast-import: Stream very large blobs directly to pack
builtin/fast-import.c
5eef828b 1063) die_errno("cannot truncate pack to skip duplicate");
5eef828b 1085) cycle_packfile();
5eef828b 1153) e->type = OBJ_BLOB;
5eef828b 1154) e->pack_id = MAX_PACK_ID;
5eef828b 1156) duplicate_count_by_type[OBJ_BLOB]++;

Shawn O. Pearce	b6f3481b Teach fast-import to recursively copy files/directories
builtin/fast-import.c
b6f3481b 720) return NULL;
b6f3481b 727) b->tree = dup_tree_content(a->tree);
b6f3481b 1576) return 0;
b6f3481b 1582) return 0;

Shawn O. Pearce	afde8dd9 Fixed segfault in fast-import after growing a tree.
builtin/fast-import.c
afde8dd9 1424) release_tree_content_recursive(e->tree);

Shawn O. Pearce	5d6f3ef6 Corrected buffer overflow during automatic checkpoint in fast-import.
builtin/fast-import.c
5d6f3ef6 1001) s.next_out = out = xrealloc(out, s.avail_out);

Shawn O. Pearce	63e0c8b3 Support RFC 2822 date parsing in fast-import.
builtin/fast-import.c
63e0c8b3 1920) return -1;
63e0c8b3 1978) break;

Shawn O. Pearce	463acbe1 Added tree and commit writing to fast-import.
builtin/fast-import.c
463acbe1 640) l->next_avail = f->next_avail;
463acbe1 1227) return NULL;
463acbe1 1456) return 0;
463acbe1 2032) e = active_branches;
463acbe1 2033) active_branches = e->active_next_branch;

Shawn O. Pearce	bdf1c06d fast-import: Hide the pack boundary commits by default.
builtin/fast-import.c
bdf1c06d 891) if (t->pack_id == pack_id)

Shawn O. Pearce	2f6dc35d fast-import: Fail if a non-existant commit is used for merge
builtin/fast-import.c
2f6dc35d 2654) free(buf);

Shawn O. Pearce	8acb3297 Generate crash reports on die in fast-import
builtin/fast-import.c
8acb3297 305) fprintf(rpt, "%u", b->pack_id);
8acb3297 322) return;

Shawn O. Pearce	69e74e74 Correct packfile edge output in fast-import.
builtin/fast-import.c
69e74e74 2860) t->pack_id = MAX_PACK_ID;

Shawn O. Pearce	bb23fdfa Teach fast-import to honor pack.compression and pack.depth
builtin/fast-import.c
bb23fdfa 3450) if (max_depth > MAX_DEPTH)
bb23fdfa 3451) max_depth = MAX_DEPTH;

Stefan Beller	0df8e965 cache.h: add repository argument to oid_object_info
builtin/fast-import.c
0df8e965 2502) enum object_type type = oid_object_info(the_repository, &oid,

Sverre Rabbelier	9c8398f0 fast-import: add option command
builtin/fast-import.c
9c8398f0 3500) usage(fast_import_usage);

Sverre Rabbelier	0f6927c2 fast-import: put option parsing code in separate functions
builtin/fast-import.c
0f6927c2 3284) if (max_depth > MAX_DEPTH)
0f6927c2 3286) }
0f6927c2 3309) fclose(pack_edges);
0f6927c2 3361) show_stats = 1;

SZEDER Gábor	87d01c85 credential-store: don't pass strerror to die_errno()
builtin/credential-store.c
87d01c85 67) die_errno("unable to write credential store");

SZEDER Gábor	17e6275f commit-graph: simplify chunk writes into loop
commit-graph.c
17e6275f 1821) return -1;

Tanay Abhra	536900e5 fast-import.c: replace `git_config()` with `git_config_get_*()` family
builtin/fast-import.c
536900e5 3454) pack_idx_opts.version = indexversion_value;
536900e5 3456) git_die_config("pack.indexversion",
536900e5 3460) max_packsize = packsizelimit_value;

Taylor Blau	809e0327 builtin/commit-graph.c: introduce '--max-new-filters=<n>'
builtin/commit-graph.c
809e0327 175) *to = -1;

Taylor Blau	b9ea2147 list_objects_filter_options: introduce 'list_object_filter_config_name'
list-objects-filter-options.c
b9ea2147 23) break;
b9ea2147 36) break;

Taylor Blau	6dd3456a upload-pack.c: allow banning certain object filter(s)
upload-pack.c
6dd3456a 1078) die_if_using_banned_filter(data);

Taylor Blau	5b01a4e8 upload-pack.c: introduce 'uploadpackfilter.tree.maxDepth'
upload-pack.c
5b01a4e8 1259) strbuf_release(&buf);
5b01a4e8 1260) return config_error_nonbool(var);

Taylor Blau	59f0d507 bloom: encode out-of-bounds filters as non-empty
bloom.c
59f0d507 294) init_truncated_large_filter(filter);

Taylor Blau	ab14d067 commit-graph: pass a 'struct repository *' in more places
fuzz-commit-graph.c
ab14d067 14) g = parse_commit_graph(the_repository, (void *)data, size);

Taylor Blau	98bb7961 commit-graph: rename 'split_commit_graph_opts'
commit-graph.c
98bb7961 2218) ctx->oids.alloc = opts->max_commits;

Taylor Blau	312cff52 bloom: split 'get_bloom_filter()' in two
bloom.c
312cff52 296) if (computed)
312cff52 297) *computed |= BLOOM_TRUNC_LARGE;

Thomas Rast	0721c314 Use die_errno() instead of die() when checking syscalls
builtin/fast-import.c
0721c314 793) die_errno("cannot create keep file");
0721c314 796) die_errno("failed to write keep file");



^ permalink raw reply	[relevance 2%]

* Re: How to checkout a revision that contains a deleted submodule?
  @ 2020-09-21 22:46  7%   ` Philippe Blain
  0 siblings, 0 replies; 200+ results
From: Philippe Blain @ 2020-09-21 22:46 UTC (permalink / raw)
  To: Luke Diamand; +Cc: Git mailing list, Jens Lehmann, kaartic.sivaraam

Hi Luke, 

> Le 20 sept. 2020 à 05:44, Luke Diamand <luke@diamand.org> a écrit :
> 
> On Sat, 19 Sep 2020 at 10:03, Luke Diamand <luke@diamand.org> wrote:
>> 
>> Maybe this is a FAQ, but I couldn't figure it out!
>> 
>> I have a repo which has a couple of submodules.
>> 
>> At some point in the past I deleted one of those submodules:
>> 
>>    git rm sub2
>>    git add -u
>>    git commit -m 'Deleting sub2'
>>    git push origin
>>    ...
>>    ... more commits and pushes...
>> 
>> Now I go and clone the head revision. This gives me a clone which has
>> nothing present in .git/modules/sub2.
>>    login on some other machine
>>    git clone git@my.repo:thing
>>    cd thing
>>    ls .git/modules
>>    <sub2 not present>
>> 
>> So when I go and checkout an old revision where sub2 is still around I get:
>>    git checkout oldrevision
>>    fatal: not a git repository: sub2/../.git/modules/sub2
>> 
>> What am I doing wrong?
>> What set of commands do I need to use to ensure that this will always
>> do the right thing?
>> 
>> Thanks
>> Luke
> 
> Replying to myself, adding Jens who added the section below.
> 
> This is a known bug:
> 
> https://git-scm.com/docs/git-rm
> 
>> BUGS
>> ----
>> Each time a superproject update removes a populated submodule
>> (e.g. when switching between commits before and after the removal) a
>> stale submodule checkout will remain in the old location. Removing the
>> old directory is only safe when it uses a gitfile, as otherwise the
>> history of the submodule will be deleted too. This step will be
>> obsolete when recursive submodule update has been implemented.
> 
> I'm wondering what "recursive submodule update" is. If I do:
> 
>    git submodule update --checkout --force --remote --recursive
> 
> then those stale repos are still left lying around. I guess that's a
> different kind of recursive?
> 

I think Jens was referring to this project :
https://github.com/jlehmann/git-submod-enhancements/wiki/Recursive-submodule-checkout

of which some parts were implemented over the years,
a lot of them by Stefan Beller. 

In fact this part of the doc is stale and should be removed since `git checkout` now 
understands `--recurse-submodules` and will
automatically transform "old-style" subdmodules (i.e. with an embeded .git repository)
into "new style" submodules (with a gitfile) (see gitsubmodules(7), at [1], for more info)
when switching to a commit where the submodule is not present.

Cheers,
Philippe.

^ permalink raw reply	[relevance 7%]

* [GSoC][PATCH] submodule: port submodule subcommand 'add' from shell to C
@ 2020-08-24  9:03 18% Shourya Shukla
  0 siblings, 0 replies; 200+ results
From: Shourya Shukla @ 2020-08-24  9:03 UTC (permalink / raw)
  To: git
  Cc: christian.couder, kaartic.sivaraam, gitster, johannes.schindelin,
	liu.denton, Prathamesh Chavan, Christian Couder, Stefan Beller,
	Shourya Shukla

From: Prathamesh Chavan <pc44800@gmail.com>

Convert submodule subcommand 'add' to a builtin and call it via
'git-submodule.sh'.

Also, since the command die()s out in case of absence of commits in the
submodule and exits with exit status 1 when we try adding a submodule
which is mentioned in .gitignore, the keyword 'fatal' is prefixed in the
error messages. Therefore, prepend the keyword in the expected outputs
of tests t7400.6 and t7400.16.

Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Mentored-by: Stefan Beller <stefanbeller@gmail.com>
Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
---
This is my port of 'git submodule add' from shell to C. I had some
confusion regarding this segment in the shell script:

	if test -z "$force"
	then
		git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
		die "$(eval_gettext "'\$sm_path' already exists in the index")"
	else
		git ls-files -s "$sm_path" | sane_grep -v "^160000" > /dev/null 2>&1 &&
		die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
	fi

This is what I have done in C:

	if (!force) {
		if (is_directory(path) && submodule_from_path(the_repository, &null_oid, path))
			die(_("'%s' already exists in the index"), path);
	} else {
		int err;
		if (index_name_pos(&the_index, path, strlen(path)) >= 0 &&
		    !is_submodule_populated_gently(path, &err))
			die(_("'%s' already exists in the index and is not a "
			      "submodule"), path);
	}

Is this part correct? I am not very sure about this. This particular
part is not covered in any test or test script, so, I do not have a
solid method of knowing the correctness of this segment.
Feedback and reviews are appreciated.
---

 builtin/submodule--helper.c | 371 ++++++++++++++++++++++++++++++++++++
 git-submodule.sh            | 161 +---------------
 t/t7400-submodule-basic.sh  |   5 +-
 3 files changed, 375 insertions(+), 162 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index df135abbf1..b8189822a3 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2320,6 +2320,376 @@ static int module_set_branch(int argc, const char **argv, const char *prefix)
 	return !!ret;
 }
 
+struct add_data {
+	const char *prefix;
+	const char *branch;
+	const char *reference_path;
+	const char *sm_path;
+	const char *sm_name;
+	const char *repo;
+	const char *realrepo;
+	int depth;
+	unsigned int force: 1;
+	unsigned int quiet: 1;
+	unsigned int progress: 1;
+	unsigned int dissociate: 1;
+};
+#define ADD_DATA_INIT { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }
+
+/*
+ * Guess dir name from repository: strip leading '.*[/:]',
+ * strip trailing '[:/]*.git'.
+ */
+static char *guess_dir_name(const char *repo)
+{
+	const char *p, *start, *end, *limit;
+	int after_slash_or_colon;
+
+	after_slash_or_colon = 0;
+	limit = repo + strlen(repo);
+	start = repo;
+	end = limit;
+	for (p = repo; p < limit; p++) {
+		if (starts_with(p, ".git")) {
+			/* strip trailing '[:/]*.git' */
+			if (!after_slash_or_colon)
+				end = p;
+			p += 3;
+		} else if (*p == '/' || *p == ':') {
+			/* strip leading '.*[/:]' */
+			if (end == limit)
+				end = p;
+			after_slash_or_colon = 1;
+		} else if (after_slash_or_colon) {
+			start = p;
+			end = limit;
+			after_slash_or_colon = 0;
+		}
+	}
+	return xstrndup(start, end - start);
+}
+
+static void fprintf_submodule_remote(const char *str)
+{
+	const char *p = str;
+	const char *start;
+	const char *end;
+	char *name, *url;
+
+	start = p;
+	while (*p != ' ')
+		p++;
+	end = p;
+	name = xstrndup(start, end - start);
+
+	while(*p == ' ')
+		p++;
+	start = p;
+	while (*p != ' ')
+		p++;
+	end = p;
+	url = xstrndup(start, end - start);
+
+	fprintf(stderr, "  %s\t%s\n", name, url);
+	free(name);
+	free(url);
+}
+
+static void modify_remote_v(struct strbuf *sb)
+{
+	int i;
+	for (i = 0; i < sb->len; i++) {
+		const char *start = sb->buf + i;
+		const char *end = start;
+		while (sb->buf[i++] != '\n')
+			end++;
+		if (!strcmp("fetch", xstrndup(end - 6, 5)))
+			fprintf_submodule_remote(xstrndup(start, end - start - 7));
+	}
+}
+
+static int add_submodule(struct add_data *info)
+{
+	/* perhaps the path exists and is already a git repo, else clone it */
+	if (is_directory(info->sm_path)) {
+		char *sub_git_path = xstrfmt("%s/.git", info->sm_path);
+		if (is_directory(sub_git_path) || file_exists(sub_git_path))
+			printf(_("Adding existing repo at '%s' to the index\n"),
+				 info->sm_path);
+		else
+			die(_("'%s' already exists and is not a valid git repo"),
+			      info->sm_path);
+		free(sub_git_path);
+	} else {
+		struct strvec clone_args = STRVEC_INIT;
+		struct child_process cp = CHILD_PROCESS_INIT;
+		char *submodule_git_dir = xstrfmt(".git/modules/%s", info->sm_name);
+
+		if (is_directory(submodule_git_dir)) {
+			if (!info->force) {
+				struct child_process cp_rem = CHILD_PROCESS_INIT;
+				struct strbuf sb_rem = STRBUF_INIT;
+				cp_rem.git_cmd = 1;
+				fprintf(stderr, _("A git directory for '%s' is "
+					"found locally with remote(s):\n"),
+					info->sm_name);
+				strvec_pushf(&cp_rem.env_array,
+					     "GIT_DIR=%s", submodule_git_dir);
+				strvec_push(&cp_rem.env_array, "GIT_WORK_TREE=.");
+				strvec_pushl(&cp_rem.args, "remote", "-v", NULL);
+				if (!capture_command(&cp_rem, &sb_rem, 0)) {
+					modify_remote_v(&sb_rem);
+				}
+				error(_("If you want to reuse this local git "
+				      "directory instead of cloning again from\n "
+				      "  %s\n"
+				      "use the '--force' option. If the local "
+				      "git directory is not the correct repo\n"
+				      "or you are unsure what this means choose "
+				      "another name with the '--name' option."),
+				      info->realrepo);
+				return 1;
+			} else {
+				printf(_("Reactivating local git directory for "
+					 "submodule '%s'."), info->sm_path);
+			}
+		}
+		free(submodule_git_dir);
+
+		strvec_push(&clone_args, "clone");
+
+		if (info->quiet)
+			strvec_push(&clone_args, "--quiet");
+
+		if (info->progress)
+			strvec_push(&clone_args, "--progress");
+
+		if (info->prefix)
+			strvec_pushl(&clone_args, "--prefix", info->prefix, NULL);
+		strvec_pushl(&clone_args, "--path", info->sm_path, "--name",
+			     info->sm_name, "--url", info->realrepo, NULL);
+		if (info->reference_path)
+			strvec_pushl(&clone_args, "--reference",
+				     info->reference_path, NULL);
+		if (info->dissociate)
+			strvec_push(&clone_args, "--dissociate");
+
+		if (info->depth >= 0)
+			strvec_pushf(&clone_args, "--depth=%d", info->depth);
+
+		if (module_clone(clone_args.nr, clone_args.v, info->prefix)) {
+			strvec_clear(&clone_args);
+			return -1;
+		}
+
+		prepare_submodule_repo_env(&cp.env_array);
+		cp.git_cmd = 1;
+		cp.dir = info->sm_path;
+		strvec_pushl(&cp.args, "checkout", "-f", "-q", NULL);
+
+		if (info->branch) {
+			strvec_pushl(&cp.args, "-B", info->branch, NULL);
+			strvec_pushf(&cp.args, "origin/%s", info->branch);
+		}
+
+		if (run_command(&cp))
+			die(_("unable to checkout submodule '%s'"), info->sm_path);
+	}
+	return 0;
+}
+
+static void config_added_submodule(struct add_data *info)
+{
+	char *key, *var = NULL;
+	struct child_process cp = CHILD_PROCESS_INIT;
+
+	key = xstrfmt("submodule.%s.url", info->sm_name);
+	git_config_set_gently(key, info->realrepo);
+	free(key);
+
+	cp.git_cmd = 1;
+	strvec_pushl(&cp.args, "add", "--no-warn-embedded-repo", NULL);
+	if (info->force)
+		strvec_push(&cp.args, "--force");
+	strvec_pushl(&cp.args, "--", info->sm_path, ".gitmodules", NULL);
+
+	key = xstrfmt("submodule.%s.path", info->sm_name);
+	git_config_set_in_file_gently(".gitmodules", key, info->sm_path);
+	free(key);
+	key = xstrfmt("submodule.%s.url", info->sm_name);
+	git_config_set_in_file_gently(".gitmodules", key, info->repo);
+	free(key);
+	key = xstrfmt("submodule.%s.branch", info->sm_name);
+	if (info->branch)
+		git_config_set_in_file_gently(".gitmodules", key, info->branch);
+	free(key);
+
+	if (run_command(&cp))
+		die(_("failed to add submodule '%s'"), info->sm_path);
+
+	/*
+	 * NEEDSWORK: In a multi-working-tree world, this needs to be
+	 * set in the per-worktree config.
+	 */
+	if (!git_config_get_string("submodule.active", &var) && var) {
+
+		/*
+		 * If the submodule being adding isn't already covered by the
+		 * current configured pathspec, set the submodule's active flag
+		 */
+		if (!is_submodule_active(the_repository, info->sm_path)) {
+			key = xstrfmt("submodule.%s.active", info->sm_name);
+			git_config_set_gently(key, "true");
+			free(key);
+		}
+	} else {
+		key = xstrfmt("submodule.%s.active", info->sm_name);
+		git_config_set_gently(key, "true");
+		free(key);
+	}
+}
+
+static int module_add(int argc, const char **argv, const char *prefix)
+{
+	const char *branch = NULL, *custom_name = NULL, *realrepo = NULL;
+	const char *reference_path = NULL, *repo = NULL, *name = NULL;
+	char *path;
+	int force = 0, quiet = 0, depth = -1, progress = 0, dissociate = 0;
+	struct add_data info = ADD_DATA_INIT;
+	struct strbuf sb = STRBUF_INIT;
+
+	struct option options[] = {
+		OPT_STRING('b', "branch", &branch, N_("branch"),
+			   N_("branch of repository to add as submodule")),
+		OPT_BOOL('f', "force", &force, N_("allow adding an otherwise "
+						  "ignored submodule path")),
+		OPT__QUIET(&quiet, N_("print only error messages")),
+		OPT_BOOL(0, "progress", &progress, N_("force cloning progress")),
+		OPT_STRING(0, "reference", &reference_path, N_("repository"),
+			   N_("reference repository")),
+		OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")),
+		OPT_STRING(0, "name", &custom_name, N_("name"),
+			   N_("sets the submodule’s name to the given string "
+			      "instead of defaulting to its path")),
+		OPT_INTEGER(0, "depth", &depth, N_("depth for shallow clones")),
+		OPT_END()
+	};
+
+	const char *const usage[] = {
+		N_("git submodule--helper add [<options>] [--] [<path>]"),
+		NULL
+	};
+
+	argc = parse_options(argc, argv, prefix, options, usage, 0);
+
+	if (!is_writing_gitmodules_ok())
+		die(_("please make sure that the .gitmodules file is in the working tree"));
+
+	if (reference_path && !is_absolute_path(reference_path) && prefix)
+		reference_path = xstrfmt("%s%s", prefix, reference_path);
+
+	if (argc == 0 || argc > 2) {
+		usage_with_options(usage, options);
+	} else if (argc == 1) {
+		repo = argv[0];
+		path = guess_dir_name(repo);
+	} else {
+		repo = argv[0];
+		path = xstrdup(argv[1]);
+	}
+
+	if (!is_absolute_path(path) && prefix)
+		path = xstrfmt("%s%s", prefix, path);
+
+	/* assure repo is absolute or relative to parent */
+	if (starts_with_dot_dot_slash(repo) || starts_with_dot_slash(repo)) {
+		char *remote = get_default_remote();
+		char *remoteurl;
+		struct strbuf sb = STRBUF_INIT;
+
+		if (prefix)
+			die(_("relative path can only be used from the toplevel "
+			      "of the working tree"));
+		/* dereference source url relative to parent's url */
+		strbuf_addf(&sb, "remote.%s.url", remote);
+		if (git_config_get_string(sb.buf, &remoteurl))
+			remoteurl = xgetcwd();
+		realrepo = relative_url(remoteurl, repo, NULL);
+
+		free(remoteurl);
+		free(remote);
+	} else if (is_dir_sep(repo[0]) || strchr(repo, ':')) {
+		realrepo = repo;
+	} else {
+		die(_("repo URL: '%s' must be absolute or begin with ./|../"),
+		      repo);
+	}
+
+	/*
+	 * normalize path:
+	 * multiple //; leading ./; /./; /../;
+	 */
+	normalize_path_copy(path, path);
+	/* strip trailing '/' */
+	if (is_dir_sep(path[strlen(path) -1]))
+		path[strlen(path) - 1] = '\0';
+
+	if (!force) {
+		if (is_directory(path) && submodule_from_path(the_repository, &null_oid, path))
+			die(_("'%s' already exists in the index"), path);
+	} else {
+		int err;
+		if (index_name_pos(&the_index, path, strlen(path)) >= 0 &&
+		    !is_submodule_populated_gently(path, &err))
+			die(_("'%s' already exists in the index and is not a "
+			      "submodule"), path);
+	}
+
+	strbuf_addstr(&sb, path);
+	if (is_directory(path)) {
+		struct object_id oid;
+		if (resolve_gitlink_ref(path, "HEAD", &oid) < 0)
+			die(_("'%s' does not have a commit checked out"), path);
+	}
+
+	if (!force) {
+		struct strbuf sb = STRBUF_INIT;
+		struct child_process cp = CHILD_PROCESS_INIT;
+		cp.git_cmd = 1;
+		cp.no_stdout = 1;
+		strvec_pushl(&cp.args, "add", "--dry-run", "--ignore-missing",
+			     "--no-warn-embedded-repo", path, NULL);
+		if (pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0))
+			die(_("%s"), sb.buf);
+		strbuf_release(&sb);
+	}
+
+	name = custom_name ? custom_name : path;
+	if (check_submodule_name(name))
+		die(_("'%s' is not a valid submodule name"), name);
+
+	info.prefix = prefix;
+	info.sm_name = name;
+	info.sm_path = path;
+	info.repo = repo;
+	info.realrepo = realrepo;
+	info.reference_path = reference_path;
+	info.branch = branch;
+	info.depth = depth;
+	info.progress = !!progress;
+	info.dissociate = !!dissociate;
+	info.force = !!force;
+	info.quiet = !!quiet;
+
+	if (add_submodule(&info))
+		return 1;
+	config_added_submodule(&info);
+
+	free(path);
+
+	return 0;
+}
+
 #define SUPPORT_SUPER_PREFIX (1<<0)
 
 struct cmd_struct {
@@ -2352,6 +2722,7 @@ static struct cmd_struct commands[] = {
 	{"config", module_config, 0},
 	{"set-url", module_set_url, 0},
 	{"set-branch", module_set_branch, 0},
+	{"add", module_add, SUPPORT_SUPER_PREFIX},
 };
 
 int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
diff --git a/git-submodule.sh b/git-submodule.sh
index 43eb6051d2..434db338a4 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -171,166 +171,7 @@ cmd_add()
 		shift
 	done
 
-	if ! git submodule--helper config --check-writeable >/dev/null 2>&1
-	then
-		 die "$(eval_gettext "please make sure that the .gitmodules file is in the working tree")"
-	fi
-
-	if test -n "$reference_path"
-	then
-		is_absolute_path "$reference_path" ||
-		reference_path="$wt_prefix$reference_path"
-
-		reference="--reference=$reference_path"
-	fi
-
-	repo=$1
-	sm_path=$2
-
-	if test -z "$sm_path"; then
-		sm_path=$(printf '%s\n' "$repo" |
-			sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
-	fi
-
-	if test -z "$repo" || test -z "$sm_path"; then
-		usage
-	fi
-
-	is_absolute_path "$sm_path" || sm_path="$wt_prefix$sm_path"
-
-	# assure repo is absolute or relative to parent
-	case "$repo" in
-	./*|../*)
-		test -z "$wt_prefix" ||
-		die "$(gettext "Relative path can only be used from the toplevel of the working tree")"
-
-		# dereference source url relative to parent's url
-		realrepo=$(git submodule--helper resolve-relative-url "$repo") || exit
-		;;
-	*:*|/*)
-		# absolute url
-		realrepo=$repo
-		;;
-	*)
-		die "$(eval_gettext "repo URL: '\$repo' must be absolute or begin with ./|../")"
-	;;
-	esac
-
-	# normalize path:
-	# multiple //; leading ./; /./; /../; trailing /
-	sm_path=$(printf '%s/\n' "$sm_path" |
-		sed -e '
-			s|//*|/|g
-			s|^\(\./\)*||
-			s|/\(\./\)*|/|g
-			:start
-			s|\([^/]*\)/\.\./||
-			tstart
-			s|/*$||
-		')
-	if test -z "$force"
-	then
-		git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
-		die "$(eval_gettext "'\$sm_path' already exists in the index")"
-	else
-		git ls-files -s "$sm_path" | sane_grep -v "^160000" > /dev/null 2>&1 &&
-		die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
-	fi
-
-	if test -d "$sm_path" &&
-		test -z $(git -C "$sm_path" rev-parse --show-cdup 2>/dev/null)
-	then
-	    git -C "$sm_path" rev-parse --verify -q HEAD >/dev/null ||
-	    die "$(eval_gettext "'\$sm_path' does not have a commit checked out")"
-	fi
-
-	if test -z "$force"
-	then
-	    dryerr=$(git add --dry-run --ignore-missing --no-warn-embedded-repo "$sm_path" 2>&1 >/dev/null)
-	    res=$?
-	    if test $res -ne 0
-	    then
-		 echo >&2 "$dryerr"
-		 exit $res
-	    fi
-	fi
-
-	if test -n "$custom_name"
-	then
-		sm_name="$custom_name"
-	else
-		sm_name="$sm_path"
-	fi
-
-	if ! git submodule--helper check-name "$sm_name"
-	then
-		die "$(eval_gettext "'$sm_name' is not a valid submodule name")"
-	fi
-
-	# perhaps the path exists and is already a git repo, else clone it
-	if test -e "$sm_path"
-	then
-		if test -d "$sm_path"/.git || test -f "$sm_path"/.git
-		then
-			eval_gettextln "Adding existing repo at '\$sm_path' to the index"
-		else
-			die "$(eval_gettext "'\$sm_path' already exists and is not a valid git repo")"
-		fi
-
-	else
-		if test -d ".git/modules/$sm_name"
-		then
-			if test -z "$force"
-			then
-				eval_gettextln >&2 "A git directory for '\$sm_name' is found locally with remote(s):"
-				GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^,"  ", -e s,' (fetch)',, >&2
-				die "$(eval_gettextln "\
-If you want to reuse this local git directory instead of cloning again from
-  \$realrepo
-use the '--force' option. If the local git directory is not the correct repo
-or you are unsure what this means choose another name with the '--name' option.")"
-			else
-				eval_gettextln "Reactivating local git directory for submodule '\$sm_name'."
-			fi
-		fi
-		git submodule--helper clone ${GIT_QUIET:+--quiet} ${progress:+"--progress"} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${dissociate:+"--dissociate"} ${depth:+"$depth"} || exit
-		(
-			sanitize_submodule_env
-			cd "$sm_path" &&
-			# ash fails to wordsplit ${branch:+-b "$branch"...}
-			case "$branch" in
-			'') git checkout -f -q ;;
-			?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
-			esac
-		) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")"
-	fi
-	git config submodule."$sm_name".url "$realrepo"
-
-	git add --no-warn-embedded-repo $force "$sm_path" ||
-	die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
-
-	git submodule--helper config submodule."$sm_name".path "$sm_path" &&
-	git submodule--helper config submodule."$sm_name".url "$repo" &&
-	if test -n "$branch"
-	then
-		git submodule--helper config submodule."$sm_name".branch "$branch"
-	fi &&
-	git add --force .gitmodules ||
-	die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
-
-	# NEEDSWORK: In a multi-working-tree world, this needs to be
-	# set in the per-worktree config.
-	if git config --get submodule.active >/dev/null
-	then
-		# If the submodule being adding isn't already covered by the
-		# current configured pathspec, set the submodule's active flag
-		if ! git submodule--helper is-active "$sm_path"
-		then
-			git config submodule."$sm_name".active "true"
-		fi
-	else
-		git config submodule."$sm_name".active "true"
-	fi
+	git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper add ${force:+--force} ${GIT_QUIET:+--quiet} ${progress:+--progress} ${branch:+--branch "$branch"} ${reference_path:+--reference "$reference_path"} ${dissociate:+--dissociate} ${custom_name:+--name "$custom_name"} ${depth:+"$depth"} -- "$@"
 }
 
 #
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index fec7e0299d..f26edddbb8 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -48,7 +48,7 @@ test_expect_success 'submodule update aborts on missing gitmodules url' '
 
 test_expect_success 'add aborts on repository with no commits' '
 	cat >expect <<-\EOF &&
-	'"'repo-no-commits'"' does not have a commit checked out
+	fatal: '"'repo-no-commits'"' does not have a commit checked out
 	EOF
 	git init repo-no-commits &&
 	test_must_fail git submodule add ../a ./repo-no-commits 2>actual &&
@@ -171,11 +171,12 @@ test_expect_success 'submodule add to .gitignored path fails' '
 	(
 		cd addtest-ignore &&
 		cat <<-\EOF >expect &&
-		The following paths are ignored by one of your .gitignore files:
+		fatal: The following paths are ignored by one of your .gitignore files:
 		submod
 		hint: Use -f if you really want to add them.
 		hint: Turn this message off by running
 		hint: "git config advice.addIgnoredFile false"
+
 		EOF
 		# Does not use test_commit due to the ignore
 		echo "*" > .gitignore &&
-- 
2.28.0


^ permalink raw reply related	[relevance 18%]

* [PATCH v3 4/4] submodule: port submodule subcommand 'summary' from shell to C
  @ 2020-08-12 19:44 18%   ` Shourya Shukla
  0 siblings, 0 replies; 200+ results
From: Shourya Shukla @ 2020-08-12 19:44 UTC (permalink / raw)
  To: shouryashukla.oo
  Cc: christian.couder, git, gitster, Johannes.Schindelin,
	kaartic.sivaraam, liu.denton, Prathamesh Chavan, Christian Couder,
	Stefan Beller

From: Prathamesh Chavan <pc44800@gmail.com>

Convert submodule subcommand 'summary' to a builtin and call it via
'git-submodule.sh'.

The shell version had to call $diff_cmd twice, once to find the modified
modules cared by the user and then again, with that list of modules
to do various operations for computing the summary of those modules.
On the other hand, the C version does not need a second call to
$diff_cmd since it reuses the module list from the first call to do the
aforementioned tasks.

In the C version, we use the combination of setting a child process'
working directory to the submodule path and then calling
'prepare_submodule_repo_env()' which also sets the 'GIT_DIR' to '.git',
so that we can be certain that those spawned processes will not access
the superproject's ODB by mistake.

A behavioural difference between the C and the shell version is that the
shell version outputs two line feeds after the 'git log' output when run
outside of the tests while the C version outputs one line feed in any
case. The reason for this is that the shell version calls log with
'--pretty=format:<fmt>' whose output is followed by two echo
calls; 'format' does not have "terminator" semantics like its 'tformat'
counterpart. So, the log output is terminated by a newline only when
invoked by the user and not when invoked from the scripts. This results
in the one & two line feed differences in the shell version.
On the other hand, the C version calls log with '--pretty=<fmt>'
which is equivalent to '--pretty:tformat:<fmt>' which is then
followed by a 'printf("\n")'. Due to its "terminator" semantics the
log output is always terminated by newline and hence one line feed in
any case.

Also, when we try to pass an option-like argument after a non-option
argument, for instance:

    git submodule summary HEAD --foo-bar

    (or)

    git submodule summary HEAD --cached

That argument would be treated like a path to the submodule for which
the user is requesting a summary. So, the option ends up having no
effect. Though, passing '--quiet' is an exception to this:

    git submodule summary HEAD --quiet

While 'summary' doesn't support '--quiet', we don't get an output for
the above command as '--quiet' is treated as a path which means we get
an output only if a submodule whose path is '--quiet' exists.

The error message in case of computing a summary for non-existent
submodules in the C version is different from that of the shell version.
Since the new error message is not marked for translation, change the
'test_i18ngrep' in t7421.4 to 'grep'.

Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Mentored-by: Stefan Beller <stefanbeller@gmail.com>
Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
---
 builtin/submodule--helper.c      | 429 +++++++++++++++++++++++++++++++
 git-submodule.sh                 | 186 +-------------
 t/t7421-submodule-summary-add.sh |   2 +-
 3 files changed, 431 insertions(+), 186 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index a03dc84ea4..63ea39025d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -927,6 +927,434 @@ static int module_name(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+struct module_cb {
+	unsigned int mod_src;
+	unsigned int mod_dst;
+	struct object_id oid_src;
+	struct object_id oid_dst;
+	char status;
+	const char *sm_path;
+};
+#define MODULE_CB_INIT { 0, 0, NULL, NULL, '\0', NULL }
+
+struct module_cb_list {
+	struct module_cb **entries;
+	int alloc, nr;
+};
+#define MODULE_CB_LIST_INIT { NULL, 0, 0 }
+
+struct summary_cb {
+	int argc;
+	const char **argv;
+	const char *prefix;
+	unsigned int cached: 1;
+	unsigned int for_status: 1;
+	unsigned int files: 1;
+	int summary_limit;
+};
+#define SUMMARY_CB_INIT { 0, NULL, NULL, 0, 0, 0, 0 }
+
+enum diff_cmd {
+	DIFF_INDEX,
+	DIFF_FILES
+};
+
+static char* verify_submodule_committish(const char *sm_path,
+					 const char *committish)
+{
+	struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
+	struct strbuf result = STRBUF_INIT;
+
+	cp_rev_parse.git_cmd = 1;
+	cp_rev_parse.dir = sm_path;
+	prepare_submodule_repo_env(&cp_rev_parse.env_array);
+	strvec_pushl(&cp_rev_parse.args, "rev-parse", "-q", "--short", NULL);
+	strvec_pushf(&cp_rev_parse.args, "%s^0", committish);
+	strvec_push(&cp_rev_parse.args, "--");
+
+	if (capture_command(&cp_rev_parse, &result, 0))
+		return NULL;
+
+	strbuf_trim_trailing_newline(&result);
+	return strbuf_detach(&result, NULL);
+}
+
+static void print_submodule_summary(struct summary_cb *info, char* errmsg,
+				    int total_commits, const char *displaypath,
+				    const char *src_abbrev, const char *dst_abbrev,
+				    int missing_src, int missing_dst,
+				    struct module_cb *p)
+{
+	if (p->status == 'T') {
+		if (S_ISGITLINK(p->mod_dst))
+			printf(_("* %s %s(blob)->%s(submodule)"),
+				 displaypath, src_abbrev, dst_abbrev);
+		else
+			printf(_("* %s %s(submodule)->%s(blob)"),
+				 displaypath, src_abbrev, dst_abbrev);
+	} else {
+		printf("* %s %s...%s",
+			displaypath, src_abbrev, dst_abbrev);
+	}
+
+	if (total_commits < 0)
+		printf(":\n");
+	else
+		printf(" (%d):\n", total_commits);
+
+	if (errmsg) {
+		printf(_("%s"), errmsg);
+	} else if (total_commits > 0) {
+		struct child_process cp_log = CHILD_PROCESS_INIT;
+
+		cp_log.git_cmd = 1;
+		cp_log.dir = p->sm_path;
+		prepare_submodule_repo_env(&cp_log.env_array);
+		strvec_pushl(&cp_log.args, "log", NULL);
+
+		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
+			if (info->summary_limit > 0)
+				strvec_pushf(&cp_log.args, "-%d",
+					     info->summary_limit);
+
+			strvec_pushl(&cp_log.args, "--pretty=  %m %s",
+				     "--first-parent", NULL);
+			strvec_pushf(&cp_log.args, "%s...%s",
+				     src_abbrev, dst_abbrev);
+		} else if (S_ISGITLINK(p->mod_dst)) {
+			strvec_pushl(&cp_log.args, "--pretty=  > %s",
+				     "-1", dst_abbrev, NULL);
+		} else {
+			strvec_pushl(&cp_log.args, "--pretty=  < %s",
+				     "-1", src_abbrev, NULL);
+		}
+		run_command(&cp_log);
+	}
+	printf("\n");
+}
+
+static void generate_submodule_summary(struct summary_cb *info,
+				       struct module_cb *p)
+{
+	char *displaypath, *src_abbrev, *dst_abbrev;
+	int missing_src = 0, missing_dst = 0;
+	char *errmsg = NULL;
+	int total_commits = -1;
+
+	if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
+		if (S_ISGITLINK(p->mod_dst)) {
+			struct ref_store *refs = get_submodule_ref_store(p->sm_path);
+			if (refs)
+				refs_head_ref(refs, handle_submodule_head_ref, &p->oid_dst);
+		} else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
+			struct stat st;
+			int fd = open(p->sm_path, O_RDONLY);
+
+			if (fd < 0 || fstat(fd, &st) < 0 ||
+			    index_fd(&the_index, &p->oid_dst, fd, &st, OBJ_BLOB,
+				     p->sm_path, 0))
+				error(_("couldn't hash object from '%s'"), p->sm_path);
+		} else {
+			/* for a submodule removal (mode:0000000), don't warn */
+			if (p->mod_dst)
+				warning(_("unexpected mode %d\n"), p->mod_dst);
+		}
+	}
+
+	if (S_ISGITLINK(p->mod_src)) {
+		src_abbrev = verify_submodule_committish(p->sm_path,
+							 oid_to_hex(&p->oid_src));
+		if (!src_abbrev) {
+			missing_src = 1;
+			/*
+			 * As `rev-parse` failed, we fallback to getting
+			 * the abbreviated hash using oid_src. We do
+			 * this as we might still need the abbreviated
+			 * hash in cases like a submodule type change, etc.
+			 */
+			src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
+		}
+	} else {
+		/*
+		 * The source does not point to a submodule.
+		 * So, we fallback to getting the abbreviation using
+		 * oid_src as we might still need the abbreviated
+		 * hash in cases like submodule add, etc.
+		 */
+		src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
+	}
+
+	if (S_ISGITLINK(p->mod_dst)) {
+		dst_abbrev = verify_submodule_committish(p->sm_path,
+							 oid_to_hex(&p->oid_dst));
+		if (!dst_abbrev) {
+			missing_dst = 1;
+			/*
+			 * As `rev-parse` failed, we fallback to getting
+			 * the abbreviated hash using oid_dst. We do
+			 * this as we might still need the abbreviated
+			 * hash in cases like a submodule type change, etc.
+			 */
+			dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
+		}
+	} else {
+		/*
+		 * The destination does not point to a submodule.
+		 * So, we fallback to getting the abbreviation using
+		 * oid_dst as we might still need the abbreviated
+		 * hash in cases like a submodule removal, etc.
+		 */
+		dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
+	}
+
+	displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
+
+	if (!missing_src && !missing_dst) {
+		struct child_process cp_rev_list = CHILD_PROCESS_INIT;
+		struct strbuf sb_rev_list = STRBUF_INIT;
+
+		strvec_pushl(&cp_rev_list.args, "rev-list",
+			     "--first-parent", "--count", NULL);
+		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
+			strvec_pushf(&cp_rev_list.args, "%s...%s",
+				     src_abbrev, dst_abbrev);
+		else
+			strvec_push(&cp_rev_list.args, S_ISGITLINK(p->mod_src) ?
+				    src_abbrev : dst_abbrev);
+		strvec_push(&cp_rev_list.args, "--");
+
+		cp_rev_list.git_cmd = 1;
+		cp_rev_list.dir = p->sm_path;
+		prepare_submodule_repo_env(&cp_rev_list.env_array);
+
+		if (!capture_command(&cp_rev_list, &sb_rev_list, 0))
+			total_commits = atoi(sb_rev_list.buf);
+
+		strbuf_release(&sb_rev_list);
+	} else {
+		/*
+		 * Don't give error msg for modification whose dst is not
+		 * submodule, i.e., deleted or changed to blob
+		 */
+		if (S_ISGITLINK(p->mod_dst)) {
+			struct strbuf errmsg_str = STRBUF_INIT;
+			if (missing_src && missing_dst) {
+				strbuf_addf(&errmsg_str, "  Warn: %s doesn't contain commits %s and %s\n",
+					    displaypath, oid_to_hex(&p->oid_src),
+					    oid_to_hex(&p->oid_dst));
+			} else {
+				strbuf_addf(&errmsg_str, "  Warn: %s doesn't contain commit %s\n",
+					    displaypath, missing_src ?
+					    oid_to_hex(&p->oid_src) :
+					    oid_to_hex(&p->oid_dst));
+			}
+			errmsg = strbuf_detach(&errmsg_str, NULL);
+		}
+	}
+
+	print_submodule_summary(info, errmsg, total_commits,
+				displaypath, src_abbrev,
+				dst_abbrev, missing_src,
+				missing_dst, p);
+
+	free(displaypath);
+	free(src_abbrev);
+	free(dst_abbrev);
+}
+
+static void prepare_submodule_summary(struct summary_cb *info,
+				      struct module_cb_list *list)
+{
+	int i;
+	for (i = 0; i < list->nr; i++) {
+		const struct submodule *sub;
+		struct module_cb *p = list->entries[i];
+		struct strbuf sm_gitdir = STRBUF_INIT;
+
+		if (p->status == 'D' || p->status == 'T') {
+			generate_submodule_summary(info, p);
+			continue;
+		}
+
+		if (info->for_status && p->status != 'A' &&
+		    (sub = submodule_from_path(the_repository,
+					       &null_oid, p->sm_path))) {
+			char *config_key = NULL;
+			const char *value;
+			int ignore_all = 0;
+
+			config_key = xstrfmt("submodule.%s.ignore",
+					     sub->name);
+			if (!git_config_get_string_const(config_key, &value))
+				ignore_all = !strcmp(value, "all");
+			else if (sub->ignore)
+				ignore_all = !strcmp(sub->ignore, "all");
+
+			free(config_key);
+			if (ignore_all)
+				continue;
+		}
+
+		/* Also show added or modified modules which are checked out */
+		strbuf_addstr(&sm_gitdir, p->sm_path);
+		if (is_nonbare_repository_dir(&sm_gitdir))
+			generate_submodule_summary(info, p);
+		strbuf_release(&sm_gitdir);
+	}
+}
+
+static void submodule_summary_callback(struct diff_queue_struct *q,
+				       struct diff_options *options,
+				       void *data)
+{
+	int i;
+	struct module_cb_list *list = data;
+	for (i = 0; i < q->nr; i++) {
+		struct diff_filepair *p = q->queue[i];
+		struct module_cb *temp;
+
+		if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
+			continue;
+		temp = (struct module_cb*)malloc(sizeof(struct module_cb));
+		temp->mod_src = p->one->mode;
+		temp->mod_dst = p->two->mode;
+		temp->oid_src = p->one->oid;
+		temp->oid_dst = p->two->oid;
+		temp->status = p->status;
+		temp->sm_path = xstrdup(p->one->path);
+
+		ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
+		list->entries[list->nr++] = temp;
+	}
+}
+
+static const char *get_diff_cmd(enum diff_cmd diff_cmd)
+{
+	switch (diff_cmd) {
+	case DIFF_INDEX: return "diff-index";
+	case DIFF_FILES: return "diff-files";
+	default: BUG("bad diff_cmd value %d", diff_cmd);
+	}
+}
+
+static int compute_summary_module_list(struct object_id *head_oid,
+				       struct summary_cb *info,
+				       enum diff_cmd diff_cmd)
+{
+	struct strvec diff_args = STRVEC_INIT;
+	struct rev_info rev;
+	struct module_cb_list list = MODULE_CB_LIST_INIT;
+
+	strvec_push(&diff_args, get_diff_cmd(diff_cmd));
+	if (info->cached)
+		strvec_push(&diff_args, "--cached");
+	strvec_pushl(&diff_args, "--ignore-submodules=dirty", "--raw", NULL);
+	if (head_oid)
+		strvec_push(&diff_args, oid_to_hex(head_oid));
+	strvec_push(&diff_args, "--");
+	if (info->argc)
+		strvec_pushv(&diff_args, info->argv);
+
+	git_config(git_diff_basic_config, NULL);
+	init_revisions(&rev, info->prefix);
+	rev.abbrev = 0;
+	precompose_argv(diff_args.nr, diff_args.v);
+	setup_revisions(diff_args.nr, diff_args.v, &rev, NULL);
+	rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
+	rev.diffopt.format_callback = submodule_summary_callback;
+	rev.diffopt.format_callback_data = &list;
+
+	if (!info->cached) {
+		if (diff_cmd == DIFF_INDEX)
+			setup_work_tree();
+		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
+			perror("read_cache_preload");
+			return -1;
+		}
+	} else if (read_cache() < 0) {
+		perror("read_cache");
+		return -1;
+	}
+
+	if (diff_cmd == DIFF_INDEX)
+		run_diff_index(&rev, info->cached);
+	else
+		run_diff_files(&rev, 0);
+	prepare_submodule_summary(info, &list);
+	strvec_clear(&diff_args);
+	return 0;
+}
+
+static int module_summary(int argc, const char **argv, const char *prefix)
+{
+	struct summary_cb info = SUMMARY_CB_INIT;
+	int cached = 0;
+	int for_status = 0;
+	int files = 0;
+	int summary_limit = -1;
+	enum diff_cmd diff_cmd = DIFF_INDEX;
+	struct object_id head_oid;
+	int ret;
+
+	struct option module_summary_options[] = {
+		OPT_BOOL(0, "cached", &cached,
+			 N_("use the commit stored in the index instead of the submodule HEAD")),
+		OPT_BOOL(0, "files", &files,
+			 N_("to compare the commit in the index with that in the submodule HEAD")),
+		OPT_BOOL(0, "for-status", &for_status,
+			 N_("skip submodules with 'ignore_config' value set to 'all'")),
+		OPT_INTEGER('n', "summary-limit", &summary_limit,
+			     N_("limit the summary size")),
+		OPT_END()
+	};
+
+	const char *const git_submodule_helper_usage[] = {
+		N_("git submodule--helper summary [<options>] [commit] [--] [<path>]"),
+		NULL
+	};
+
+	argc = parse_options(argc, argv, prefix, module_summary_options,
+			     git_submodule_helper_usage, 0);
+
+	if (!summary_limit)
+		return 0;
+
+	if (!get_oid(argc ? argv[0] : "HEAD", &head_oid)) {
+		if (argc) {
+			argv++;
+			argc--;
+		}
+	} else if (!argc || !strcmp(argv[0], "HEAD")) {
+		/* before the first commit: compare with an empty tree */
+		oidcpy(&head_oid, the_hash_algo->empty_tree);
+		if (argc) {
+			argv++;
+			argc--;
+		}
+	} else {
+		if (get_oid("HEAD", &head_oid))
+			die(_("could not fetch a revision for HEAD"));
+	}
+
+	if (files) {
+		if (cached)
+			die(_("--cached and --files are mutually exclusive"));
+		diff_cmd = DIFF_FILES;
+	}
+
+	info.argc = argc;
+	info.argv = argv;
+	info.prefix = prefix;
+	info.cached = !!cached;
+	info.files = !!files;
+	info.for_status = !!for_status;
+	info.summary_limit = summary_limit;
+
+	ret = compute_summary_module_list((diff_cmd == DIFF_INDEX) ? &head_oid : NULL,
+					  &info, diff_cmd);
+	return ret;
+}
+
 struct sync_cb {
 	const char *prefix;
 	unsigned int flags;
@@ -2341,6 +2769,7 @@ static struct cmd_struct commands[] = {
 	{"print-default-remote", print_default_remote, 0},
 	{"sync", module_sync, SUPPORT_SUPER_PREFIX},
 	{"deinit", module_deinit, 0},
+	{"summary", module_summary, SUPPORT_SUPER_PREFIX},
 	{"remote-branch", resolve_remote_submodule_branch, 0},
 	{"push-check", push_check, 0},
 	{"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
diff --git a/git-submodule.sh b/git-submodule.sh
index 43eb6051d2..6fb12585cb 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -59,31 +59,6 @@ die_if_unmatched ()
 	fi
 }
 
-#
-# Print a submodule configuration setting
-#
-# $1 = submodule name
-# $2 = option name
-# $3 = default value
-#
-# Checks in the usual git-config places first (for overrides),
-# otherwise it falls back on .gitmodules.  This allows you to
-# distribute project-wide defaults in .gitmodules, while still
-# customizing individual repositories if necessary.  If the option is
-# not in .gitmodules either, print a default value.
-#
-get_submodule_config () {
-	name="$1"
-	option="$2"
-	default="$3"
-	value=$(git config submodule."$name"."$option")
-	if test -z "$value"
-	then
-		value=$(git submodule--helper config submodule."$name"."$option")
-	fi
-	printf '%s' "${value:-$default}"
-}
-
 isnumber()
 {
 	n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
@@ -831,166 +806,7 @@ cmd_summary() {
 		shift
 	done
 
-	test $summary_limit = 0 && return
-
-	if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
-	then
-		head=$rev
-		test $# = 0 || shift
-	elif test -z "$1" || test "$1" = "HEAD"
-	then
-		# before the first commit: compare with an empty tree
-		head=$(git hash-object -w -t tree --stdin </dev/null)
-		test -z "$1" || shift
-	else
-		head="HEAD"
-	fi
-
-	if [ -n "$files" ]
-	then
-		test -n "$cached" &&
-		die "$(gettext "The --cached option cannot be used with the --files option")"
-		diff_cmd=diff-files
-		head=
-	fi
-
-	cd_to_toplevel
-	eval "set $(git rev-parse --sq --prefix "$wt_prefix" -- "$@")"
-	# Get modified modules cared by user
-	modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
-		sane_egrep '^:([0-7]* )?160000' |
-		while read -r mod_src mod_dst sha1_src sha1_dst status sm_path
-		do
-			# Always show modules deleted or type-changed (blob<->module)
-			if test "$status" = D || test "$status" = T
-			then
-				printf '%s\n' "$sm_path"
-				continue
-			fi
-			# Respect the ignore setting for --for-status.
-			if test -n "$for_status"
-			then
-				name=$(git submodule--helper name "$sm_path")
-				ignore_config=$(get_submodule_config "$name" ignore none)
-				test $status != A && test $ignore_config = all && continue
-			fi
-			# Also show added or modified modules which are checked out
-			GIT_DIR="$sm_path/.git" git rev-parse --git-dir >/dev/null 2>&1 &&
-			printf '%s\n' "$sm_path"
-		done
-	)
-
-	test -z "$modules" && return
-
-	git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
-	sane_egrep '^:([0-7]* )?160000' |
-	cut -c2- |
-	while read -r mod_src mod_dst sha1_src sha1_dst status name
-	do
-		if test -z "$cached" &&
-			is_zero_oid $sha1_dst
-		then
-			case "$mod_dst" in
-			160000)
-				sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
-				;;
-			100644 | 100755 | 120000)
-				sha1_dst=$(git hash-object $name)
-				;;
-			000000)
-				;; # removed
-			*)
-				# unexpected type
-				eval_gettextln "unexpected mode \$mod_dst" >&2
-				continue ;;
-			esac
-		fi
-		missing_src=
-		missing_dst=
-
-		test $mod_src = 160000 &&
-		! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
-		missing_src=t
-
-		test $mod_dst = 160000 &&
-		! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
-		missing_dst=t
-
-		display_name=$(git submodule--helper relative-path "$name" "$wt_prefix")
-
-		total_commits=
-		case "$missing_src,$missing_dst" in
-		t,)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
-			;;
-		,t)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
-			;;
-		t,t)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$sha1_dst")"
-			;;
-		*)
-			errmsg=
-			total_commits=$(
-			if test $mod_src = 160000 && test $mod_dst = 160000
-			then
-				range="$sha1_src...$sha1_dst"
-			elif test $mod_src = 160000
-			then
-				range=$sha1_src
-			else
-				range=$sha1_dst
-			fi
-			GIT_DIR="$name/.git" \
-			git rev-list --first-parent $range -- | wc -l
-			)
-			total_commits=" ($(($total_commits + 0)))"
-			;;
-		esac
-
-		sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
-			echo $sha1_src | cut -c1-7)
-		sha1_abbr_dst=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_dst 2>/dev/null ||
-			echo $sha1_dst | cut -c1-7)
-
-		if test $status = T
-		then
-			blob="$(gettext "blob")"
-			submodule="$(gettext "submodule")"
-			if test $mod_dst = 160000
-			then
-				echo "* $display_name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:"
-			else
-				echo "* $display_name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:"
-			fi
-		else
-			echo "* $display_name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
-		fi
-		if test -n "$errmsg"
-		then
-			# Don't give error msg for modification whose dst is not submodule
-			# i.e. deleted or changed to blob
-			test $mod_dst = 160000 && echo "$errmsg"
-		else
-			if test $mod_src = 160000 && test $mod_dst = 160000
-			then
-				limit=
-				test $summary_limit -gt 0 && limit="-$summary_limit"
-				GIT_DIR="$name/.git" \
-				git log $limit --pretty='format:  %m %s' \
-				--first-parent $sha1_src...$sha1_dst
-			elif test $mod_dst = 160000
-			then
-				GIT_DIR="$name/.git" \
-				git log --pretty='format:  > %s' -1 $sha1_dst
-			else
-				GIT_DIR="$name/.git" \
-				git log --pretty='format:  < %s' -1 $sha1_src
-			fi
-			echo
-		fi
-		echo
-	done
+	git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${prefix:+--prefix "$prefix"} ${files:+--files} ${cached:+--cached} ${for_status:+--for-status} ${summary_limit:+-n $summary_limit} -- "$@"
 }
 #
 # List all submodules, prefixed with:
diff --git a/t/t7421-submodule-summary-add.sh b/t/t7421-submodule-summary-add.sh
index 829fe26d6d..59a9b00467 100755
--- a/t/t7421-submodule-summary-add.sh
+++ b/t/t7421-submodule-summary-add.sh
@@ -58,7 +58,7 @@ test_expect_success 'submodule summary output for submodules with changed paths'
 	git commit -m "change submodule path" &&
 	rev=$(git -C sm rev-parse --short HEAD^) &&
 	git submodule summary HEAD^^ -- my-subm >actual 2>err &&
-	test_i18ngrep "fatal:.*my-subm" err &&
+	grep "fatal:.*my-subm" err &&
 	cat >expected <<-EOF &&
 	* my-subm ${rev}...0000000:
 
-- 
2.28.0


^ permalink raw reply related	[relevance 18%]

* [GSoC][PATCH v2 0/5] submodule: port subcommand 'summary' from shell to C
@ 2020-08-06 16:40  4% Shourya Shukla
  2020-08-06 16:41 18% ` [PATCH v2 5/5] submodule: port submodule " Shourya Shukla
    0 siblings, 2 replies; 200+ results
From: Shourya Shukla @ 2020-08-06 16:40 UTC (permalink / raw)
  To: git
  Cc: gitster, christian.couder, kaartic.sivaraam, johannes.schindelin,
	liu.denton, Shourya Shukla

Greetings,

After a long list of changes proposed by Johannes in the v1, here I
present the v2 of the patch series porting 'summary' from shell to C.
Apart from requested changes in 'submodule--helper.c' and dropping the
commit changing the scope of the 'count_lines()' function, there are
two new commits: one documents the 'for-status' option and one
introduces the test 't7421-submodule-summary-add.sh'. Link to the v1:
https://lore.kernel.org/git/20200702192409.21865-1-shouryashukla.oo@gmail.com/

The reasons for the introduction of the test are covered in a previous
patch series delivered by me last night regarding t7401:
https://lore.kernel.org/git/20200805174921.16000-1-shouryashukla.oo@gmail.com/

But I will touch upon it again in this patch. The test script
't7401-submodule-summary.sh' adds submodules using 'git add' instead of
'git submodule add'. Therefore, some commands such as
'git submodule init' and 'git submodule deinit' do not give the desired
effects since there is no .gitmodules file. Note that, 'summary'
works without issues as it does not depend on the existence of
.gitmodules.

I will tag along the 'range-diff' between this v2 and the v1 at the end
of the cover letter for ease of review.

The changelog:

- Introduce commit [PATCH 1/5] 4f0e4f6ace (submodule: document the
  '--for-status' option, 2020-08-02).

- Improve commit message of [PATCH 2/5] 6e42cc99a7 (submodule: remove
  extra line feeds between callback struct and macro, 2020-06-25).

- Drop commit (Previously [PATCH 3/4]) 745f2bd92e (diff: change scope
  of the function count_lines(), 2017-07-11).

- Introduce commit [PATCH 4/5] ef4cf4be0f (t7421: introduce a test
  script for verifying 'summary' output, 2020-07-23).

- Improve the commit [PATCH 5/5] 331cc1a487 (submodule: port submodule
  subcommand 'summary' from shell to C, 2017-07-11) which includes:
    -> Improve the commit message, focusing more on the specialities of
       the commit rather than describing the flow of the subcommand.

    -> Rename the function 'verify_submodule_object_name()' to
       'verify_submodule_committish()' as the latter is more accurate.
       While at it, rename its argument 'const char *sha1' to 'const
       char *committish' since Git is shifting to SHA256 (covered in the
       patch series by Brian M. Carlson) and we look for a committish in
       the 'rev-parse' called in the function. Also, pass a '--short' in
       the call to 'rev-parse' as this option does the job of '--verify'
       and also shortens the hash the way we desire.

    -> Reuse the hash obtained from the function
      'verify_submodule_committish()' instead of incorrectly calling
      'find_unique_abbrev()' multiple times. Also eliminate the usage
      of 'oid_to_hex()' and instead reuse the aforementioned hash.

    -> Eliminate the variable 'is_sm_git_dir' and therefore, simplify
       the checks involving it since the GIT_DIR is already set to
       '.git/' and therefore we need to check it again.

    -> Eliminate the NEEDSWORK in 'generate_submodule_summary()' and
       instead call the function 'refs_head_ref()' (successor of
       'head_ref_submodule()').

    -> Use 'index_fd()' instead of spawning a process to run 'git
       hash-object' to find the 'oid_dst' in case of a regular file or
       a symbolic link.

    -> In case of an unexpected file mode, give a warning() and continue
       instead of die()ing.

    -> Simplify the 'range' computation by cuddling up a couple of lines
       and thus removing the 'range' variable since it will be useless.
       The 'range' is the range of commits whose summary will be
       computed.

    -> Eliminate the usage of 'count_lines()' since 'git rev-list
       --count' does the job anyway.

    -> Compute the error messages in 'generate_submodule_summary()'
       itself instead of 'print_submodule_summary()' and therefore, pass
       the err_msg into the latter as a 'char *'.

    -> Simplify the if-statement in case of 'for-status' by cuddling up
       various lines and thus removing one whole level of indentation.

    -> Remove the OPT__QUIET from the option struct since 'summary' does
       not support 'quiet'.

    -> Decapitalise the first letter of the option descriptions since
       the guidelines mention so.

    -> Instead of spawning a child process, use
       'is_nonbare_repository_dir()' to check if the submodules are
       checked out or not.

    -> Call 'get_oid()' to find the hash of 'HEAD' instead of spawning a
       process to call 'rev-parse' in 'module_summary()'. While at it,
       simplify the set of if-else statements which fetch the revision
       of the superproject to calculate the summary of.

    -> Pass the revision computed above to
       'compute_summary_module_list()' as 'struct object_id *' instead of
       passing it as a string.

There is a behavioural difference between the shell and the C version.
The shell version printed two newlines at the end of the output
when executed outside the tests but one newline when executed in the
tests. On the other hand, the C version printed only one newline
irrespective of where it was executed. This is due to the difference
in the way they call 'git log'. The shell version does a
'--pretty=format:<fmt>' whereas the C version does a '--pretty=<fmt>'.
The latter is indirectly a '--pretty=tformat:<fmt>' which causes the
difference between the two.

Also, when we try to pass an option-like argument after a non-option
argument:

	git submodule summary HEAD --foo-bar

That argument would be treated like a path to the submodule for which
the user is requesting a summary. So, the option ends up having no
effect. Though, passing `--quiet` is an exception to this:

	git submodule summary HEAD --quiet

While 'summary' doesn't support '--quiet', we don't get an output for
the above command as '--quiet' is treated as a path which means we get
an output only if a submodule whose path is '--quiet' exists.

Also, I want to ask a couple of things:

	1.Whether we can suppress the error message that we get when
	  trying to find the summary of non-existent submodules?
	  For example:

	  fatal: exec 'rev-parse': cd to 'my-subm' failed: No such file or directory
	   * my-subm 35b40f1...0000000:

	 Will it be OK to suppress the above error message?

	2.Is it fine to document and expose the 'for-status' option in
	  'git-submodule.txt'?

Feedback and reviews are appreciated.

Regards,
Shourya Shukla
-----

-:  ---------- > 1:  c063390a94 submodule: expose the '--for-status' option of summary
1:  add55c1d22 ! 2:  561d03351b submodule: amend extra line feed between callback struct and macro
    @@ Metadata
     Author: Shourya Shukla <shouryashukla.oo@gmail.com>
     
      ## Commit message ##
    -    submodule: amend extra line feed between callback struct and macro
    +    submodule: remove extra line feeds between callback struct and macro
     
    -    All subcommands of 'git submodule' using a callback mechanism had
    -    absence of an extra linefeed between their callback structs and
    -    macros. Subcommands 'init', 'status' and 'sync' did not follow suit.
    -    Amend the extra line feed.
    +    Many `submodule--helper` subcommands follow the convention that a struct
    +    defines their callback data, and the declaration of that struct is
    +    followed immediately by a macro to use in static initializers, without
    +    any separating empty line.
    +
    +    Let's align the `init`, `status` and `sync` subcommands with that convention.
     
         Mentored-by: Christian Couder <chriscool@tuxfamily.org>
         Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
    +    Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
    +    Helped-by: Philip Oakley <philipoakley@iee.email>
         Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
     
      ## builtin/submodule--helper.c ##
2:  75c986a5e0 = 3:  e0e0c3ba4b submodule: rename helper functions to avoid ambiguity
3:  745f2bd92e < -:  ---------- diff: change scope of the function count_lines()
-:  ---------- > 4:  ec6e6c9e64 t7421: introduce a test script for verifying 'summary' output
4:  c5baf68ecf ! 5:  9222b4168b submodule: port submodule subcommand 'summary' from shell to C
    @@ Metadata
      ## Commit message ##
         submodule: port submodule subcommand 'summary' from shell to C
     
    -    The submodule subcommand 'summary' is ported in the process of
    -    making git-submodule a builtin. The function cmd_summary() from
    -    git-submodule.sh is ported to functions module_summary(),
    -    compute_summary_module_list(), prepare_submodule_summary() and
    -    generate_submodule_summary(), print_submodule_summary().
    +    Convert submodule subcommand 'summary' to a builtin and call it via
    +    'git-submodule.sh'.
     
    -    The first function module_summary() parses the options of submodule
    -    subcommand and also acts as the front-end of this subcommand.
    -    After parsing them, it calls the compute_summary_module_list()
    +    The shell version had to call $diff_cmd twice, once to find the modified
    +    modules cared by the user and then again, with that list of modules
    +    to do various operations for computing the summary of those modules.
    +    On the other hand, the C version does not need a second call to
    +    $diff_cmd since it reuses the module list from the first call to do the
    +    aforementioned tasks.
     
    -    The functions compute_summary_module_list() runs the diff_cmd,
    -    and generates the modules list, as required by the subcommand.
    -    The generation of this module list is done by the using the
    -    callback function submodule_summary_callback(), and stored in the
    -    structure module_cb.
    +    In the C version, we use the combination of setting a child process'
    +    working directory to the submodule path and then calling
    +    'prepare_submodule_repo_env()' which also sets the 'GIT_DIR' to '.git',
    +    so that we can be certain that those spawned processes will not access
    +    the superproject's ODB by mistake.
     
    -    Once the module list is generated, prepare_submodule_summary()
    -    further goes through the list and filters the list, for
    -    eventually calling the generate_submodule_summary() function.
    +    A behavioural difference between the C and the shell version is that the
    +    shell version outputs two line feeds after the 'git log' output when run
    +    outside of the tests while the C version outputs one line feed in any
    +    case. The reason for this is that the shell version calls log with
    +    '--pretty=format:<fmt>' whose output is followed by two echo
    +    calls; 'format' does not have "terminator" semantics like its 'tformat'
    +    counterpart. So, the log output is terminated by a newline only when
    +    invoked by the user and not when invoked from the scripts. This results
    +    in the one & two line feed differences in the shell version.
    +    On the other hand, the C version calls log with '--pretty=<fmt>'
    +    which is equivalent to '--pretty:tformat:<fmt>' which is then
    +    followed by a 'printf("\n")'. Due to its "terminator" semantics the
    +    log output is always terminated by newline and hence one line feed in
    +    any case.
     
    -    The function generate_submodule_summary() takes care of generating
    -    the summary for each submodule and then calls the function
    -    print_submodule_summary() for printing it.
    +    Also, when we try to pass an option-like argument after a non-option
    +    argument, for instance:
     
    -    Mentored-by: Christian Couder <christian.couder@gmail.com>
    -    Mentored-by: Stefan Beller <sbeller@google.com>
    +        git submodule summary HEAD --foo-bar
    +
    +        (or)
    +
    +        git submodule summary HEAD --cached
    +
    +    That argument would be treated like a path to the submodule for which
    +    the user is requesting a summary. So, the option ends up having no
    +    effect. Though, passing '--quiet' is an exception to this:
    +
    +        git submodule summary HEAD --quiet
    +
    +    While 'summary' doesn't support '--quiet', we don't get an output for
    +    the above command as '--quiet' is treated as a path which means we get
    +    an output only if a submodule whose path is '--quiet' exists.
    +
    +    The error message in case of computing a summary for non-existent
    +    submodules in the C version is different from that of the shell version.
    +    Since the new error message is not marked for translation, change the
    +    'test_i18ngrep' in t7421.4 to 'grep'.
    +
    +    Mentored-by: Christian Couder <chriscool@tuxfamily.org>
    +    Mentored-by: Stefan Beller <stefanbeller@gmail.com>
         Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
    +    Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
         Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
         Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
     
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +  const char *prefix;
     +  unsigned int cached: 1;
     +  unsigned int for_status: 1;
    -+  unsigned int quiet: 1;
     +  unsigned int files: 1;
     +  int summary_limit;
     +};
    -+#define SUMMARY_CB_INIT { 0, NULL, NULL, 0, 0, 0, 0, 0 }
    ++#define SUMMARY_CB_INIT { 0, NULL, NULL, 0, 0, 0, 0 }
     +
     +enum diff_cmd {
     +  DIFF_INDEX,
     +  DIFF_FILES
     +};
     +
    -+static int verify_submodule_object_name(const char *sm_path,
    -+                                    const char *sha1)
    ++static char* verify_submodule_committish(const char *sm_path,
    ++                                   const char *committish)
     +{
     +  struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
    ++  struct strbuf result = STRBUF_INIT;
     +
     +  cp_rev_parse.git_cmd = 1;
    -+  cp_rev_parse.no_stdout = 1;
     +  cp_rev_parse.dir = sm_path;
     +  prepare_submodule_repo_env(&cp_rev_parse.env_array);
     +  argv_array_pushl(&cp_rev_parse.args, "rev-parse", "-q",
    -+                   "--verify", NULL);
    -+  argv_array_pushf(&cp_rev_parse.args, "%s^0", sha1);
    ++                   "--short", NULL);
    ++  argv_array_pushf(&cp_rev_parse.args, "%s^0", committish);
    ++  argv_array_push(&cp_rev_parse.args, "--");
     +
    -+  if (run_command(&cp_rev_parse))
    -+          return 1;
    ++  if (capture_command(&cp_rev_parse, &result, 0))
    ++          return NULL;
     +
    -+  return 0;
    ++  strbuf_trim_trailing_newline(&result);
    ++  return strbuf_detach(&result, NULL);
     +}
     +
    -+static void print_submodule_summary(struct summary_cb *info, int errmsg,
    -+                                int total_commits, int missing_src,
    -+                                int missing_dst, const char *displaypath,
    -+                                int is_sm_git_dir, struct module_cb *p)
    ++static void print_submodule_summary(struct summary_cb *info, char* errmsg,
    ++                              int total_commits, const char *displaypath,
    ++                              const char *src_abbrev, const char *dst_abbrev,
    ++                              int missing_src, int missing_dst,
    ++                              struct module_cb *p)
     +{
     +  if (p->status == 'T') {
     +          if (S_ISGITLINK(p->mod_dst))
     +                  printf(_("* %s %s(blob)->%s(submodule)"),
    -+                           displaypath, find_unique_abbrev(&p->oid_src, 7),
    -+                           find_unique_abbrev(&p->oid_dst, 7));
    ++                           displaypath, src_abbrev, dst_abbrev);
     +          else
     +                  printf(_("* %s %s(submodule)->%s(blob)"),
    -+                           displaypath, find_unique_abbrev(&p->oid_src, 7),
    -+                           find_unique_abbrev(&p->oid_dst, 7));
    ++                           displaypath, src_abbrev, dst_abbrev);
     +  } else {
     +          printf("* %s %s...%s",
    -+                  displaypath, find_unique_abbrev(&p->oid_src, 7),
    -+                  find_unique_abbrev(&p->oid_dst, 7));
    ++                  displaypath, src_abbrev, dst_abbrev);
     +  }
     +
     +  if (total_commits < 0)
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +          printf(" (%d):\n", total_commits);
     +
     +  if (errmsg) {
    -+          /*
    -+           * Don't give error msg for modification whose dst is not
    -+           * submodule, i.e. deleted or changed to blob
    -+           */
    -+          if (S_ISGITLINK(p->mod_src)) {
    -+                  if (missing_src && missing_dst) {
    -+                          printf(_("  Warn: %s doesn't contain commits %s and %s\n"),
    -+                                 displaypath, oid_to_hex(&p->oid_src),
    -+                                 oid_to_hex(&p->oid_dst));
    -+                  } else if (missing_src) {
    -+                          printf(_("  Warn: %s doesn't contain commit %s\n"),
    -+                                 displaypath, oid_to_hex(&p->oid_src));
    -+                  } else {
    -+                          printf(_("  Warn: %s doesn't contain commit %s\n"),
    -+                                 displaypath, oid_to_hex(&p->oid_dst));
    -+                  }
    -+          }
    -+  } else if (is_sm_git_dir) {
    ++          printf(_("%s"), errmsg);
    ++  } else if (total_commits > 0) {
     +          struct child_process cp_log = CHILD_PROCESS_INIT;
     +
     +          cp_log.git_cmd = 1;
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +                  argv_array_pushl(&cp_log.args, "--pretty=  %m %s",
     +                                   "--first-parent", NULL);
     +                  argv_array_pushf(&cp_log.args, "%s...%s",
    -+                                   oid_to_hex(&p->oid_src),
    -+                                   oid_to_hex(&p->oid_dst));
    ++                                   src_abbrev,
    ++                                   dst_abbrev);
     +          } else if (S_ISGITLINK(p->mod_dst)) {
     +                  argv_array_pushl(&cp_log.args, "--pretty=  > %s",
    -+                                   "-1", oid_to_hex(&p->oid_dst), NULL);
    ++                                   "-1", dst_abbrev, NULL);
     +          } else {
     +                  argv_array_pushl(&cp_log.args, "--pretty=  < %s",
    -+                                   "-1", oid_to_hex(&p->oid_src), NULL);
    ++                                   "-1", src_abbrev, NULL);
     +          }
     +          run_command(&cp_log);
     +  }
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +static void generate_submodule_summary(struct summary_cb *info,
     +                                 struct module_cb *p)
     +{
    -+  int missing_src = 0;
    -+  int missing_dst = 0;
    -+  char *displaypath;
    -+  int errmsg = 0;
    ++  char *displaypath, *src_abbrev, *dst_abbrev;
    ++  int missing_src = 0, missing_dst = 0;
    ++  char *errmsg = NULL;
     +  int total_commits = -1;
    -+  int is_sm_git_dir = 0;
    -+  struct strbuf sm_git_dir_sb = STRBUF_INIT;
     +
     +  if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
     +          if (S_ISGITLINK(p->mod_dst)) {
    -+                  /*
    -+                   * NEEDSWORK: avoid using separate process with
    -+                   * the help of the function head_ref_submodule()
    -+                   */
    -+                  struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
    -+                  struct strbuf sb_rev_parse = STRBUF_INIT;
    -+
    -+                  cp_rev_parse.git_cmd = 1;
    -+                  cp_rev_parse.no_stderr = 1;
    -+                  cp_rev_parse.dir = p->sm_path;
    -+                  prepare_submodule_repo_env(&cp_rev_parse.env_array);
    -+
    -+                  argv_array_pushl(&cp_rev_parse.args, "rev-parse",
    -+                                   "HEAD", NULL);
    -+                  if (!capture_command(&cp_rev_parse, &sb_rev_parse, 0)) {
    -+                          strbuf_strip_suffix(&sb_rev_parse, "\n");
    -+                          get_oid_hex(sb_rev_parse.buf, &p->oid_dst);
    -+                  }
    -+                  strbuf_release(&sb_rev_parse);
    ++                  struct ref_store *refs = get_submodule_ref_store(p->sm_path);
    ++                  if (refs)
    ++                          refs_head_ref(refs, handle_submodule_head_ref, &p->oid_dst);
     +          } else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
    -+                  struct child_process cp_hash_object = CHILD_PROCESS_INIT;
    -+                  struct strbuf sb_hash_object = STRBUF_INIT;
    -+
    -+                  cp_hash_object.git_cmd = 1;
    -+                  argv_array_pushl(&cp_hash_object.args, "hash-object",
    -+                                   p->sm_path, NULL);
    -+                  if (!capture_command(&cp_hash_object,
    -+                                       &sb_hash_object, 0)) {
    -+                          strbuf_strip_suffix(&sb_hash_object, "\n");
    -+                          get_oid_hex(sb_hash_object.buf, &p->oid_dst);
    -+                  }
    -+                  strbuf_release(&sb_hash_object);
    ++                  struct stat st;
    ++                  int fd = open(p->sm_path, O_RDONLY);
    ++
    ++                  if (fd < 0 || fstat(fd, &st) < 0 ||
    ++                      index_fd(&the_index, &p->oid_dst, fd, &st, OBJ_BLOB,
    ++                               p->sm_path, 0))
    ++                          error(_("couldn't hash object from '%s'"), p->sm_path);
     +          } else {
    ++                  /* for a submodule removal (mode:0000000), don't warn */
     +                  if (p->mod_dst)
    -+                          die(_("unexpected mode %d\n"), p->mod_dst);
    ++                          warning(_("unexpected mode %d\n"), p->mod_dst);
     +          }
     +  }
     +
    -+  strbuf_addstr(&sm_git_dir_sb, p->sm_path);
    -+  if (is_nonbare_repository_dir(&sm_git_dir_sb))
    -+          is_sm_git_dir = 1;
    -+
    -+  if (is_sm_git_dir && S_ISGITLINK(p->mod_src))
    -+          missing_src = verify_submodule_object_name(p->sm_path,
    -+                                                     oid_to_hex(&p->oid_src));
    ++  if (S_ISGITLINK(p->mod_src)) {
    ++          src_abbrev = verify_submodule_committish(p->sm_path,
    ++                                                   oid_to_hex(&p->oid_src));
    ++          if (!src_abbrev) {
    ++                  missing_src = 1;
    ++                  /*
    ++                   * As `rev-parse` failed, we fallback to getting
    ++                   * the abbreviated hash using oid_src. We do
    ++                   * this as we might still need the abbreviated
    ++                   * hash in cases like a submodule type change, etc.
    ++                   */
    ++                  src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
    ++          }
    ++  } else {
    ++          /*
    ++           * The source does not point to a submodule.
    ++           * So, we fallback to getting the abbreviation using
    ++           * oid_src as we might still need the abbreviated
    ++           * hash in cases like submodule add, etc.
    ++           */
    ++          src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
    ++  }
     +
    -+  if (is_sm_git_dir && S_ISGITLINK(p->mod_dst))
    -+          missing_dst = verify_submodule_object_name(p->sm_path,
    -+                                                     oid_to_hex(&p->oid_dst));
    ++  if (S_ISGITLINK(p->mod_dst)) {
    ++          dst_abbrev = verify_submodule_committish(p->sm_path,
    ++                                                   oid_to_hex(&p->oid_dst));
    ++          if (!dst_abbrev) {
    ++                  missing_dst = 1;
    ++                  /*
    ++                   * As `rev-parse` failed, we fallback to getting
    ++                   * the abbreviated hash using oid_dst. We do
    ++                   * this as we might still need the abbreviated
    ++                   * hash in cases like a submodule type change, etc.
    ++                   */
    ++                  dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
    ++          }
    ++  } else {
    ++          /*
    ++           * The destination does not point to a submodule.
    ++           * So, we fallback to getting the abbreviation using
    ++           * oid_dst as we might still need the abbreviated
    ++           * hash in cases like a submodule removal, etc.
    ++           */
    ++          dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
    ++  }
     +
     +  displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
     +
    -+  if (!missing_dst && !missing_src) {
    -+          if (is_sm_git_dir) {
    -+                  struct child_process cp_rev_list = CHILD_PROCESS_INIT;
    -+                  struct strbuf sb_rev_list = STRBUF_INIT;
    -+                  char *range;
    -+
    -+                  if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
    -+                          range = xstrfmt("%s...%s", oid_to_hex(&p->oid_src),
    -+                                          oid_to_hex(&p->oid_dst));
    -+                  else if (S_ISGITLINK(p->mod_src))
    -+                          range = xstrdup(oid_to_hex(&p->oid_src));
    -+                  else
    -+                          range = xstrdup(oid_to_hex(&p->oid_dst));
    -+
    -+                  cp_rev_list.git_cmd = 1;
    -+                  cp_rev_list.dir = p->sm_path;
    -+                  prepare_submodule_repo_env(&cp_rev_list.env_array);
    -+
    -+                  argv_array_pushl(&cp_rev_list.args, "rev-list",
    -+                                   "--first-parent", range, "--", NULL);
    -+                  if (!capture_command(&cp_rev_list, &sb_rev_list, 0)) {
    -+                          if (sb_rev_list.len)
    -+                                  total_commits = count_lines(sb_rev_list.buf,
    -+                                                              sb_rev_list.len);
    -+                          else
    -+                                  total_commits = 0;
    -+                  }
    ++  if (!missing_src && !missing_dst) {
    ++          struct child_process cp_rev_list = CHILD_PROCESS_INIT;
    ++          struct strbuf sb_rev_list = STRBUF_INIT;
     +
    -+                  free(range);
    -+                  strbuf_release(&sb_rev_list);
    -+          }
    ++          argv_array_pushl(&cp_rev_list.args, "rev-list",
    ++                           "--first-parent", "--count", NULL);
    ++          if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
    ++                  argv_array_pushf(&cp_rev_list.args, "%s...%s",
    ++                                   src_abbrev,
    ++                                   dst_abbrev);
    ++          else
    ++                  argv_array_push(&cp_rev_list.args,
    ++                                  S_ISGITLINK(p->mod_src) ?
    ++                                  src_abbrev :
    ++                                  dst_abbrev);
    ++          argv_array_push(&cp_rev_list.args, "--");
    ++
    ++          cp_rev_list.git_cmd = 1;
    ++          cp_rev_list.dir = p->sm_path;
    ++          prepare_submodule_repo_env(&cp_rev_list.env_array);
    ++
    ++          if (!capture_command(&cp_rev_list, &sb_rev_list, 0))
    ++                  total_commits = atoi(sb_rev_list.buf);
    ++
    ++          strbuf_release(&sb_rev_list);
     +  } else {
    -+          errmsg = 1;
    ++          /*
    ++           * Don't give error msg for modification whose dst is not
    ++           * submodule, i.e., deleted or changed to blob
    ++           */
    ++          if (S_ISGITLINK(p->mod_dst)) {
    ++                  struct strbuf errmsg_str = STRBUF_INIT;
    ++                  if (missing_src && missing_dst) {
    ++                          strbuf_addf(&errmsg_str, "  Warn: %s doesn't contain commits %s and %s\n",
    ++                                      displaypath, oid_to_hex(&p->oid_src),
    ++                                      oid_to_hex(&p->oid_dst));
    ++                  } else {
    ++                          strbuf_addf(&errmsg_str, "  Warn: %s doesn't contain commit %s\n",
    ++                                      displaypath, missing_src ?
    ++                                      oid_to_hex(&p->oid_src) :
    ++                                      oid_to_hex(&p->oid_dst));
    ++                  }
    ++                  errmsg = strbuf_detach(&errmsg_str, NULL);
    ++          }
     +  }
     +
     +  print_submodule_summary(info, errmsg, total_commits,
    -+                          missing_src, missing_dst,
    -+                          displaypath, is_sm_git_dir, p);
    ++                          displaypath, src_abbrev,
    ++                          dst_abbrev, missing_src,
    ++                          missing_dst, p);
     +
     +  free(displaypath);
    -+  strbuf_release(&sm_git_dir_sb);
    ++  free(src_abbrev);
    ++  free(dst_abbrev);
     +}
     +
     +static void prepare_submodule_summary(struct summary_cb *info,
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +{
     +  int i;
     +  for (i = 0; i < list->nr; i++) {
    ++          const struct submodule *sub;
     +          struct module_cb *p = list->entries[i];
    -+          struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
    ++          struct strbuf sm_gitdir = STRBUF_INIT;
     +
     +          if (p->status == 'D' || p->status == 'T') {
     +                  generate_submodule_summary(info, p);
     +                  continue;
     +          }
     +
    -+          if (info->for_status) {
    -+                  char *config_key;
    -+                  const char *ignore_config = "none";
    ++          if (info->for_status && p->status != 'A' &&
    ++              (sub = submodule_from_path(the_repository,
    ++                                         &null_oid, p->sm_path))) {
    ++                  char *config_key = NULL;
     +                  const char *value;
    -+                  const struct submodule *sub = submodule_from_path(the_repository,
    -+                                                                    &null_oid,
    -+                                                                    p->sm_path);
    -+
    -+                  if (sub && p->status != 'A') {
    -+                          config_key = xstrfmt("submodule.%s.ignore",
    -+                                               sub->name);
    -+                          if (!git_config_get_string_const(config_key, &value))
    -+                                  ignore_config = value;
    -+                          else if (sub->ignore)
    -+                                  ignore_config = sub->ignore;
    -+
    -+                          free(config_key);
    -+                          if (!strcmp(ignore_config, "all"))
    -+                                  continue;
    -+                  }
    ++                  int ignore_all = 0;
    ++
    ++                  config_key = xstrfmt("submodule.%s.ignore",
    ++                                       sub->name);
    ++                  if (!git_config_get_string_const(config_key, &value))
    ++                          ignore_all = !strcmp(value, "all");
    ++                  else if (sub->ignore)
    ++                          ignore_all = !strcmp(sub->ignore, "all");
    ++
    ++                  free(config_key);
    ++                  if (ignore_all)
    ++                          continue;
     +          }
     +
     +          /* Also show added or modified modules which are checked out */
    -+          cp_rev_parse.dir = p->sm_path;
    -+          cp_rev_parse.git_cmd = 1;
    -+          cp_rev_parse.no_stderr = 1;
    -+          cp_rev_parse.no_stdout = 1;
    -+
    -+          argv_array_pushl(&cp_rev_parse.args, "rev-parse",
    -+                           "--git-dir", NULL);
    -+
    -+          if (!run_command(&cp_rev_parse))
    ++          strbuf_addstr(&sm_gitdir, p->sm_path);
    ++          if (is_nonbare_repository_dir(&sm_gitdir))
     +                  generate_submodule_summary(info, p);
    ++          strbuf_release(&sm_gitdir);
     +  }
     +}
     +
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +  }
     +}
     +
    -+static int compute_summary_module_list(char *head,
    -+                                   struct summary_cb *info,
    -+                                   enum diff_cmd diff_cmd)
    ++static int compute_summary_module_list(struct object_id *head_oid,
    ++                                 struct summary_cb *info,
    ++                                 enum diff_cmd diff_cmd)
     +{
     +  struct argv_array diff_args = ARGV_ARRAY_INIT;
     +  struct rev_info rev;
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +          argv_array_push(&diff_args, "--cached");
     +  argv_array_pushl(&diff_args, "--ignore-submodules=dirty", "--raw",
     +                   NULL);
    -+  if (head)
    -+          argv_array_push(&diff_args, head);
    ++  if (head_oid)
    ++          argv_array_push(&diff_args, oid_to_hex(head_oid));
     +  argv_array_push(&diff_args, "--");
     +  if (info->argc)
     +          argv_array_pushv(&diff_args, info->argv);
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +  rev.diffopt.format_callback_data = &list;
     +
     +  if (!info->cached) {
    -+          if (diff_cmd ==  DIFF_INDEX)
    ++          if (diff_cmd == DIFF_INDEX)
     +                  setup_work_tree();
     +          if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
     +                  perror("read_cache_preload");
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +  struct summary_cb info = SUMMARY_CB_INIT;
     +  int cached = 0;
     +  int for_status = 0;
    -+  int quiet = 0;
     +  int files = 0;
     +  int summary_limit = -1;
    -+  struct child_process cp_rev = CHILD_PROCESS_INIT;
    -+  struct strbuf sb = STRBUF_INIT;
     +  enum diff_cmd diff_cmd = DIFF_INDEX;
    ++  struct object_id head_oid;
     +  int ret;
     +
     +  struct option module_summary_options[] = {
    -+          OPT__QUIET(&quiet, N_("Suppress output of summarising submodules")),
     +          OPT_BOOL(0, "cached", &cached,
    -+                   N_("Use the commit stored in the index instead of the submodule HEAD")),
    ++                   N_("use the commit stored in the index instead of the submodule HEAD")),
     +          OPT_BOOL(0, "files", &files,
    -+                   N_("To compare the commit in the index with that in the submodule HEAD")),
    ++                   N_("to compare the commit in the index with that in the submodule HEAD")),
     +          OPT_BOOL(0, "for-status", &for_status,
    -+                   N_("Skip submodules with 'ignore_config' value set to 'all'")),
    ++                   N_("skip submodules with 'ignore_config' value set to 'all'")),
     +          OPT_INTEGER('n', "summary-limit", &summary_limit,
    -+                       N_("Limit the summary size")),
    ++                       N_("limit the summary size")),
     +          OPT_END()
     +  };
     +
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +  if (!summary_limit)
     +          return 0;
     +
    -+  cp_rev.git_cmd = 1;
    -+  argv_array_pushl(&cp_rev.args, "rev-parse", "-q", "--verify",
    -+                   argc ? argv[0] : "HEAD", NULL);
    -+
    -+  if (!capture_command(&cp_rev, &sb, 0)) {
    -+          strbuf_strip_suffix(&sb, "\n");
    ++  if (!get_oid(argc ? argv[0] : "HEAD", &head_oid)) {
     +          if (argc) {
     +                  argv++;
     +                  argc--;
     +          }
     +  } else if (!argc || !strcmp(argv[0], "HEAD")) {
     +          /* before the first commit: compare with an empty tree */
    -+          struct stat st;
    -+          struct object_id oid;
    -+          if (fstat(0, &st) < 0 || index_fd(&the_index, &oid, 0, &st, 2,
    -+                                            prefix, 3))
    -+                  die("Unable to add %s to database", oid.hash);
    -+          strbuf_addstr(&sb, oid_to_hex(&oid));
    ++          oidcpy(&head_oid, the_hash_algo->empty_tree);
     +          if (argc) {
     +                  argv++;
     +                  argc--;
     +          }
     +  } else {
    -+          strbuf_addstr(&sb, "HEAD");
    ++          if (get_oid("HEAD", &head_oid))
    ++                  die(_("could not fetch a revision for HEAD"));
     +  }
     +
     +  if (files) {
    @@ builtin/submodule--helper.c: static int module_name(int argc, const char **argv,
     +  info.argv = argv;
     +  info.prefix = prefix;
     +  info.cached = !!cached;
    ++  info.files = !!files;
     +  info.for_status = !!for_status;
    -+  info.quiet = quiet;
    -+  info.files = files;
     +  info.summary_limit = summary_limit;
     +
    -+  ret = compute_summary_module_list((diff_cmd == DIFF_FILES) ? NULL : sb.buf,
    -+                                     &info, diff_cmd);
    -+  strbuf_release(&sb);
    ++  ret = compute_summary_module_list((diff_cmd == DIFF_INDEX) ? &head_oid : NULL,
    ++                                    &info, diff_cmd);
     +  return ret;
     +}
     +
    @@ git-submodule.sh: cmd_summary() {
     -          fi
     -          echo
     -  done
    -+  git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${GIT_QUIET:+--quiet} ${prefix:+--prefix "$prefix"} ${for_status:+--for-status} ${files:+--files} ${cached:+--cached} ${summary_limit:+-n $summary_limit} "$@"
    ++  git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${prefix:+--prefix "$prefix"} ${files:+--files} ${cached:+--cached} ${for_status:+--for-status} ${summary_limit:+-n $summary_limit} -- "$@"
      }
      #
      # List all submodules, prefixed with:
    +
    + ## t/t7421-submodule-summary-add.sh ##
    +@@ t/t7421-submodule-summary-add.sh: test_expect_success 'submodule summary output for submodules with changed paths'
    +   git commit -m "change submodule path" &&
    +   rev=$(git -C sm rev-parse --short HEAD^) &&
    +   git submodule summary HEAD^^ -- my-subm >actual 2>err &&
    +-  test_i18ngrep "fatal:.*my-subm" err &&
    ++  grep "fatal:.*my-subm" err &&
    +   cat >expected <<-EOF &&
    +   * my-subm ${rev}...0000000:
    + 

Prathamesh Chavan (1):
  submodule: port submodule subcommand 'summary' from shell to C

Shourya Shukla (4):
  submodule: expose the '--for-status' option of summary
  submodule: remove extra line feeds between callback struct and macro
  submodule: rename helper functions to avoid ambiguity
  t7421: introduce a test script for verifying 'summary' output

 Documentation/git-submodule.txt        |   8 +-
 builtin/submodule--helper.c            | 439 ++++++++++++++++++++++++-
 contrib/completion/git-completion.bash |   2 +-
 diff.c                                 |   2 +-
 git-submodule.sh                       | 188 +----------
 submodule.c                            |  10 +-
 submodule.h                            |   2 +-
 t/t7421-submodule-summary-add.sh       |  69 ++++
 8 files changed, 522 insertions(+), 198 deletions(-)
 create mode 100755 t/t7421-submodule-summary-add.sh

-- 
2.28.0


^ permalink raw reply	[relevance 4%]

* [PATCH v2 5/5] submodule: port submodule subcommand 'summary' from shell to C
  2020-08-06 16:40  4% [GSoC][PATCH v2 0/5] submodule: port " Shourya Shukla
@ 2020-08-06 16:41 18% ` Shourya Shukla
    1 sibling, 0 replies; 200+ results
From: Shourya Shukla @ 2020-08-06 16:41 UTC (permalink / raw)
  To: git
  Cc: gitster, christian.couder, kaartic.sivaraam, johannes.schindelin,
	liu.denton, Prathamesh Chavan, Christian Couder, Stefan Beller,
	Johannes Schindelin, Shourya Shukla

From: Prathamesh Chavan <pc44800@gmail.com>

Convert submodule subcommand 'summary' to a builtin and call it via
'git-submodule.sh'.

The shell version had to call $diff_cmd twice, once to find the modified
modules cared by the user and then again, with that list of modules
to do various operations for computing the summary of those modules.
On the other hand, the C version does not need a second call to
$diff_cmd since it reuses the module list from the first call to do the
aforementioned tasks.

In the C version, we use the combination of setting a child process'
working directory to the submodule path and then calling
'prepare_submodule_repo_env()' which also sets the 'GIT_DIR' to '.git',
so that we can be certain that those spawned processes will not access
the superproject's ODB by mistake.

A behavioural difference between the C and the shell version is that the
shell version outputs two line feeds after the 'git log' output when run
outside of the tests while the C version outputs one line feed in any
case. The reason for this is that the shell version calls log with
'--pretty=format:<fmt>' whose output is followed by two echo
calls; 'format' does not have "terminator" semantics like its 'tformat'
counterpart. So, the log output is terminated by a newline only when
invoked by the user and not when invoked from the scripts. This results
in the one & two line feed differences in the shell version.
On the other hand, the C version calls log with '--pretty=<fmt>'
which is equivalent to '--pretty:tformat:<fmt>' which is then
followed by a 'printf("\n")'. Due to its "terminator" semantics the
log output is always terminated by newline and hence one line feed in
any case.

Also, when we try to pass an option-like argument after a non-option
argument, for instance:

    git submodule summary HEAD --foo-bar

    (or)

    git submodule summary HEAD --cached

That argument would be treated like a path to the submodule for which
the user is requesting a summary. So, the option ends up having no
effect. Though, passing '--quiet' is an exception to this:

    git submodule summary HEAD --quiet

While 'summary' doesn't support '--quiet', we don't get an output for
the above command as '--quiet' is treated as a path which means we get
an output only if a submodule whose path is '--quiet' exists.

The error message in case of computing a summary for non-existent
submodules in the C version is different from that of the shell version.
Since the new error message is not marked for translation, change the
'test_i18ngrep' in t7421.4 to 'grep'.

Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Mentored-by: Stefan Beller <stefanbeller@gmail.com>
Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
---
 builtin/submodule--helper.c      | 436 +++++++++++++++++++++++++++++++
 git-submodule.sh                 | 186 +------------
 t/t7421-submodule-summary-add.sh |   2 +-
 3 files changed, 438 insertions(+), 186 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 3641718d0a..43ed2f645f 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -927,6 +927,441 @@ static int module_name(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+struct module_cb {
+	unsigned int mod_src;
+	unsigned int mod_dst;
+	struct object_id oid_src;
+	struct object_id oid_dst;
+	char status;
+	const char *sm_path;
+};
+#define MODULE_CB_INIT { 0, 0, NULL, NULL, '\0', NULL }
+
+struct module_cb_list {
+	struct module_cb **entries;
+	int alloc, nr;
+};
+#define MODULE_CB_LIST_INIT { NULL, 0, 0 }
+
+struct summary_cb {
+	int argc;
+	const char **argv;
+	const char *prefix;
+	unsigned int cached: 1;
+	unsigned int for_status: 1;
+	unsigned int files: 1;
+	int summary_limit;
+};
+#define SUMMARY_CB_INIT { 0, NULL, NULL, 0, 0, 0, 0 }
+
+enum diff_cmd {
+	DIFF_INDEX,
+	DIFF_FILES
+};
+
+static char* verify_submodule_committish(const char *sm_path,
+					 const char *committish)
+{
+	struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
+	struct strbuf result = STRBUF_INIT;
+
+	cp_rev_parse.git_cmd = 1;
+	cp_rev_parse.dir = sm_path;
+	prepare_submodule_repo_env(&cp_rev_parse.env_array);
+	argv_array_pushl(&cp_rev_parse.args, "rev-parse", "-q",
+			 "--short", NULL);
+	argv_array_pushf(&cp_rev_parse.args, "%s^0", committish);
+	argv_array_push(&cp_rev_parse.args, "--");
+
+	if (capture_command(&cp_rev_parse, &result, 0))
+		return NULL;
+
+	strbuf_trim_trailing_newline(&result);
+	return strbuf_detach(&result, NULL);
+}
+
+static void print_submodule_summary(struct summary_cb *info, char* errmsg,
+				    int total_commits, const char *displaypath,
+				    const char *src_abbrev, const char *dst_abbrev,
+				    int missing_src, int missing_dst,
+				    struct module_cb *p)
+{
+	if (p->status == 'T') {
+		if (S_ISGITLINK(p->mod_dst))
+			printf(_("* %s %s(blob)->%s(submodule)"),
+				 displaypath, src_abbrev, dst_abbrev);
+		else
+			printf(_("* %s %s(submodule)->%s(blob)"),
+				 displaypath, src_abbrev, dst_abbrev);
+	} else {
+		printf("* %s %s...%s",
+			displaypath, src_abbrev, dst_abbrev);
+	}
+
+	if (total_commits < 0)
+		printf(":\n");
+	else
+		printf(" (%d):\n", total_commits);
+
+	if (errmsg) {
+		printf(_("%s"), errmsg);
+	} else if (total_commits > 0) {
+		struct child_process cp_log = CHILD_PROCESS_INIT;
+
+		cp_log.git_cmd = 1;
+		cp_log.dir = p->sm_path;
+		prepare_submodule_repo_env(&cp_log.env_array);
+		argv_array_pushl(&cp_log.args, "log", NULL);
+
+		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
+			if (info->summary_limit > 0)
+				argv_array_pushf(&cp_log.args, "-%d",
+						 info->summary_limit);
+
+			argv_array_pushl(&cp_log.args, "--pretty=  %m %s",
+					 "--first-parent", NULL);
+			argv_array_pushf(&cp_log.args, "%s...%s",
+					 src_abbrev,
+					 dst_abbrev);
+		} else if (S_ISGITLINK(p->mod_dst)) {
+			argv_array_pushl(&cp_log.args, "--pretty=  > %s",
+					 "-1", dst_abbrev, NULL);
+		} else {
+			argv_array_pushl(&cp_log.args, "--pretty=  < %s",
+					 "-1", src_abbrev, NULL);
+		}
+		run_command(&cp_log);
+	}
+	printf("\n");
+}
+
+static void generate_submodule_summary(struct summary_cb *info,
+				       struct module_cb *p)
+{
+	char *displaypath, *src_abbrev, *dst_abbrev;
+	int missing_src = 0, missing_dst = 0;
+	char *errmsg = NULL;
+	int total_commits = -1;
+
+	if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
+		if (S_ISGITLINK(p->mod_dst)) {
+			struct ref_store *refs = get_submodule_ref_store(p->sm_path);
+			if (refs)
+				refs_head_ref(refs, handle_submodule_head_ref, &p->oid_dst);
+		} else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
+			struct stat st;
+			int fd = open(p->sm_path, O_RDONLY);
+
+			if (fd < 0 || fstat(fd, &st) < 0 ||
+			    index_fd(&the_index, &p->oid_dst, fd, &st, OBJ_BLOB,
+				     p->sm_path, 0))
+				error(_("couldn't hash object from '%s'"), p->sm_path);
+		} else {
+			/* for a submodule removal (mode:0000000), don't warn */
+			if (p->mod_dst)
+				warning(_("unexpected mode %d\n"), p->mod_dst);
+		}
+	}
+
+	if (S_ISGITLINK(p->mod_src)) {
+		src_abbrev = verify_submodule_committish(p->sm_path,
+							 oid_to_hex(&p->oid_src));
+		if (!src_abbrev) {
+			missing_src = 1;
+			/*
+			 * As `rev-parse` failed, we fallback to getting
+			 * the abbreviated hash using oid_src. We do
+			 * this as we might still need the abbreviated
+			 * hash in cases like a submodule type change, etc.
+			 */
+			src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
+		}
+	} else {
+		/*
+		 * The source does not point to a submodule.
+		 * So, we fallback to getting the abbreviation using
+		 * oid_src as we might still need the abbreviated
+		 * hash in cases like submodule add, etc.
+		 */
+		src_abbrev = xstrndup(oid_to_hex(&p->oid_src), 7);
+	}
+
+	if (S_ISGITLINK(p->mod_dst)) {
+		dst_abbrev = verify_submodule_committish(p->sm_path,
+							 oid_to_hex(&p->oid_dst));
+		if (!dst_abbrev) {
+			missing_dst = 1;
+			/*
+			 * As `rev-parse` failed, we fallback to getting
+			 * the abbreviated hash using oid_dst. We do
+			 * this as we might still need the abbreviated
+			 * hash in cases like a submodule type change, etc.
+			 */
+			dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
+		}
+	} else {
+		/*
+		 * The destination does not point to a submodule.
+		 * So, we fallback to getting the abbreviation using
+		 * oid_dst as we might still need the abbreviated
+		 * hash in cases like a submodule removal, etc.
+		 */
+		dst_abbrev = xstrndup(oid_to_hex(&p->oid_dst), 7);
+	}
+
+	displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
+
+	if (!missing_src && !missing_dst) {
+		struct child_process cp_rev_list = CHILD_PROCESS_INIT;
+		struct strbuf sb_rev_list = STRBUF_INIT;
+
+		argv_array_pushl(&cp_rev_list.args, "rev-list",
+				 "--first-parent", "--count", NULL);
+		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
+			argv_array_pushf(&cp_rev_list.args, "%s...%s",
+					 src_abbrev,
+					 dst_abbrev);
+		else
+			argv_array_push(&cp_rev_list.args,
+					S_ISGITLINK(p->mod_src) ?
+					src_abbrev :
+					dst_abbrev);
+		argv_array_push(&cp_rev_list.args, "--");
+
+		cp_rev_list.git_cmd = 1;
+		cp_rev_list.dir = p->sm_path;
+		prepare_submodule_repo_env(&cp_rev_list.env_array);
+
+		if (!capture_command(&cp_rev_list, &sb_rev_list, 0))
+			total_commits = atoi(sb_rev_list.buf);
+
+		strbuf_release(&sb_rev_list);
+	} else {
+		/*
+		 * Don't give error msg for modification whose dst is not
+		 * submodule, i.e., deleted or changed to blob
+		 */
+		if (S_ISGITLINK(p->mod_dst)) {
+			struct strbuf errmsg_str = STRBUF_INIT;
+			if (missing_src && missing_dst) {
+				strbuf_addf(&errmsg_str, "  Warn: %s doesn't contain commits %s and %s\n",
+					    displaypath, oid_to_hex(&p->oid_src),
+					    oid_to_hex(&p->oid_dst));
+			} else {
+				strbuf_addf(&errmsg_str, "  Warn: %s doesn't contain commit %s\n",
+					    displaypath, missing_src ?
+					    oid_to_hex(&p->oid_src) :
+					    oid_to_hex(&p->oid_dst));
+			}
+			errmsg = strbuf_detach(&errmsg_str, NULL);
+		}
+	}
+
+	print_submodule_summary(info, errmsg, total_commits,
+				displaypath, src_abbrev,
+				dst_abbrev, missing_src,
+				missing_dst, p);
+
+	free(displaypath);
+	free(src_abbrev);
+	free(dst_abbrev);
+}
+
+static void prepare_submodule_summary(struct summary_cb *info,
+				      struct module_cb_list *list)
+{
+	int i;
+	for (i = 0; i < list->nr; i++) {
+		const struct submodule *sub;
+		struct module_cb *p = list->entries[i];
+		struct strbuf sm_gitdir = STRBUF_INIT;
+
+		if (p->status == 'D' || p->status == 'T') {
+			generate_submodule_summary(info, p);
+			continue;
+		}
+
+		if (info->for_status && p->status != 'A' &&
+		    (sub = submodule_from_path(the_repository,
+					       &null_oid, p->sm_path))) {
+			char *config_key = NULL;
+			const char *value;
+			int ignore_all = 0;
+
+			config_key = xstrfmt("submodule.%s.ignore",
+					     sub->name);
+			if (!git_config_get_string_const(config_key, &value))
+				ignore_all = !strcmp(value, "all");
+			else if (sub->ignore)
+				ignore_all = !strcmp(sub->ignore, "all");
+
+			free(config_key);
+			if (ignore_all)
+				continue;
+		}
+
+		/* Also show added or modified modules which are checked out */
+		strbuf_addstr(&sm_gitdir, p->sm_path);
+		if (is_nonbare_repository_dir(&sm_gitdir))
+			generate_submodule_summary(info, p);
+		strbuf_release(&sm_gitdir);
+	}
+}
+
+static void submodule_summary_callback(struct diff_queue_struct *q,
+				       struct diff_options *options,
+				       void *data)
+{
+	int i;
+	struct module_cb_list *list = data;
+	for (i = 0; i < q->nr; i++) {
+		struct diff_filepair *p = q->queue[i];
+		struct module_cb *temp;
+
+		if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
+			continue;
+		temp = (struct module_cb*)malloc(sizeof(struct module_cb));
+		temp->mod_src = p->one->mode;
+		temp->mod_dst = p->two->mode;
+		temp->oid_src = p->one->oid;
+		temp->oid_dst = p->two->oid;
+		temp->status = p->status;
+		temp->sm_path = xstrdup(p->one->path);
+
+		ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
+		list->entries[list->nr++] = temp;
+	}
+}
+
+static const char *get_diff_cmd(enum diff_cmd diff_cmd)
+{
+	switch (diff_cmd) {
+	case DIFF_INDEX: return "diff-index";
+	case DIFF_FILES: return "diff-files";
+	default: BUG("bad diff_cmd value %d", diff_cmd);
+	}
+}
+
+static int compute_summary_module_list(struct object_id *head_oid,
+				       struct summary_cb *info,
+				       enum diff_cmd diff_cmd)
+{
+	struct argv_array diff_args = ARGV_ARRAY_INIT;
+	struct rev_info rev;
+	struct module_cb_list list = MODULE_CB_LIST_INIT;
+
+	argv_array_push(&diff_args, get_diff_cmd(diff_cmd));
+	if (info->cached)
+		argv_array_push(&diff_args, "--cached");
+	argv_array_pushl(&diff_args, "--ignore-submodules=dirty", "--raw",
+			 NULL);
+	if (head_oid)
+		argv_array_push(&diff_args, oid_to_hex(head_oid));
+	argv_array_push(&diff_args, "--");
+	if (info->argc)
+		argv_array_pushv(&diff_args, info->argv);
+
+	git_config(git_diff_basic_config, NULL);
+	init_revisions(&rev, info->prefix);
+	rev.abbrev = 0;
+	precompose_argv(diff_args.argc, diff_args.argv);
+
+	diff_args.argc = setup_revisions(diff_args.argc, diff_args.argv,
+					 &rev, NULL);
+	rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
+	rev.diffopt.format_callback = submodule_summary_callback;
+	rev.diffopt.format_callback_data = &list;
+
+	if (!info->cached) {
+		if (diff_cmd == DIFF_INDEX)
+			setup_work_tree();
+		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
+			perror("read_cache_preload");
+			return -1;
+		}
+	} else if (read_cache() < 0) {
+		perror("read_cache");
+		return -1;
+	}
+
+	if (diff_cmd == DIFF_INDEX)
+		run_diff_index(&rev, info->cached);
+	else
+		run_diff_files(&rev, 0);
+	prepare_submodule_summary(info, &list);
+	return 0;
+}
+
+static int module_summary(int argc, const char **argv, const char *prefix)
+{
+	struct summary_cb info = SUMMARY_CB_INIT;
+	int cached = 0;
+	int for_status = 0;
+	int files = 0;
+	int summary_limit = -1;
+	enum diff_cmd diff_cmd = DIFF_INDEX;
+	struct object_id head_oid;
+	int ret;
+
+	struct option module_summary_options[] = {
+		OPT_BOOL(0, "cached", &cached,
+			 N_("use the commit stored in the index instead of the submodule HEAD")),
+		OPT_BOOL(0, "files", &files,
+			 N_("to compare the commit in the index with that in the submodule HEAD")),
+		OPT_BOOL(0, "for-status", &for_status,
+			 N_("skip submodules with 'ignore_config' value set to 'all'")),
+		OPT_INTEGER('n', "summary-limit", &summary_limit,
+			     N_("limit the summary size")),
+		OPT_END()
+	};
+
+	const char *const git_submodule_helper_usage[] = {
+		N_("git submodule--helper summary [<options>] [commit] [--] [<path>]"),
+		NULL
+	};
+
+	argc = parse_options(argc, argv, prefix, module_summary_options,
+			     git_submodule_helper_usage, 0);
+
+	if (!summary_limit)
+		return 0;
+
+	if (!get_oid(argc ? argv[0] : "HEAD", &head_oid)) {
+		if (argc) {
+			argv++;
+			argc--;
+		}
+	} else if (!argc || !strcmp(argv[0], "HEAD")) {
+		/* before the first commit: compare with an empty tree */
+		oidcpy(&head_oid, the_hash_algo->empty_tree);
+		if (argc) {
+			argv++;
+			argc--;
+		}
+	} else {
+		if (get_oid("HEAD", &head_oid))
+			die(_("could not fetch a revision for HEAD"));
+	}
+
+	if (files) {
+		if (cached)
+			die(_("--cached and --files are mutually exclusive"));
+		diff_cmd = DIFF_FILES;
+	}
+
+	info.argc = argc;
+	info.argv = argv;
+	info.prefix = prefix;
+	info.cached = !!cached;
+	info.files = !!files;
+	info.for_status = !!for_status;
+	info.summary_limit = summary_limit;
+
+	ret = compute_summary_module_list((diff_cmd == DIFF_INDEX) ? &head_oid : NULL,
+					  &info, diff_cmd);
+	return ret;
+}
+
 struct sync_cb {
 	const char *prefix;
 	unsigned int flags;
@@ -2341,6 +2776,7 @@ static struct cmd_struct commands[] = {
 	{"print-default-remote", print_default_remote, 0},
 	{"sync", module_sync, SUPPORT_SUPER_PREFIX},
 	{"deinit", module_deinit, 0},
+	{"summary", module_summary, SUPPORT_SUPER_PREFIX},
 	{"remote-branch", resolve_remote_submodule_branch, 0},
 	{"push-check", push_check, 0},
 	{"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
diff --git a/git-submodule.sh b/git-submodule.sh
index dda3fee167..236a08f27d 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -59,31 +59,6 @@ die_if_unmatched ()
 	fi
 }
 
-#
-# Print a submodule configuration setting
-#
-# $1 = submodule name
-# $2 = option name
-# $3 = default value
-#
-# Checks in the usual git-config places first (for overrides),
-# otherwise it falls back on .gitmodules.  This allows you to
-# distribute project-wide defaults in .gitmodules, while still
-# customizing individual repositories if necessary.  If the option is
-# not in .gitmodules either, print a default value.
-#
-get_submodule_config () {
-	name="$1"
-	option="$2"
-	default="$3"
-	value=$(git config submodule."$name"."$option")
-	if test -z "$value"
-	then
-		value=$(git submodule--helper config submodule."$name"."$option")
-	fi
-	printf '%s' "${value:-$default}"
-}
-
 isnumber()
 {
 	n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
@@ -831,166 +806,7 @@ cmd_summary() {
 		shift
 	done
 
-	test $summary_limit = 0 && return
-
-	if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
-	then
-		head=$rev
-		test $# = 0 || shift
-	elif test -z "$1" || test "$1" = "HEAD"
-	then
-		# before the first commit: compare with an empty tree
-		head=$(git hash-object -w -t tree --stdin </dev/null)
-		test -z "$1" || shift
-	else
-		head="HEAD"
-	fi
-
-	if [ -n "$files" ]
-	then
-		test -n "$cached" &&
-		die "$(gettext "The --cached option cannot be used with the --files option")"
-		diff_cmd=diff-files
-		head=
-	fi
-
-	cd_to_toplevel
-	eval "set $(git rev-parse --sq --prefix "$wt_prefix" -- "$@")"
-	# Get modified modules cared by user
-	modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
-		sane_egrep '^:([0-7]* )?160000' |
-		while read -r mod_src mod_dst sha1_src sha1_dst status sm_path
-		do
-			# Always show modules deleted or type-changed (blob<->module)
-			if test "$status" = D || test "$status" = T
-			then
-				printf '%s\n' "$sm_path"
-				continue
-			fi
-			# Respect the ignore setting for --for-status.
-			if test -n "$for_status"
-			then
-				name=$(git submodule--helper name "$sm_path")
-				ignore_config=$(get_submodule_config "$name" ignore none)
-				test $status != A && test $ignore_config = all && continue
-			fi
-			# Also show added or modified modules which are checked out
-			GIT_DIR="$sm_path/.git" git rev-parse --git-dir >/dev/null 2>&1 &&
-			printf '%s\n' "$sm_path"
-		done
-	)
-
-	test -z "$modules" && return
-
-	git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
-	sane_egrep '^:([0-7]* )?160000' |
-	cut -c2- |
-	while read -r mod_src mod_dst sha1_src sha1_dst status name
-	do
-		if test -z "$cached" &&
-			is_zero_oid $sha1_dst
-		then
-			case "$mod_dst" in
-			160000)
-				sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
-				;;
-			100644 | 100755 | 120000)
-				sha1_dst=$(git hash-object $name)
-				;;
-			000000)
-				;; # removed
-			*)
-				# unexpected type
-				eval_gettextln "unexpected mode \$mod_dst" >&2
-				continue ;;
-			esac
-		fi
-		missing_src=
-		missing_dst=
-
-		test $mod_src = 160000 &&
-		! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
-		missing_src=t
-
-		test $mod_dst = 160000 &&
-		! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
-		missing_dst=t
-
-		display_name=$(git submodule--helper relative-path "$name" "$wt_prefix")
-
-		total_commits=
-		case "$missing_src,$missing_dst" in
-		t,)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
-			;;
-		,t)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
-			;;
-		t,t)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$sha1_dst")"
-			;;
-		*)
-			errmsg=
-			total_commits=$(
-			if test $mod_src = 160000 && test $mod_dst = 160000
-			then
-				range="$sha1_src...$sha1_dst"
-			elif test $mod_src = 160000
-			then
-				range=$sha1_src
-			else
-				range=$sha1_dst
-			fi
-			GIT_DIR="$name/.git" \
-			git rev-list --first-parent $range -- | wc -l
-			)
-			total_commits=" ($(($total_commits + 0)))"
-			;;
-		esac
-
-		sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
-			echo $sha1_src | cut -c1-7)
-		sha1_abbr_dst=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_dst 2>/dev/null ||
-			echo $sha1_dst | cut -c1-7)
-
-		if test $status = T
-		then
-			blob="$(gettext "blob")"
-			submodule="$(gettext "submodule")"
-			if test $mod_dst = 160000
-			then
-				echo "* $display_name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:"
-			else
-				echo "* $display_name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:"
-			fi
-		else
-			echo "* $display_name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
-		fi
-		if test -n "$errmsg"
-		then
-			# Don't give error msg for modification whose dst is not submodule
-			# i.e. deleted or changed to blob
-			test $mod_dst = 160000 && echo "$errmsg"
-		else
-			if test $mod_src = 160000 && test $mod_dst = 160000
-			then
-				limit=
-				test $summary_limit -gt 0 && limit="-$summary_limit"
-				GIT_DIR="$name/.git" \
-				git log $limit --pretty='format:  %m %s' \
-				--first-parent $sha1_src...$sha1_dst
-			elif test $mod_dst = 160000
-			then
-				GIT_DIR="$name/.git" \
-				git log --pretty='format:  > %s' -1 $sha1_dst
-			else
-				GIT_DIR="$name/.git" \
-				git log --pretty='format:  < %s' -1 $sha1_src
-			fi
-			echo
-		fi
-		echo
-	done
+	git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${prefix:+--prefix "$prefix"} ${files:+--files} ${cached:+--cached} ${for_status:+--for-status} ${summary_limit:+-n $summary_limit} -- "$@"
 }
 #
 # List all submodules, prefixed with:
diff --git a/t/t7421-submodule-summary-add.sh b/t/t7421-submodule-summary-add.sh
index 829fe26d6d..59a9b00467 100755
--- a/t/t7421-submodule-summary-add.sh
+++ b/t/t7421-submodule-summary-add.sh
@@ -58,7 +58,7 @@ test_expect_success 'submodule summary output for submodules with changed paths'
 	git commit -m "change submodule path" &&
 	rev=$(git -C sm rev-parse --short HEAD^) &&
 	git submodule summary HEAD^^ -- my-subm >actual 2>err &&
-	test_i18ngrep "fatal:.*my-subm" err &&
+	grep "fatal:.*my-subm" err &&
 	cat >expected <<-EOF &&
 	* my-subm ${rev}...0000000:
 
-- 
2.28.0


^ permalink raw reply related	[relevance 18%]

* Re: [PATCH 4/4] submodule: port submodule subcommand 'summary' from shell to C
  2020-07-06  9:16  4%       ` Kaartic Sivaraam
@ 2020-07-06 11:15  2%         ` Shourya Shukla
  0 siblings, 0 replies; 200+ results
From: Shourya Shukla @ 2020-07-06 11:15 UTC (permalink / raw)
  To: Kaartic Sivaraam
  Cc: Johannes.Schindelin, git, christian.couder, gitster, liu.denton,
	pc44800, stefanbeller

On 06/07 02:46, Kaartic Sivaraam wrote:
> Note: I've added some comment but I've not been able to address all the
> parts due to lack of time. I'm sending it sooner hoping it would be
> useful.

Sure no problem

> On 05-07-2020 23:04, Shourya Shukla wrote:
> [...]
> >> [exchanging Stefan Beller's dysfunct @google address for their private
> >> one; I encourage you to do the same in the next iteration, probably
> >> by editing the `Mentored-by:` line.]
> > 
> > I think you missed to mention it.
> >
> 
> If you're looking for the private e-mail. The exachange was already done
> and it was right there in the Cc list of the mail sent by Dscho. I've
> added it again as you seem to have removed it.

Oh I did not catch that actually. Thanks!

> >> On Fri, 3 Jul 2020, Shourya Shukla wrote:
> >>
> >>> From: Prathamesh Chavan <pc44800@gmail.com>
> >>>
> >>> The submodule subcommand 'summary' is ported in the process of
> >>> making git-submodule a builtin. The function cmd_summary() from
> >>> git-submodule.sh is ported to functions module_summary(),
> >>> compute_summary_module_list(), prepare_submodule_summary() and
> >>> generate_submodule_summary(), print_submodule_summary().
> >>>
> >>> The first function module_summary() parses the options of submodule
> >>> subcommand and also acts as the front-end of this subcommand.
> >>> After parsing them, it calls the compute_summary_module_list()
> >>
> >> Missing full-stop, and probably the sentence also wanted to say "function"
> >> at the end.
> > 
> > I will correct. Thanks for pointing out!
> > 
> >>> The functions compute_summary_module_list() runs the diff_cmd,
> >>> and generates the modules list, as required by the subcommand.
> >>> The generation of this module list is done by the using the
> >>
> >> s/the using/using/
> > 
> > Will amend!
> > 
> >>> callback function submodule_summary_callback(), and stored in the
> >>> structure module_cb.
> >>
> >> This explains nicely what the patch does. But the commit message should
> >> not really repeat what can be readily deduced from the patch; It should
> >> focus on the motivation and on interesting background information that is
> >> _not_ readily deduced from the patch.
> > 
> > I understand. I will follow your suggestions regarding my patch.
> > 
> >> For example, I see that `$diff_cmd` is called twice in the shell script
> >> version, once to "get modified modules cared by user" and then _again_,
> >> with that list of modified modules.
> >>
> >> I would have liked to see a reasoning in the commit message that explains
> >> why this has to be so in the C version. I get why it is complicated in a
> >> shell script (which lacks proper objects, after all), but I would have
> >> expected the C version to be able to accumulate the information with a
> >> single pass.
> >>
> >> (Before writing the following paragraph, I actually reviewed the patch
> >> from bottom to top, in the caller->callee direction.)
> >>
> >> Ah. I see that this indeed is the case: there is only one pass in the C
> >> version. That's a useful piece of metadata for the commit message, I
> >> think, much more useful than describing the call tree of the functions.
> > 
> > Yup that it worth mentioning.
> > 
> >> Another thing worth mentioning in the commit message is that we use the
> >> combination of setting a child_process' working directory to the submodule
> >> path and then calling `prepare_submodule_repo_env()` which also sets
> >> `GIT_DIR` to `.git`, so that we can be certain that those spawned
> >> processes will not access the superproject's ODB by mistake.
> >>
> >> When reading my suggestions, please keep in mind that I reviewed the
> >> functions in caller->callee order, i.e. I started at the end of the patch
> >> and then worked my way up.
> >>
> >> All in all, I like the function structure, but I think there is still a
> >> bit room for improvement in a v2.
> > 
> >>> +static int verify_submodule_object_name(const char *sm_path,
> >>> +					  const char *sha1)
> >>> +{
> >>> +	struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> >>> + > > +	cp_rev_parse.git_cmd = 1;
> >>> +	cp_rev_parse.no_stdout = 1;
> >>> +	cp_rev_parse.dir = sm_path;
> >>
> >> So here we specify `sm_path` as current working directory.
> >>
> >>> +	prepare_submodule_repo_env(&cp_rev_parse.env_array);
> >>
> >> And this implicitly sets `GIT_DIR=.git`. Good.
> >>
> >>> +	argv_array_pushl(&cp_rev_parse.args, "rev-parse", "-q",
> >>> +			 "--verify", NULL);
> >>> +	argv_array_pushf(&cp_rev_parse.args, "%s^0", sha1);
> >>
> >> After this, we should also append `--` to make sure that we're not parsing
> >> this as a file name.
> > 
> > Will do!
> > 
> >> Two comments about naming: `sha1` is pretty misleading here, as we do not
> >> require it to be a SHA-1 (especially in the future in which we switch to
> >> SHA-256). Besides, what we're really asking for (via that `^0` suffix) is
> >> a committish. Therefore, I would propose to use `committish` both in the
> >> parameter name as well as the function name.
> > 
> > I am not aware of this change. I will take this suggestion into account.
> > 
> >>> +
> >>> +	if (run_command(&cp_rev_parse))
> >>> +		return 1;
> >>> +
> >>> +	return 0;
> >>> +}
> >>> +
> >>> +static void print_submodule_summary(struct summary_cb *info, int errmsg,
> >>> +				      int total_commits, int missing_src,
> >>> +				      int missing_dst, const char *displaypath,
> >>> +				      int is_sm_git_dir, struct module_cb *p)
> >>> +{
> >>> +	if (p->status == 'T') {
> >>> +		if (S_ISGITLINK(p->mod_dst))
> >>> +			printf(_("* %s %s(blob)->%s(submodule)"),
> >>> +				 displaypath, find_unique_abbrev(&p->oid_src, 7),
> >>
> >> The shell script version does this:
> >>
> >>                 sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
> >>                         echo $sha1_src | cut -c1-7)
> >>
> >> That is not quite the same, as it looks for the abbreviation _in the
> >> submodule_, not in the current project. So I think `find_unique_abbrev()`
> >> is not correct here.
> >>
> >> The funny thing is that we _already_ will have called `git rev-parse
> >> --verify` for both `p->oid_src` and `p->oid_dst` in the submodule, in the
> >> caller of this function! And while we throw away the result, and while we
> >> do not pass `--short`, there is no reason why we shouldn't be able to do
> >> precisely that.
> > 
> > Okay so you are saying that there is no need of a 'find_unique_abbrev()'
> > since we would be easily able to obtain these values from the caller of
> > 'print_submodule_summary()' right?
> 
> Yes. 'generate_submodule_summary' already does a rev-parse on
> p->oid_src and p->oid_dst via 'verify_submodule_object_name'.
> We should be able to get the short version of them by passing '--short'
> to rev-parse there and make it return the short SHA1. We can then use it
> like how Dscho mentions below.

Okay. That seems good. Yes, it will be cleaner to pass them as
arguments.

> > Maybe we can pass 'oid_src' or 'oid_dst' as an argument?
> > 
> >>> +				 find_unique_abbrev(&p->oid_dst, 7));
> >>> +		else
> >>> +			printf(_("* %s %s(submodule)->%s(blob)"),
> >>> +				 displaypath, find_unique_abbrev(&p->oid_src, 7),
> >>> +				 find_unique_abbrev(&p->oid_dst, 7));
> >>> +	} else {
> >>> +		printf("* %s %s...%s",
> >>> +			displaypath, find_unique_abbrev(&p->oid_src, 7),
> >>> +			find_unique_abbrev(&p->oid_dst, 7));
> >>> +	}
> >>> +
> >>> +	if (total_commits < 0)
> >>> +		printf(":\n");
> >>> +	else
> >>> +		printf(" (%d):\n", total_commits);
> >>> +
> >>> +	if (errmsg) {
> >>> +		/*
> >>> +		 * Don't give error msg for modification whose dst is not
> >>> +		 * submodule, i.e. deleted or changed to blob
> >>> +		 */
> >>> +		if (S_ISGITLINK(p->mod_src)) {
> >>> +			if (missing_src && missing_dst) {
> >>> +				printf(_("  Warn: %s doesn't contain commits %s and %s\n"),
> >>> +				       displaypath, oid_to_hex(&p->oid_src),
> >>> +				       oid_to_hex(&p->oid_dst));
> >>> +			} else if (missing_src) {
> >>> +				printf(_("  Warn: %s doesn't contain commit %s\n"),
> >>> +				       displaypath, oid_to_hex(&p->oid_src));
> >>> +			} else {
> >>> +				printf(_("  Warn: %s doesn't contain commit %s\n"),
> >>> +				       displaypath, oid_to_hex(&p->oid_dst));
> >>> +			}
> >>> +		}
> >>> +	} else if (is_sm_git_dir) {
> >>> +		struct child_process cp_log = CHILD_PROCESS_INIT;
> >>> +
> >>> +		cp_log.git_cmd = 1;
> >>> +		cp_log.dir = p->sm_path;
> >>> +		prepare_submodule_repo_env(&cp_log.env_array);
> >>
> >> Since the working directory is set to the top-level directory of the
> >> submodule, and since `prepare_submodule_repo_env()` sets `GIT_DIR` to
> >> `.git`, I think that the `is_sm_git_dir` condition is unnecessary. In
> >> fact, the entire `is_sm_git_dir` parameter (and local variable in the
> >> caller, see more on that below) can go away.
> > 
> > Because we already set the $GIT_DIR to .git/ so an extra check will not
> > be necessary right?
> > 
> 
> Yes. If we remove that check and we get a p->sm_path that does not point
> to a submodule, I wonder what would happen if we run 'run_command'
> on it. I'm also not sure if that's a possible case. Something to
> explore.

This might take some time but would be a huge change for this patch if
successful.

> >>> +		argv_array_pushl(&cp_log.args, "log", NULL);
> >>> +
> >>> +		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
> >>> +			if (info->summary_limit > 0)
> >>> +				argv_array_pushf(&cp_log.args, "-%d",
> >>> +						 info->summary_limit);
> >>> +
> >>> +			argv_array_pushl(&cp_log.args, "--pretty=  %m %s",
> >>> +					 "--first-parent", NULL);
> >>> +			argv_array_pushf(&cp_log.args, "%s...%s",
> >>> +					 oid_to_hex(&p->oid_src),
> >>> +					 oid_to_hex(&p->oid_dst));
> >>> +		} else if (S_ISGITLINK(p->mod_dst)) {
> >>> +			argv_array_pushl(&cp_log.args, "--pretty=  > %s",
> >>> +					 "-1", oid_to_hex(&p->oid_dst), NULL);
> >>> +		} else {
> >>> +			argv_array_pushl(&cp_log.args, "--pretty=  < %s",
> >>> +					 "-1", oid_to_hex(&p->oid_src), NULL);
> >>> +		}
> >>> +		run_command(&cp_log);
> >>> +	}
> >>> +	printf("\n");
> >>> +}
> >>
> >> It looks as if there is a whole lot of `oid_to_hex(&p->oid_src)` in that
> >> function. Together with the realization that we need the abbreviated
> >> version of that at least in one place, and the other realization that we
> >> already call `rev-parse --verify` for both `oid_src` and `oid_dst` in the
> >> caller of this function, it seems to suggest itself that we would actually
> >> want to pass the `--short` option, too, and to capture the output, and
> >> pass it down to `print_submodule_summary()` _instead of_ `missing_src` and
> >> `missing_dst` (e.g. as `src_abbrev` and `dst_abbrev`).
> > 
> > Oh you have mentioned it here too. This seems quite a good approach. I
> > will adopt this.
> > 
> >>> +
> >>> +static void generate_submodule_summary(struct summary_cb *info,
> >>> +				       struct module_cb *p)
> >>> +{
> >>> +	int missing_src = 0;
> >>> +	int missing_dst = 0;
> >>> +	char *displaypath;
> >>> +	int errmsg = 0;
> >>> +	int total_commits = -1;
> >>> +	int is_sm_git_dir = 0;
> >>> +	struct strbuf sm_git_dir_sb = STRBUF_INIT;
> >>> +
> >>> +	if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
> >>> +		if (S_ISGITLINK(p->mod_dst)) {
> >>> +			/*
> >>> +			 * NEEDSWORK: avoid using separate process with
> >>> +			 * the help of the function head_ref_submodule()
> >>
> >> I don't quite understand this comment. There is no `head_ref_submodule()`
> >> function.
> >>
> 
> That NEEDSWORK was added based on Stefan's comment on a previous version
> of Prathamesh's patch. Here it is for reference:
> 
> >> +       if (!info->cached && !oidcmp(&p->oid_dst, &null_oid)) {
> >> +               if (S_ISGITLINK(p->mod_dst)) {
> >> +                       struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> >> +                       struct strbuf sb_rev_parse = STRBUF_INIT;
> >> +
> >> +                       cp_rev_parse.git_cmd = 1;
> >> +                       cp_rev_parse.no_stderr = 1;
> >> +                       cp_rev_parse.dir = p->sm_path;
> >> +                       prepare_submodule_repo_env(&cp_rev_parse.env_array);
> >> +
> >> +                       argv_array_pushl(&cp_rev_parse.args,
> >> +                                        "rev-parse", "HEAD", NULL);
> >> +                       if (!capture_command(&cp_rev_parse, &sb_rev_parse, 0)) {
> >> +                               strbuf_strip_suffix(&sb_rev_parse, "\n");
> >> +
> >> +                               get_oid_hex(sb_rev_parse.buf, &p->oid_dst);
> >> +                       }
> >> +                       strbuf_release(&sb_rev_parse);
> > 
> > I think this could be replaced via
> > head_ref_submodule(sub->path, callback function, &where_to_store)
> > or is there some trickery going on, that this also works on
> > non-compliant submodules?
> > (Maybe add that as a NEEDSWORK/TODO)
> 
> Ref:
> https://public-inbox.org/git/CAGZ79kaWn9z47Va=VW4R2Aswws1N5n2u4Kvatn73s0YnV0pVqQ@mail.gmail.com/
> 
> A quick search reveals that 'head_ref_submodule' existed during that
> period. On further investigation it seems that 'refs_head_ref' was
> introduced in 62f0b399e0 (refs: add refs_head_ref(), 2017-08-23) and
> 'head_ref_submodule' was made to use it. Later on, in 419221c106 (refs:
> remove dead for_each_*_submodule(), 2017-08-23), 'head_ref-submodule'
> was removed with an advice to use the 'refs_' API for accessing
> submodules.
> 
> > +* Use `refs_` API for accessing submodules. The submodule ref store could
> > +  be obtained with `get_submodule_ref_store()`
> 
> How it applies to our code is something to be looked into, yet.
> 
> >>> +			 */
> >>> +			struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> >>> +			struct strbuf sb_rev_parse = STRBUF_INIT;
> >>> +
> >>> +			cp_rev_parse.git_cmd = 1;
> >>> +			cp_rev_parse.no_stderr = 1;
> >>> +			cp_rev_parse.dir = p->sm_path;
> >>> +			prepare_submodule_repo_env(&cp_rev_parse.env_array);
> >>> +
> >>> +			argv_array_pushl(&cp_rev_parse.args, "rev-parse",
> >>> +					 "HEAD", NULL);
> >>> +			if (!capture_command(&cp_rev_parse, &sb_rev_parse, 0)) {
> >>> +				strbuf_strip_suffix(&sb_rev_parse, "\n");
> >>> +				get_oid_hex(sb_rev_parse.buf, &p->oid_dst);
> >>> +			}
> >>> +			strbuf_release(&sb_rev_parse);
> >>> +		} else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
> >>> +			struct child_process cp_hash_object = CHILD_PROCESS_INIT;
> >>> +			struct strbuf sb_hash_object = STRBUF_INIT;
> >>> +
> >>> +			cp_hash_object.git_cmd = 1;
> >>> +			argv_array_pushl(&cp_hash_object.args, "hash-object",
> >>> +					 p->sm_path, NULL);
> >>> +			if (!capture_command(&cp_hash_object,
> >>> +					     &sb_hash_object, 0)) {
> >>> +				strbuf_strip_suffix(&sb_hash_object, "\n");
> >>> +				get_oid_hex(sb_hash_object.buf, &p->oid_dst);
> >>> +			}
> >>> +			strbuf_release(&sb_hash_object);
> >>
> >> It would probably be shorter, less error-prone, and quicker to use
> >> `index_fd()` directly.
> >>
> >> BTW I am not quite sure that this code does the correct thing in case of a
> >> symlink: it hashes the contents of the symlink target (if it is a file,
> >> otherwise it errors out). But that is hardly an issue introduced by the
> >> conversion, that's just copied from `git-submodule.sh`.
> >>
> >>> +		} else {
> >>> +			if (p->mod_dst)
> >>> +				die(_("unexpected mode %d\n"), p->mod_dst);
> >>
> >> Hmm. This does not match what the shell script version does:
> >>
> >>                         *)
> >>                                 # unexpected type
> >>                                 eval_gettextln "unexpected mode \$mod_dst" >&2
> >>                                 continue ;;
> >>
> >> I think we should also just write the message to `stderr` and continue,
> >> not `die()`.
> >>
> >> In addition to that, I am missing the C code for this case:
> >>
> >>                         000000)
> >>                                 ;; # removed
> >>
> >> It is quite possible that our test suite does not cover this case (or did
> >> the test suite fail for you?). If that is indeed the case, it would be
> >> really good to add a test case as part of this patch series, to gain
> >> confidence in the correctness of the conversion.
> > 
> > The tests passed for me actually. Whether this is covered by the test
> > cases, I am not sure. I will have to check it.
> > 
> >>> +		}
> >>> +	}
> >>> +
> >>> +	strbuf_addstr(&sm_git_dir_sb, p->sm_path);
> >>
> >> I have to admit that I am not loving the name `sm_git_dir_sb`. Why not
> >> `submodule_git_dir`? I guess you copied it from elsewhere in
> >> `submodule--helper.c`...
> >>
> >>> +	if (is_nonbare_repository_dir(&sm_git_dir_sb))
> >>> +		is_sm_git_dir = 1;
> >>
> >> So here, we verify whether there is a repository at `p->sm_path`. I don't
> >> see that in the shell script version:
> >>
> >>                 missing_src=
> >>                 missing_dst=
> >>
> >>                 test $mod_src = 160000 &&
> >>                 ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
> >>                 missing_src=t
> >>
> >>                 test $mod_dst = 160000 &&
> >>                 ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
> >>                 missing_dst=t
> >>
> >> Let's read a bit further.
> >>
> >>> +
> >>> +	if (is_sm_git_dir && S_ISGITLINK(p->mod_src))
> >>> +		missing_src = verify_submodule_object_name(p->sm_path,
> >>> +							   oid_to_hex(&p->oid_src));
> >>
> >> Ah, and `verify_submodule_object_name()` uses `p->sm_path` as working
> >> directory. But that's not what the shell script version did: it specified
> >> the `GIT_DIR` explicitly.
> >>
> >> And by using the `prepare_submodule_repo_env()` function in
> >> `verify_submodule_object_name()`, we specify `GIT_DIR` implicitly, as I
> >> pointed out in my comment on that function.
> > 
> > Oh so you're saying that it will be better to call
> > 'prepare_submodule_repo_env()' on some variable since we explicitly want to
> > store the path to GIT_DIR?
> > 
> 
> We already call 'prepare_submodule_repo_env' in
> 'verify_submodule_object_name'. So, he's likely saying that
> 'is_sm_git_dir' is unnecessary here.

Understood.

> > It would be of much help if you could explain this part just a little
> > more (for my own sake).
> > 
> >> So I think that `is_sm_git_dir` might be
> > 
> 
> ... unnecessary.
> 
> > I think you missed something here...
> > 
> 
> That's likely what he meant based on what is mentioned above.

Oh okay. Thanks!

> >>> +
> >>> +	if (is_sm_git_dir && S_ISGITLINK(p->mod_dst))
> >>> +		missing_dst = verify_submodule_object_name(p->sm_path,
> >>> +							   oid_to_hex(&p->oid_dst));
> >>> +
> >>> +	displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
> >>> +
> >>> +	if (!missing_dst && !missing_src) {
> >>> +		if (is_sm_git_dir) {
> >>> +			struct child_process cp_rev_list = CHILD_PROCESS_INIT;
> >>> +			struct strbuf sb_rev_list = STRBUF_INIT;
> >>> +			char *range;
> >>> +
> >>> +			if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
> >>> +				range = xstrfmt("%s...%s", oid_to_hex(&p->oid_src),
> >>> +						oid_to_hex(&p->oid_dst));
> >>> +			else if (S_ISGITLINK(p->mod_src))
> >>> +				range = xstrdup(oid_to_hex(&p->oid_src));
> >>> +			else
> >>> +				range = xstrdup(oid_to_hex(&p->oid_dst));
> >>> +
> >>> +			cp_rev_list.git_cmd = 1;
> >>> +			cp_rev_list.dir = p->sm_path;
> >>> +			prepare_submodule_repo_env(&cp_rev_list.env_array);
> >>
> >> Again, due to setting the working directory to `p->sm_path` and
> >> (implicitly, via `prepare_submodule_repo_env()`) `GIT_DIR` to `.git`, I do
> >> not think that we have to guard this block beind `is_sm_git_dir`.
> > 
> >>> +
> >>> +			argv_array_pushl(&cp_rev_list.args, "rev-list",
> >>> +					 "--first-parent", range, "--", NULL);
> >>
> >> Since `argv_array_push()` duplicates the strings, anyway, we can totally
> >> avoid the need for the `range` variable:
> >>
> >> 			if (IS_GITLINK(p->mod_src) && IS_GITLINK(p->mod_dst))
> >> 				argv_array_pushf(&cp_rev_list.args, "%s...%s",
> >> 						 oid_to_hex(&p->oid_src),
> >> 						 oid_to_hex(&p->oid_dst));
> >> 			else
> >> 				argv_array_push(&cp_rev_list.args, IS_GITLINK(p->mod_src) ?
> >> 						oid_to_hex(&p->oid_src) :
> >> 						oid_to_hex(&p->oid_dst));
> >>
> >>> +			if (!capture_command(&cp_rev_list, &sb_rev_list, 0)) {
> >>> +				if (sb_rev_list.len)
> >>> +					total_commits = count_lines(sb_rev_list.buf,
> >>> +								    sb_rev_list.len);
> >>
> >> That's actually not necessary. `git rev-list --count` will give you a nice
> >> number, no need to capture a potentially large amount of memory only to
> >> count the lines.
> >>
> >> This may also make the patch obsolete that makes `count_lines()` public.
> > 
> > Therefore we eliminate count_lines() from here and instead do a 'git
> > rev-list --count'?
> > 
> 
> Yes.
> 
> >>> +				else
> >>> +					total_commits = 0;
> >>> +			}
> >>
> >>> +
> >>> +			free(range);
> >>> +			strbuf_release(&sb_rev_list);
> >>> +		}
> >>> +	} else {
> >>> +		errmsg = 1;
> >>> +	}
> >>
> >> I am missing the equivalent for these lines here:
> >>
> >>                 t,)
> >>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
> >>                         ;;
> >>                 ,t)
> >>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
> >>                         ;;
> >>                 t,t)
> >>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$ ha1_dst")"
> >>                         ;;
> > 
> > I will add them.
> > 
> 
> I think they're already there in the 'print_submodule_summary' function
> above.
> 
> >> I am not quite sure whether it is a good idea to leave it to the
> >> `print_submodule_summary()` function to generate the `errmsg`. I think I'd
> >> rather have it a `char *` than an `int`.
> > 
> > Would it be better to add these error messages in
> > 'prepare_submodule_summary()'?
> 
> No. He's likely saying that instead of setting `errmsg` to 1 and
> constructing the error message in `print_submodule_summary` we should
> be having the error messages in `generate_submodule_summary` and pass
> them to `print_submodule_summary` instead of passing an int.

So this means that we will have to generate the above mentioned messages
in 'generate_submodule_summary()' and then pass them as char into
'print_submodule_summary()' rather than generating them in the latter.
This is what we want right?

> > If we have error messages as integers
> > then we will simply
> > 
> 
> You missed something here. ;)

I actually don't know what I was trying to write here.

> >>> +
> >>> +	print_submodule_summary(info, errmsg, total_commits,
> >>> +				missing_src, missing_dst,
> >>> +		      		displaypath, is_sm_git_dir, p);
> >>> +
> >>> +	free(displaypath);
> >>> +	strbuf_release(&sm_git_dir_sb);
> >>> +}
> >>> +
> >>> +static void prepare_submodule_summary(struct summary_cb *info,
> >>> +				      struct module_cb_list *list)
> >>> +{
> >>> +	int i;
> >>> +	for (i = 0; i < list->nr; i++) {
> >>> +		struct module_cb *p = list->entries[i];
> >>> +		struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> >>> +
> >>> +		if (p->status == 'D' || p->status == 'T') {
> >>> +			generate_submodule_summary(info, p);
> >>> +			continue;
> >>> +		}
> >>> +
> >>> +		if (info->for_status) {
> >>> +			char *config_key;
> >>
> >> Since the `config_key` is only used within the `if()` block it would be
> >> better to declare it within that block.
> >>
> >>> +			const char *ignore_config = "none";
> >>
> >> Since the only value we ever care about is "all", how about turning this
> >> into an `int`, setting it to `0` here, and later assigning it to
> >> `!strcmp(value, "all")` and `!strcmp(sub->ignore, "all")`, respectively?
> > 
> > Alright will do!
> > 
> >> I mean, I get it. Unix shell scripts are all about passing around text.
> >> And it is much easier to just translate that to C faithfully. But that
> >> does not make it good C code. C has data types, and proper C code makes
> >> use of that.
> >>
> >>> +			const char *value;
> >>
> >> If you want to save on lines, you can cuddle this together with other
> >> declarations of the same type. Even so, it could be scoped more narrowly.
> >>
> >>> +			const struct submodule *sub = submodule_from_path(the_repository,
> >>> +									  &null_oid,
> >>> +									  p->sm_path);
> >>> +
> >>> +			if (sub && p->status != 'A') {
> >>
> >> Good. The shell script version _always_ retrieved the `.ignore` config
> >> value, even if the `status` is `A`. Your version is much better.
> >>
> >> But why bother calling `submodule_from_path()` if the status is `A`?
> > 
> > What exactly does a status of 'A' or 'T' mean? I mean I know what we are
> > doing but what exactly do these translate into?
> > 
> 
> Its interesting you understood it without knowing what 'A' and 'T'
> meant. Anyways, if you take a look at the documentation of
> 'diff-index'[1] which provides us the `status` you'll know that:

I just assumed that they must mean something to something and read on
the rest of the code. I meant to ask the full-form of 'A', 'T', etc.
You have provided it below and this makes things even more clear.
Thanks!

> > Possible status letters are:
> > 
> >     A: addition of a file
> > 
> >     C: copy of a file into a new one
> > 
> >     D: deletion of a file
> > 
> >     M: modification of the contents or mode of a file
> > 
> >     R: renaming of a file
> > 
> >     T: change in the type of the file
> > 
> >     U: file is unmerged (you must complete the merge before it can be committed)
> > 
> >     X: "unknown" change type (most probably a bug, please report it)
> > 
> 
> [1]: https://git-scm.com/docs/git-diff-index
> 
> >> I could actually see the `const struct submodule *sub;` declaration be
> >> pulled out of this scope, and combining the `if (info->for_status &&
> >> p->status != 'A'), and the moving the assignment of `sub` into the `else
> >> if ((sub = submodule_from_path(r, &null_oid, p->sm_path)) &&
> >> sub->ignore)`.
> >>
> >> That would save us one entire indentation level.
> > 
> > That seems a good approach! I will try this out.
> > 
> >>> +				config_key = xstrfmt("submodule.%s.ignore",
> >>> +						     sub->name);
> >>> +				if (!git_config_get_string_const(config_key, &value))
> >>> +					ignore_config = value;
> >>> +				else if (sub->ignore)
> >>> +					ignore_config = sub->ignore;
> >>> +
> >>> +				free(config_key);
> >>> +				if (!strcmp(ignore_config, "all"))
> >>> +					continue;
> >>> +			}
> >>> +		}
> >>> +
> >>> +		/* Also show added or modified modules which are checked out */
> >>> +		cp_rev_parse.dir = p->sm_path;
> >>> +		cp_rev_parse.git_cmd = 1;
> >>> +		cp_rev_parse.no_stderr = 1;
> >>> +		cp_rev_parse.no_stdout = 1;
> >>> +
> >>> +		argv_array_pushl(&cp_rev_parse.args, "rev-parse",
> >>> +				 "--git-dir", NULL);
> >>> +
> >>> +		if (!run_command(&cp_rev_parse))
> >>
> >> I wonder whether we really need to waste an entire spawned process on
> >> figuring out whether `p->sm_path` refers to an active repository. Wouldn't
> >> `is_submodule_active(r, p->sm_path)` fulfill the same purpose?
> > 
> > Yep! This is correct. I will change.
> > 
> >>> +			generate_submodule_summary(info, p);
> >>> +	}
> >>> +}
> >>> +
> >>> +static void submodule_summary_callback(struct diff_queue_struct *q,
> >>> +				       struct diff_options *options,
> >>> +				       void *data)
> >>> +{
> >>> +	int i;
> >>> +	struct module_cb_list *list = data;
> >>> +	for (i = 0; i < q->nr; i++) {
> >>> +		struct diff_filepair *p = q->queue[i];
> >>> +		struct module_cb *temp;
> >>> +
> >>> +		if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
> >>> +			continue;
> >>> +		temp = (struct module_cb*)malloc(sizeof(struct module_cb));
> >>> +		temp->mod_src = p->one->mode;
> >>> +		temp->mod_dst = p->two->mode;
> >>> +		temp->oid_src = p->one->oid;
> >>> +		temp->oid_dst = p->two->oid;
> >>> +		temp->status = p->status;
> >>> +		temp->sm_path = xstrdup(p->one->path);
> >>> +
> >>> +		ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
> >>> +		list->entries[list->nr++] = temp;
> >>> +	}
> >>> +}
> >>> +
> >>> +static const char *get_diff_cmd(enum diff_cmd diff_cmd)
> >>> +{
> >>> +	switch (diff_cmd) {
> >>> +	case DIFF_INDEX: return "diff-index";
> >>> +	case DIFF_FILES: return "diff-files";
> >>> +	default: BUG("bad diff_cmd value %d", diff_cmd);
> >>> +	}
> >>> +}
> >>> +
> >>> +static int compute_summary_module_list(char *head,
> >>> +				         struct summary_cb *info,
> >>> +				         enum diff_cmd diff_cmd)
> >>> +{
> >>> +	struct argv_array diff_args = ARGV_ARRAY_INIT;
> >>> +	struct rev_info rev;
> >>> +	struct module_cb_list list = MODULE_CB_LIST_INIT;
> >>> +
> >>> +	argv_array_push(&diff_args, get_diff_cmd(diff_cmd));
> >>> +	if (info->cached)
> >>> +		argv_array_push(&diff_args, "--cached");
> >>> +	argv_array_pushl(&diff_args, "--ignore-submodules=dirty", "--raw",
> >>> +			 NULL);
> >>> +	if (head)
> >>> +		argv_array_push(&diff_args, head);
> >>> +	argv_array_push(&diff_args, "--");
> >>> +	if (info->argc)
> >>> +		argv_array_pushv(&diff_args, info->argv);
> >>> +
> >>> +	git_config(git_diff_basic_config, NULL);
> >>> +	init_revisions(&rev, info->prefix);
> >>> +	rev.abbrev = 0;
> >>> +	precompose_argv(diff_args.argc, diff_args.argv);
> >>> +
> >>> +	diff_args.argc = setup_revisions(diff_args.argc, diff_args.argv,
> >>> +					 &rev, NULL);
> >>> +	rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
> >>> +	rev.diffopt.format_callback = submodule_summary_callback;
> >>> +	rev.diffopt.format_callback_data = &list;
> >>> +
> >>> +	if (!info->cached) {
> >>> +		if (diff_cmd ==  DIFF_INDEX)
> >>
> >> Please substitute the double-space by a single one.
> > 
> > Will do!
> > 
> >>> +			setup_work_tree();
> >>> +		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
> >>> +			perror("read_cache_preload");
> >>> +			return -1;
> >>> +		}
> >>> +	} else if (read_cache() < 0) {
> >>> +		perror("read_cache");
> >>> +		return -1;
> >>> +	}
> >>> +
> >>> +	if (diff_cmd == DIFF_INDEX)
> >>> +		run_diff_index(&rev, info->cached);
> >>> +	else
> >>> +		run_diff_files(&rev, 0);
> >>> +	prepare_submodule_summary(info, &list);
> >>> +	return 0;
> >>> +}
> >>> +
> >>> +static int module_summary(int argc, const char **argv, const char *prefix)
> >>> +{
> >>> +	struct summary_cb info = SUMMARY_CB_INIT;
> >>> +	int cached = 0;
> >>> +	int for_status = 0;
> >>> +	int quiet = 0;
> >>> +	int files = 0;
> >>> +	int summary_limit = -1;
> >>> +	struct child_process cp_rev = CHILD_PROCESS_INIT;
> >>> +	struct strbuf sb = STRBUF_INIT;
> >>> +	enum diff_cmd diff_cmd = DIFF_INDEX;
> >>> +	int ret;
> >>> +
> >>> +	struct option module_summary_options[] = {
> >>> +		OPT__QUIET(&quiet, N_("Suppress output of summarising submodules")),
> >>> +		OPT_BOOL(0, "cached", &cached,
> >>> +			 N_("Use the commit stored in the index instead of the submodule HEAD")),
> >>> +		OPT_BOOL(0, "files", &files,
> >>> +			 N_("To compare the commit in the index with that in the submodule HEAD")),
> >>> +		OPT_BOOL(0, "for-status", &for_status,
> >>> +			 N_("Skip submodules with 'ignore_config' value set to 'all'")),
> >>> +		OPT_INTEGER('n', "summary-limit", &summary_limit,
> >>> +			     N_("Limit the summary size")),
> >>> +		OPT_END()
> >>> +	};
> >>> +
> >>> +	const char *const git_submodule_helper_usage[] = {
> >>> +		N_("git submodule--helper summary [<options>] [commit] [--] [<path>]"),
> >>> +		NULL
> >>> +	};
> >>> +
> >>> +	argc = parse_options(argc, argv, prefix, module_summary_options,
> >>> +			     git_submodule_helper_usage, 0);
> >>> +
> >>> +	if (!summary_limit)
> >>> +		return 0;
> >>> +
> >>> +	cp_rev.git_cmd = 1;
> >>> +	argv_array_pushl(&cp_rev.args, "rev-parse", "-q", "--verify",
> >>> +			 argc ? argv[0] : "HEAD", NULL);
> >>
> >> Oy. Why not simply call `get_oid()`? No need to spawn a new process.
> > 
> > Then everytime we need 'rev-parse', we simply call 'get_oid()'? That
> > will save us a ton of processes?
> > 
> > But I think we do need to capture the output of 'git rev-parse --verify
> > ....' so I think it will backfire to use 'get_oid()' or am I just being
> > too dumb and not catching on something?
> > 
> 
> I'll leave this for others to answer.

I will resolve this one after Dscho answers then.

> >>> +
> >>> +	if (!capture_command(&cp_rev, &sb, 0)) {
> >>> +		strbuf_strip_suffix(&sb, "\n");
> >>> +		if (argc) {
> >>> +			argv++;
> >>> +			argc--;
> >>> +		}
> >>> +	} else if (!argc || !strcmp(argv[0], "HEAD")) {
> >>> +		/* before the first commit: compare with an empty tree */
> >>> +		struct stat st;
> >>> +		struct object_id oid;
> >>> +		if (fstat(0, &st) < 0 || index_fd(&the_index, &oid, 0, &st, 2,
> >>> +						  prefix, 3))
> >>> +			die("Unable to add %s to database", oid.hash);
> >>
> >> Umm. The original reads:
> >>
> >>                 # before the first commit: compare with an empty tree
> >>                 head=$(git hash-object -w -t tree --stdin </dev/null)
> >>
> >> It does not actually read from `stdin`. It reads from `/dev/null`,
> >> redirected to the input. And what it _actually_ does is to generate the
> >> OID of the empty tree.
> >>
> >> But we already _have_ the OID of the empty tree! It's
> >> `the_hash_algo->empty_tree`.
> > 
> > I did not know this 'the_hash_algo'. I will use it. Thanks! :)
> > 
> >> I hope that this is covered by the test suite. Please check that. The test
> >> would succeed with your version, but only because tests are run with
> >> `stdin` redirected from `/dev/null` by default.
> > 
> > I guess yes. My work passed because the tests are written this way.
> > 
> >>> +		strbuf_addstr(&sb, oid_to_hex(&oid));
> >>> +		if (argc) {
> >>> +			argv++;
> >>> +			argc--;
> >>> +		}
> >>> +	} else {
> >>> +		strbuf_addstr(&sb, "HEAD");
> >>> +	}
> >>
> >> The conversion to C would make for a fine excuse to simplify the logic.
> > 
> > This was kind of like the 'shift' in shell. What equivalent do you
> > suggest?
> > 
> 
> I think that's just a general comment after the other comments found
> just above about simplifying things.

Alright. But I do have to simplify the logic right?

> >>> +	if (files) {
> >>> +		if (cached)
> >>> +			die(_("--cached and --files are mutually exclusive"));
> >>> +		diff_cmd = DIFF_FILES;
> >>> +	}
> >>> +
> >>> +	info.argc = argc;
> >>> +	info.argv = argv;
> >>> +	info.prefix = prefix;
> >>> +	info.cached = !!cached;
> >>> +	info.for_status = !!for_status;
> >>> +	info.quiet = quiet;
> >>> +	info.files = files;
> >>> +	info.summary_limit = summary_limit;
> >>> +
> >>> +	ret = compute_summary_module_list((diff_cmd == DIFF_FILES) ? NULL : sb.buf,
> >>> +					   &info, diff_cmd);
> >>
> >> It would be better to pass the OID as `struct object_id *`, not as string.
> > 
> > Will do!
> > 
> >> Other than that, this patch nicely follows previous conversions from Unix
> >> shell scripts to C.
> >>
> >> Well done,
> >> Johannes
> > 
> > Thank you! It was a highly detailed review! I am still learning tons of
> > stuff about Git's code and such a review does help a lot! :)
> > 

> Hope this helps,

It surely did! Thanks Kaartic :0

^ permalink raw reply	[relevance 2%]

* Re: [PATCH 4/4] submodule: port submodule subcommand 'summary' from shell to C
  2020-07-05 17:34  2%     ` Shourya Shukla
@ 2020-07-06  9:16  4%       ` Kaartic Sivaraam
  2020-07-06 11:15  2%         ` Shourya Shukla
  0 siblings, 1 reply; 200+ results
From: Kaartic Sivaraam @ 2020-07-06  9:16 UTC (permalink / raw)
  To: Shourya Shukla
  Cc: Johannes Schindelin, git, christian.couder, gitster, liu.denton,
	pc44800, stefanbeller

Note: I've added some comment but I've not been able to address all the
parts due to lack of time. I'm sending it sooner hoping it would be
useful.

On 05-07-2020 23:04, Shourya Shukla wrote:
[...]
>> [exchanging Stefan Beller's dysfunct @google address for their private
>> one; I encourage you to do the same in the next iteration, probably
>> by editing the `Mentored-by:` line.]
> 
> I think you missed to mention it.
>

If you're looking for the private e-mail. The exachange was already done
and it was right there in the Cc list of the mail sent by Dscho. I've
added it again as you seem to have removed it.

>> On Fri, 3 Jul 2020, Shourya Shukla wrote:
>>
>>> From: Prathamesh Chavan <pc44800@gmail.com>
>>>
>>> The submodule subcommand 'summary' is ported in the process of
>>> making git-submodule a builtin. The function cmd_summary() from
>>> git-submodule.sh is ported to functions module_summary(),
>>> compute_summary_module_list(), prepare_submodule_summary() and
>>> generate_submodule_summary(), print_submodule_summary().
>>>
>>> The first function module_summary() parses the options of submodule
>>> subcommand and also acts as the front-end of this subcommand.
>>> After parsing them, it calls the compute_summary_module_list()
>>
>> Missing full-stop, and probably the sentence also wanted to say "function"
>> at the end.
> 
> I will correct. Thanks for pointing out!
> 
>>> The functions compute_summary_module_list() runs the diff_cmd,
>>> and generates the modules list, as required by the subcommand.
>>> The generation of this module list is done by the using the
>>
>> s/the using/using/
> 
> Will amend!
> 
>>> callback function submodule_summary_callback(), and stored in the
>>> structure module_cb.
>>
>> This explains nicely what the patch does. But the commit message should
>> not really repeat what can be readily deduced from the patch; It should
>> focus on the motivation and on interesting background information that is
>> _not_ readily deduced from the patch.
> 
> I understand. I will follow your suggestions regarding my patch.
> 
>> For example, I see that `$diff_cmd` is called twice in the shell script
>> version, once to "get modified modules cared by user" and then _again_,
>> with that list of modified modules.
>>
>> I would have liked to see a reasoning in the commit message that explains
>> why this has to be so in the C version. I get why it is complicated in a
>> shell script (which lacks proper objects, after all), but I would have
>> expected the C version to be able to accumulate the information with a
>> single pass.
>>
>> (Before writing the following paragraph, I actually reviewed the patch
>> from bottom to top, in the caller->callee direction.)
>>
>> Ah. I see that this indeed is the case: there is only one pass in the C
>> version. That's a useful piece of metadata for the commit message, I
>> think, much more useful than describing the call tree of the functions.
> 
> Yup that it worth mentioning.
> 
>> Another thing worth mentioning in the commit message is that we use the
>> combination of setting a child_process' working directory to the submodule
>> path and then calling `prepare_submodule_repo_env()` which also sets
>> `GIT_DIR` to `.git`, so that we can be certain that those spawned
>> processes will not access the superproject's ODB by mistake.
>>
>> When reading my suggestions, please keep in mind that I reviewed the
>> functions in caller->callee order, i.e. I started at the end of the patch
>> and then worked my way up.
>>
>> All in all, I like the function structure, but I think there is still a
>> bit room for improvement in a v2.
> 
>>> +static int verify_submodule_object_name(const char *sm_path,
>>> +					  const char *sha1)
>>> +{
>>> +	struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
>>> + > > +	cp_rev_parse.git_cmd = 1;
>>> +	cp_rev_parse.no_stdout = 1;
>>> +	cp_rev_parse.dir = sm_path;
>>
>> So here we specify `sm_path` as current working directory.
>>
>>> +	prepare_submodule_repo_env(&cp_rev_parse.env_array);
>>
>> And this implicitly sets `GIT_DIR=.git`. Good.
>>
>>> +	argv_array_pushl(&cp_rev_parse.args, "rev-parse", "-q",
>>> +			 "--verify", NULL);
>>> +	argv_array_pushf(&cp_rev_parse.args, "%s^0", sha1);
>>
>> After this, we should also append `--` to make sure that we're not parsing
>> this as a file name.
> 
> Will do!
> 
>> Two comments about naming: `sha1` is pretty misleading here, as we do not
>> require it to be a SHA-1 (especially in the future in which we switch to
>> SHA-256). Besides, what we're really asking for (via that `^0` suffix) is
>> a committish. Therefore, I would propose to use `committish` both in the
>> parameter name as well as the function name.
> 
> I am not aware of this change. I will take this suggestion into account.
> 
>>> +
>>> +	if (run_command(&cp_rev_parse))
>>> +		return 1;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static void print_submodule_summary(struct summary_cb *info, int errmsg,
>>> +				      int total_commits, int missing_src,
>>> +				      int missing_dst, const char *displaypath,
>>> +				      int is_sm_git_dir, struct module_cb *p)
>>> +{
>>> +	if (p->status == 'T') {
>>> +		if (S_ISGITLINK(p->mod_dst))
>>> +			printf(_("* %s %s(blob)->%s(submodule)"),
>>> +				 displaypath, find_unique_abbrev(&p->oid_src, 7),
>>
>> The shell script version does this:
>>
>>                 sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
>>                         echo $sha1_src | cut -c1-7)
>>
>> That is not quite the same, as it looks for the abbreviation _in the
>> submodule_, not in the current project. So I think `find_unique_abbrev()`
>> is not correct here.
>>
>> The funny thing is that we _already_ will have called `git rev-parse
>> --verify` for both `p->oid_src` and `p->oid_dst` in the submodule, in the
>> caller of this function! And while we throw away the result, and while we
>> do not pass `--short`, there is no reason why we shouldn't be able to do
>> precisely that.
> 
> Okay so you are saying that there is no need of a 'find_unique_abbrev()'
> since we would be easily able to obtain these values from the caller of
> 'print_submodule_summary()' right?

Yes. 'generate_submodule_summary' already does a rev-parse on
p->oid_src and p->oid_dst via 'verify_submodule_object_name'.
We should be able to get the short version of them by passing '--short'
to rev-parse there and make it return the short SHA1. We can then use it
like how Dscho mentions below.

> Maybe we can pass 'oid_src' or 'oid_dst' as an argument?
> 
>>> +				 find_unique_abbrev(&p->oid_dst, 7));
>>> +		else
>>> +			printf(_("* %s %s(submodule)->%s(blob)"),
>>> +				 displaypath, find_unique_abbrev(&p->oid_src, 7),
>>> +				 find_unique_abbrev(&p->oid_dst, 7));
>>> +	} else {
>>> +		printf("* %s %s...%s",
>>> +			displaypath, find_unique_abbrev(&p->oid_src, 7),
>>> +			find_unique_abbrev(&p->oid_dst, 7));
>>> +	}
>>> +
>>> +	if (total_commits < 0)
>>> +		printf(":\n");
>>> +	else
>>> +		printf(" (%d):\n", total_commits);
>>> +
>>> +	if (errmsg) {
>>> +		/*
>>> +		 * Don't give error msg for modification whose dst is not
>>> +		 * submodule, i.e. deleted or changed to blob
>>> +		 */
>>> +		if (S_ISGITLINK(p->mod_src)) {
>>> +			if (missing_src && missing_dst) {
>>> +				printf(_("  Warn: %s doesn't contain commits %s and %s\n"),
>>> +				       displaypath, oid_to_hex(&p->oid_src),
>>> +				       oid_to_hex(&p->oid_dst));
>>> +			} else if (missing_src) {
>>> +				printf(_("  Warn: %s doesn't contain commit %s\n"),
>>> +				       displaypath, oid_to_hex(&p->oid_src));
>>> +			} else {
>>> +				printf(_("  Warn: %s doesn't contain commit %s\n"),
>>> +				       displaypath, oid_to_hex(&p->oid_dst));
>>> +			}
>>> +		}
>>> +	} else if (is_sm_git_dir) {
>>> +		struct child_process cp_log = CHILD_PROCESS_INIT;
>>> +
>>> +		cp_log.git_cmd = 1;
>>> +		cp_log.dir = p->sm_path;
>>> +		prepare_submodule_repo_env(&cp_log.env_array);
>>
>> Since the working directory is set to the top-level directory of the
>> submodule, and since `prepare_submodule_repo_env()` sets `GIT_DIR` to
>> `.git`, I think that the `is_sm_git_dir` condition is unnecessary. In
>> fact, the entire `is_sm_git_dir` parameter (and local variable in the
>> caller, see more on that below) can go away.
> 
> Because we already set the $GIT_DIR to .git/ so an extra check will not
> be necessary right?
> 

Yes. If we remove that check and we get a p->sm_path that does not point
to a submodule, I wonder what would happen if we run 'run_command'
on it. I'm also not sure if that's a possible case. Something to
explore.

>>> +		argv_array_pushl(&cp_log.args, "log", NULL);
>>> +
>>> +		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
>>> +			if (info->summary_limit > 0)
>>> +				argv_array_pushf(&cp_log.args, "-%d",
>>> +						 info->summary_limit);
>>> +
>>> +			argv_array_pushl(&cp_log.args, "--pretty=  %m %s",
>>> +					 "--first-parent", NULL);
>>> +			argv_array_pushf(&cp_log.args, "%s...%s",
>>> +					 oid_to_hex(&p->oid_src),
>>> +					 oid_to_hex(&p->oid_dst));
>>> +		} else if (S_ISGITLINK(p->mod_dst)) {
>>> +			argv_array_pushl(&cp_log.args, "--pretty=  > %s",
>>> +					 "-1", oid_to_hex(&p->oid_dst), NULL);
>>> +		} else {
>>> +			argv_array_pushl(&cp_log.args, "--pretty=  < %s",
>>> +					 "-1", oid_to_hex(&p->oid_src), NULL);
>>> +		}
>>> +		run_command(&cp_log);
>>> +	}
>>> +	printf("\n");
>>> +}
>>
>> It looks as if there is a whole lot of `oid_to_hex(&p->oid_src)` in that
>> function. Together with the realization that we need the abbreviated
>> version of that at least in one place, and the other realization that we
>> already call `rev-parse --verify` for both `oid_src` and `oid_dst` in the
>> caller of this function, it seems to suggest itself that we would actually
>> want to pass the `--short` option, too, and to capture the output, and
>> pass it down to `print_submodule_summary()` _instead of_ `missing_src` and
>> `missing_dst` (e.g. as `src_abbrev` and `dst_abbrev`).
> 
> Oh you have mentioned it here too. This seems quite a good approach. I
> will adopt this.
> 
>>> +
>>> +static void generate_submodule_summary(struct summary_cb *info,
>>> +				       struct module_cb *p)
>>> +{
>>> +	int missing_src = 0;
>>> +	int missing_dst = 0;
>>> +	char *displaypath;
>>> +	int errmsg = 0;
>>> +	int total_commits = -1;
>>> +	int is_sm_git_dir = 0;
>>> +	struct strbuf sm_git_dir_sb = STRBUF_INIT;
>>> +
>>> +	if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
>>> +		if (S_ISGITLINK(p->mod_dst)) {
>>> +			/*
>>> +			 * NEEDSWORK: avoid using separate process with
>>> +			 * the help of the function head_ref_submodule()
>>
>> I don't quite understand this comment. There is no `head_ref_submodule()`
>> function.
>>

That NEEDSWORK was added based on Stefan's comment on a previous version
of Prathamesh's patch. Here it is for reference:

>> +       if (!info->cached && !oidcmp(&p->oid_dst, &null_oid)) {
>> +               if (S_ISGITLINK(p->mod_dst)) {
>> +                       struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
>> +                       struct strbuf sb_rev_parse = STRBUF_INIT;
>> +
>> +                       cp_rev_parse.git_cmd = 1;
>> +                       cp_rev_parse.no_stderr = 1;
>> +                       cp_rev_parse.dir = p->sm_path;
>> +                       prepare_submodule_repo_env(&cp_rev_parse.env_array);
>> +
>> +                       argv_array_pushl(&cp_rev_parse.args,
>> +                                        "rev-parse", "HEAD", NULL);
>> +                       if (!capture_command(&cp_rev_parse, &sb_rev_parse, 0)) {
>> +                               strbuf_strip_suffix(&sb_rev_parse, "\n");
>> +
>> +                               get_oid_hex(sb_rev_parse.buf, &p->oid_dst);
>> +                       }
>> +                       strbuf_release(&sb_rev_parse);
> 
> I think this could be replaced via
> head_ref_submodule(sub->path, callback function, &where_to_store)
> or is there some trickery going on, that this also works on
> non-compliant submodules?
> (Maybe add that as a NEEDSWORK/TODO)

Ref:
https://public-inbox.org/git/CAGZ79kaWn9z47Va=VW4R2Aswws1N5n2u4Kvatn73s0YnV0pVqQ@mail.gmail.com/

A quick search reveals that 'head_ref_submodule' existed during that
period. On further investigation it seems that 'refs_head_ref' was
introduced in 62f0b399e0 (refs: add refs_head_ref(), 2017-08-23) and
'head_ref_submodule' was made to use it. Later on, in 419221c106 (refs:
remove dead for_each_*_submodule(), 2017-08-23), 'head_ref-submodule'
was removed with an advice to use the 'refs_' API for accessing
submodules.

> +* Use `refs_` API for accessing submodules. The submodule ref store could
> +  be obtained with `get_submodule_ref_store()`

How it applies to our code is something to be looked into, yet.

>>> +			 */
>>> +			struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
>>> +			struct strbuf sb_rev_parse = STRBUF_INIT;
>>> +
>>> +			cp_rev_parse.git_cmd = 1;
>>> +			cp_rev_parse.no_stderr = 1;
>>> +			cp_rev_parse.dir = p->sm_path;
>>> +			prepare_submodule_repo_env(&cp_rev_parse.env_array);
>>> +
>>> +			argv_array_pushl(&cp_rev_parse.args, "rev-parse",
>>> +					 "HEAD", NULL);
>>> +			if (!capture_command(&cp_rev_parse, &sb_rev_parse, 0)) {
>>> +				strbuf_strip_suffix(&sb_rev_parse, "\n");
>>> +				get_oid_hex(sb_rev_parse.buf, &p->oid_dst);
>>> +			}
>>> +			strbuf_release(&sb_rev_parse);
>>> +		} else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
>>> +			struct child_process cp_hash_object = CHILD_PROCESS_INIT;
>>> +			struct strbuf sb_hash_object = STRBUF_INIT;
>>> +
>>> +			cp_hash_object.git_cmd = 1;
>>> +			argv_array_pushl(&cp_hash_object.args, "hash-object",
>>> +					 p->sm_path, NULL);
>>> +			if (!capture_command(&cp_hash_object,
>>> +					     &sb_hash_object, 0)) {
>>> +				strbuf_strip_suffix(&sb_hash_object, "\n");
>>> +				get_oid_hex(sb_hash_object.buf, &p->oid_dst);
>>> +			}
>>> +			strbuf_release(&sb_hash_object);
>>
>> It would probably be shorter, less error-prone, and quicker to use
>> `index_fd()` directly.
>>
>> BTW I am not quite sure that this code does the correct thing in case of a
>> symlink: it hashes the contents of the symlink target (if it is a file,
>> otherwise it errors out). But that is hardly an issue introduced by the
>> conversion, that's just copied from `git-submodule.sh`.
>>
>>> +		} else {
>>> +			if (p->mod_dst)
>>> +				die(_("unexpected mode %d\n"), p->mod_dst);
>>
>> Hmm. This does not match what the shell script version does:
>>
>>                         *)
>>                                 # unexpected type
>>                                 eval_gettextln "unexpected mode \$mod_dst" >&2
>>                                 continue ;;
>>
>> I think we should also just write the message to `stderr` and continue,
>> not `die()`.
>>
>> In addition to that, I am missing the C code for this case:
>>
>>                         000000)
>>                                 ;; # removed
>>
>> It is quite possible that our test suite does not cover this case (or did
>> the test suite fail for you?). If that is indeed the case, it would be
>> really good to add a test case as part of this patch series, to gain
>> confidence in the correctness of the conversion.
> 
> The tests passed for me actually. Whether this is covered by the test
> cases, I am not sure. I will have to check it.
> 
>>> +		}
>>> +	}
>>> +
>>> +	strbuf_addstr(&sm_git_dir_sb, p->sm_path);
>>
>> I have to admit that I am not loving the name `sm_git_dir_sb`. Why not
>> `submodule_git_dir`? I guess you copied it from elsewhere in
>> `submodule--helper.c`...
>>
>>> +	if (is_nonbare_repository_dir(&sm_git_dir_sb))
>>> +		is_sm_git_dir = 1;
>>
>> So here, we verify whether there is a repository at `p->sm_path`. I don't
>> see that in the shell script version:
>>
>>                 missing_src=
>>                 missing_dst=
>>
>>                 test $mod_src = 160000 &&
>>                 ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
>>                 missing_src=t
>>
>>                 test $mod_dst = 160000 &&
>>                 ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
>>                 missing_dst=t
>>
>> Let's read a bit further.
>>
>>> +
>>> +	if (is_sm_git_dir && S_ISGITLINK(p->mod_src))
>>> +		missing_src = verify_submodule_object_name(p->sm_path,
>>> +							   oid_to_hex(&p->oid_src));
>>
>> Ah, and `verify_submodule_object_name()` uses `p->sm_path` as working
>> directory. But that's not what the shell script version did: it specified
>> the `GIT_DIR` explicitly.
>>
>> And by using the `prepare_submodule_repo_env()` function in
>> `verify_submodule_object_name()`, we specify `GIT_DIR` implicitly, as I
>> pointed out in my comment on that function.
> 
> Oh so you're saying that it will be better to call
> 'prepare_submodule_repo_env()' on some variable since we explicitly want to
> store the path to GIT_DIR?
> 

We already call 'prepare_submodule_repo_env' in
'verify_submodule_object_name'. So, he's likely saying that
'is_sm_git_dir' is unnecessary here.

> It would be of much help if you could explain this part just a little
> more (for my own sake).
> 
>> So I think that `is_sm_git_dir` might be
> 

... unnecessary.

> I think you missed something here...
> 

That's likely what he meant based on what is mentioned above.

>>> +
>>> +	if (is_sm_git_dir && S_ISGITLINK(p->mod_dst))
>>> +		missing_dst = verify_submodule_object_name(p->sm_path,
>>> +							   oid_to_hex(&p->oid_dst));
>>> +
>>> +	displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
>>> +
>>> +	if (!missing_dst && !missing_src) {
>>> +		if (is_sm_git_dir) {
>>> +			struct child_process cp_rev_list = CHILD_PROCESS_INIT;
>>> +			struct strbuf sb_rev_list = STRBUF_INIT;
>>> +			char *range;
>>> +
>>> +			if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
>>> +				range = xstrfmt("%s...%s", oid_to_hex(&p->oid_src),
>>> +						oid_to_hex(&p->oid_dst));
>>> +			else if (S_ISGITLINK(p->mod_src))
>>> +				range = xstrdup(oid_to_hex(&p->oid_src));
>>> +			else
>>> +				range = xstrdup(oid_to_hex(&p->oid_dst));
>>> +
>>> +			cp_rev_list.git_cmd = 1;
>>> +			cp_rev_list.dir = p->sm_path;
>>> +			prepare_submodule_repo_env(&cp_rev_list.env_array);
>>
>> Again, due to setting the working directory to `p->sm_path` and
>> (implicitly, via `prepare_submodule_repo_env()`) `GIT_DIR` to `.git`, I do
>> not think that we have to guard this block beind `is_sm_git_dir`.
> 
>>> +
>>> +			argv_array_pushl(&cp_rev_list.args, "rev-list",
>>> +					 "--first-parent", range, "--", NULL);
>>
>> Since `argv_array_push()` duplicates the strings, anyway, we can totally
>> avoid the need for the `range` variable:
>>
>> 			if (IS_GITLINK(p->mod_src) && IS_GITLINK(p->mod_dst))
>> 				argv_array_pushf(&cp_rev_list.args, "%s...%s",
>> 						 oid_to_hex(&p->oid_src),
>> 						 oid_to_hex(&p->oid_dst));
>> 			else
>> 				argv_array_push(&cp_rev_list.args, IS_GITLINK(p->mod_src) ?
>> 						oid_to_hex(&p->oid_src) :
>> 						oid_to_hex(&p->oid_dst));
>>
>>> +			if (!capture_command(&cp_rev_list, &sb_rev_list, 0)) {
>>> +				if (sb_rev_list.len)
>>> +					total_commits = count_lines(sb_rev_list.buf,
>>> +								    sb_rev_list.len);
>>
>> That's actually not necessary. `git rev-list --count` will give you a nice
>> number, no need to capture a potentially large amount of memory only to
>> count the lines.
>>
>> This may also make the patch obsolete that makes `count_lines()` public.
> 
> Therefore we eliminate count_lines() from here and instead do a 'git
> rev-list --count'?
> 

Yes.

>>> +				else
>>> +					total_commits = 0;
>>> +			}
>>
>>> +
>>> +			free(range);
>>> +			strbuf_release(&sb_rev_list);
>>> +		}
>>> +	} else {
>>> +		errmsg = 1;
>>> +	}
>>
>> I am missing the equivalent for these lines here:
>>
>>                 t,)
>>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
>>                         ;;
>>                 ,t)
>>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
>>                         ;;
>>                 t,t)
>>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$ ha1_dst")"
>>                         ;;
> 
> I will add them.
> 

I think they're already there in the 'print_submodule_summary' function
above.

>> I am not quite sure whether it is a good idea to leave it to the
>> `print_submodule_summary()` function to generate the `errmsg`. I think I'd
>> rather have it a `char *` than an `int`.
> 
> Would it be better to add these error messages in
> 'prepare_submodule_summary()'?

No. He's likely saying that instead of setting `errmsg` to 1 and
constructing the error message in `print_submodule_summary` we should
be having the error messages in `generate_submodule_summary` and pass
them to `print_submodule_summary` instead of passing an int.

> If we have error messages as integers
> then we will simply
> 

You missed something here. ;)

>>> +
>>> +	print_submodule_summary(info, errmsg, total_commits,
>>> +				missing_src, missing_dst,
>>> +		      		displaypath, is_sm_git_dir, p);
>>> +
>>> +	free(displaypath);
>>> +	strbuf_release(&sm_git_dir_sb);
>>> +}
>>> +
>>> +static void prepare_submodule_summary(struct summary_cb *info,
>>> +				      struct module_cb_list *list)
>>> +{
>>> +	int i;
>>> +	for (i = 0; i < list->nr; i++) {
>>> +		struct module_cb *p = list->entries[i];
>>> +		struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
>>> +
>>> +		if (p->status == 'D' || p->status == 'T') {
>>> +			generate_submodule_summary(info, p);
>>> +			continue;
>>> +		}
>>> +
>>> +		if (info->for_status) {
>>> +			char *config_key;
>>
>> Since the `config_key` is only used within the `if()` block it would be
>> better to declare it within that block.
>>
>>> +			const char *ignore_config = "none";
>>
>> Since the only value we ever care about is "all", how about turning this
>> into an `int`, setting it to `0` here, and later assigning it to
>> `!strcmp(value, "all")` and `!strcmp(sub->ignore, "all")`, respectively?
> 
> Alright will do!
> 
>> I mean, I get it. Unix shell scripts are all about passing around text.
>> And it is much easier to just translate that to C faithfully. But that
>> does not make it good C code. C has data types, and proper C code makes
>> use of that.
>>
>>> +			const char *value;
>>
>> If you want to save on lines, you can cuddle this together with other
>> declarations of the same type. Even so, it could be scoped more narrowly.
>>
>>> +			const struct submodule *sub = submodule_from_path(the_repository,
>>> +									  &null_oid,
>>> +									  p->sm_path);
>>> +
>>> +			if (sub && p->status != 'A') {
>>
>> Good. The shell script version _always_ retrieved the `.ignore` config
>> value, even if the `status` is `A`. Your version is much better.
>>
>> But why bother calling `submodule_from_path()` if the status is `A`?
> 
> What exactly does a status of 'A' or 'T' mean? I mean I know what we are
> doing but what exactly do these translate into?
> 

Its interesting you understood it without knowing what 'A' and 'T'
meant. Anyways, if you take a look at the documentation of
'diff-index'[1] which provides us the `status` you'll know that:
> 
> Possible status letters are:
> 
>     A: addition of a file
> 
>     C: copy of a file into a new one
> 
>     D: deletion of a file
> 
>     M: modification of the contents or mode of a file
> 
>     R: renaming of a file
> 
>     T: change in the type of the file
> 
>     U: file is unmerged (you must complete the merge before it can be committed)
> 
>     X: "unknown" change type (most probably a bug, please report it)
> 

[1]: https://git-scm.com/docs/git-diff-index

>> I could actually see the `const struct submodule *sub;` declaration be
>> pulled out of this scope, and combining the `if (info->for_status &&
>> p->status != 'A'), and the moving the assignment of `sub` into the `else
>> if ((sub = submodule_from_path(r, &null_oid, p->sm_path)) &&
>> sub->ignore)`.
>>
>> That would save us one entire indentation level.
> 
> That seems a good approach! I will try this out.
> 
>>> +				config_key = xstrfmt("submodule.%s.ignore",
>>> +						     sub->name);
>>> +				if (!git_config_get_string_const(config_key, &value))
>>> +					ignore_config = value;
>>> +				else if (sub->ignore)
>>> +					ignore_config = sub->ignore;
>>> +
>>> +				free(config_key);
>>> +				if (!strcmp(ignore_config, "all"))
>>> +					continue;
>>> +			}
>>> +		}
>>> +
>>> +		/* Also show added or modified modules which are checked out */
>>> +		cp_rev_parse.dir = p->sm_path;
>>> +		cp_rev_parse.git_cmd = 1;
>>> +		cp_rev_parse.no_stderr = 1;
>>> +		cp_rev_parse.no_stdout = 1;
>>> +
>>> +		argv_array_pushl(&cp_rev_parse.args, "rev-parse",
>>> +				 "--git-dir", NULL);
>>> +
>>> +		if (!run_command(&cp_rev_parse))
>>
>> I wonder whether we really need to waste an entire spawned process on
>> figuring out whether `p->sm_path` refers to an active repository. Wouldn't
>> `is_submodule_active(r, p->sm_path)` fulfill the same purpose?
> 
> Yep! This is correct. I will change.
> 
>>> +			generate_submodule_summary(info, p);
>>> +	}
>>> +}
>>> +
>>> +static void submodule_summary_callback(struct diff_queue_struct *q,
>>> +				       struct diff_options *options,
>>> +				       void *data)
>>> +{
>>> +	int i;
>>> +	struct module_cb_list *list = data;
>>> +	for (i = 0; i < q->nr; i++) {
>>> +		struct diff_filepair *p = q->queue[i];
>>> +		struct module_cb *temp;
>>> +
>>> +		if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
>>> +			continue;
>>> +		temp = (struct module_cb*)malloc(sizeof(struct module_cb));
>>> +		temp->mod_src = p->one->mode;
>>> +		temp->mod_dst = p->two->mode;
>>> +		temp->oid_src = p->one->oid;
>>> +		temp->oid_dst = p->two->oid;
>>> +		temp->status = p->status;
>>> +		temp->sm_path = xstrdup(p->one->path);
>>> +
>>> +		ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
>>> +		list->entries[list->nr++] = temp;
>>> +	}
>>> +}
>>> +
>>> +static const char *get_diff_cmd(enum diff_cmd diff_cmd)
>>> +{
>>> +	switch (diff_cmd) {
>>> +	case DIFF_INDEX: return "diff-index";
>>> +	case DIFF_FILES: return "diff-files";
>>> +	default: BUG("bad diff_cmd value %d", diff_cmd);
>>> +	}
>>> +}
>>> +
>>> +static int compute_summary_module_list(char *head,
>>> +				         struct summary_cb *info,
>>> +				         enum diff_cmd diff_cmd)
>>> +{
>>> +	struct argv_array diff_args = ARGV_ARRAY_INIT;
>>> +	struct rev_info rev;
>>> +	struct module_cb_list list = MODULE_CB_LIST_INIT;
>>> +
>>> +	argv_array_push(&diff_args, get_diff_cmd(diff_cmd));
>>> +	if (info->cached)
>>> +		argv_array_push(&diff_args, "--cached");
>>> +	argv_array_pushl(&diff_args, "--ignore-submodules=dirty", "--raw",
>>> +			 NULL);
>>> +	if (head)
>>> +		argv_array_push(&diff_args, head);
>>> +	argv_array_push(&diff_args, "--");
>>> +	if (info->argc)
>>> +		argv_array_pushv(&diff_args, info->argv);
>>> +
>>> +	git_config(git_diff_basic_config, NULL);
>>> +	init_revisions(&rev, info->prefix);
>>> +	rev.abbrev = 0;
>>> +	precompose_argv(diff_args.argc, diff_args.argv);
>>> +
>>> +	diff_args.argc = setup_revisions(diff_args.argc, diff_args.argv,
>>> +					 &rev, NULL);
>>> +	rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
>>> +	rev.diffopt.format_callback = submodule_summary_callback;
>>> +	rev.diffopt.format_callback_data = &list;
>>> +
>>> +	if (!info->cached) {
>>> +		if (diff_cmd ==  DIFF_INDEX)
>>
>> Please substitute the double-space by a single one.
> 
> Will do!
> 
>>> +			setup_work_tree();
>>> +		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
>>> +			perror("read_cache_preload");
>>> +			return -1;
>>> +		}
>>> +	} else if (read_cache() < 0) {
>>> +		perror("read_cache");
>>> +		return -1;
>>> +	}
>>> +
>>> +	if (diff_cmd == DIFF_INDEX)
>>> +		run_diff_index(&rev, info->cached);
>>> +	else
>>> +		run_diff_files(&rev, 0);
>>> +	prepare_submodule_summary(info, &list);
>>> +	return 0;
>>> +}
>>> +
>>> +static int module_summary(int argc, const char **argv, const char *prefix)
>>> +{
>>> +	struct summary_cb info = SUMMARY_CB_INIT;
>>> +	int cached = 0;
>>> +	int for_status = 0;
>>> +	int quiet = 0;
>>> +	int files = 0;
>>> +	int summary_limit = -1;
>>> +	struct child_process cp_rev = CHILD_PROCESS_INIT;
>>> +	struct strbuf sb = STRBUF_INIT;
>>> +	enum diff_cmd diff_cmd = DIFF_INDEX;
>>> +	int ret;
>>> +
>>> +	struct option module_summary_options[] = {
>>> +		OPT__QUIET(&quiet, N_("Suppress output of summarising submodules")),
>>> +		OPT_BOOL(0, "cached", &cached,
>>> +			 N_("Use the commit stored in the index instead of the submodule HEAD")),
>>> +		OPT_BOOL(0, "files", &files,
>>> +			 N_("To compare the commit in the index with that in the submodule HEAD")),
>>> +		OPT_BOOL(0, "for-status", &for_status,
>>> +			 N_("Skip submodules with 'ignore_config' value set to 'all'")),
>>> +		OPT_INTEGER('n', "summary-limit", &summary_limit,
>>> +			     N_("Limit the summary size")),
>>> +		OPT_END()
>>> +	};
>>> +
>>> +	const char *const git_submodule_helper_usage[] = {
>>> +		N_("git submodule--helper summary [<options>] [commit] [--] [<path>]"),
>>> +		NULL
>>> +	};
>>> +
>>> +	argc = parse_options(argc, argv, prefix, module_summary_options,
>>> +			     git_submodule_helper_usage, 0);
>>> +
>>> +	if (!summary_limit)
>>> +		return 0;
>>> +
>>> +	cp_rev.git_cmd = 1;
>>> +	argv_array_pushl(&cp_rev.args, "rev-parse", "-q", "--verify",
>>> +			 argc ? argv[0] : "HEAD", NULL);
>>
>> Oy. Why not simply call `get_oid()`? No need to spawn a new process.
> 
> Then everytime we need 'rev-parse', we simply call 'get_oid()'? That
> will save us a ton of processes?
> 
> But I think we do need to capture the output of 'git rev-parse --verify
> ....' so I think it will backfire to use 'get_oid()' or am I just being
> too dumb and not catching on something?
> 

I'll leave this for others to answer.

>>> +
>>> +	if (!capture_command(&cp_rev, &sb, 0)) {
>>> +		strbuf_strip_suffix(&sb, "\n");
>>> +		if (argc) {
>>> +			argv++;
>>> +			argc--;
>>> +		}
>>> +	} else if (!argc || !strcmp(argv[0], "HEAD")) {
>>> +		/* before the first commit: compare with an empty tree */
>>> +		struct stat st;
>>> +		struct object_id oid;
>>> +		if (fstat(0, &st) < 0 || index_fd(&the_index, &oid, 0, &st, 2,
>>> +						  prefix, 3))
>>> +			die("Unable to add %s to database", oid.hash);
>>
>> Umm. The original reads:
>>
>>                 # before the first commit: compare with an empty tree
>>                 head=$(git hash-object -w -t tree --stdin </dev/null)
>>
>> It does not actually read from `stdin`. It reads from `/dev/null`,
>> redirected to the input. And what it _actually_ does is to generate the
>> OID of the empty tree.
>>
>> But we already _have_ the OID of the empty tree! It's
>> `the_hash_algo->empty_tree`.
> 
> I did not know this 'the_hash_algo'. I will use it. Thanks! :)
> 
>> I hope that this is covered by the test suite. Please check that. The test
>> would succeed with your version, but only because tests are run with
>> `stdin` redirected from `/dev/null` by default.
> 
> I guess yes. My work passed because the tests are written this way.
> 
>>> +		strbuf_addstr(&sb, oid_to_hex(&oid));
>>> +		if (argc) {
>>> +			argv++;
>>> +			argc--;
>>> +		}
>>> +	} else {
>>> +		strbuf_addstr(&sb, "HEAD");
>>> +	}
>>
>> The conversion to C would make for a fine excuse to simplify the logic.
> 
> This was kind of like the 'shift' in shell. What equivalent do you
> suggest?
> 

I think that's just a general comment after the other comments found
just above about simplifying things.

>>> +	if (files) {
>>> +		if (cached)
>>> +			die(_("--cached and --files are mutually exclusive"));
>>> +		diff_cmd = DIFF_FILES;
>>> +	}
>>> +
>>> +	info.argc = argc;
>>> +	info.argv = argv;
>>> +	info.prefix = prefix;
>>> +	info.cached = !!cached;
>>> +	info.for_status = !!for_status;
>>> +	info.quiet = quiet;
>>> +	info.files = files;
>>> +	info.summary_limit = summary_limit;
>>> +
>>> +	ret = compute_summary_module_list((diff_cmd == DIFF_FILES) ? NULL : sb.buf,
>>> +					   &info, diff_cmd);
>>
>> It would be better to pass the OID as `struct object_id *`, not as string.
> 
> Will do!
> 
>> Other than that, this patch nicely follows previous conversions from Unix
>> shell scripts to C.
>>
>> Well done,
>> Johannes
> 
> Thank you! It was a highly detailed review! I am still learning tons of
> stuff about Git's code and such a review does help a lot! :)
> 

Hope this helps,
Sivaraam

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 4/4] submodule: port submodule subcommand 'summary' from shell to C
  2020-07-03 20:46  4%   ` Johannes Schindelin
@ 2020-07-05 17:34  2%     ` Shourya Shukla
  2020-07-06  9:16  4%       ` Kaartic Sivaraam
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-07-05 17:34 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: git, christian.couder, gitster, liu.denton, kaartic.sivaraam,
	pc44800

Hello Dscho!

Before replying, one thing I want to clarify is that I ask various
things for double-checking since if I get even the slightest confusion I
start overthinking and destroying it all for myself. Please bear with me
and confirm/clarify stuff wherever possible. Would be of great help! :)

> Hi Shourya,
> 
> [exchanging Stefan Beller's dysfunct @google address for their private
> one; I encourage you to do the same in the next iteration, probably
> by editing the `Mentored-by:` line.]

I think you missed to mention it.

> On Fri, 3 Jul 2020, Shourya Shukla wrote:
> 
> > From: Prathamesh Chavan <pc44800@gmail.com>
> >
> > The submodule subcommand 'summary' is ported in the process of
> > making git-submodule a builtin. The function cmd_summary() from
> > git-submodule.sh is ported to functions module_summary(),
> > compute_summary_module_list(), prepare_submodule_summary() and
> > generate_submodule_summary(), print_submodule_summary().
> >
> > The first function module_summary() parses the options of submodule
> > subcommand and also acts as the front-end of this subcommand.
> > After parsing them, it calls the compute_summary_module_list()
> 
> Missing full-stop, and probably the sentence also wanted to say "function"
> at the end.

I will correct. Thanks for pointing out!

> > The functions compute_summary_module_list() runs the diff_cmd,
> > and generates the modules list, as required by the subcommand.
> > The generation of this module list is done by the using the
> 
> s/the using/using/

Will amend!

> > callback function submodule_summary_callback(), and stored in the
> > structure module_cb.
> 
> This explains nicely what the patch does. But the commit message should
> not really repeat what can be readily deduced from the patch; It should
> focus on the motivation and on interesting background information that is
> _not_ readily deduced from the patch.

I understand. I will follow your suggestions regarding my patch.

> For example, I see that `$diff_cmd` is called twice in the shell script
> version, once to "get modified modules cared by user" and then _again_,
> with that list of modified modules.
> 
> I would have liked to see a reasoning in the commit message that explains
> why this has to be so in the C version. I get why it is complicated in a
> shell script (which lacks proper objects, after all), but I would have
> expected the C version to be able to accumulate the information with a
> single pass.
> 
> (Before writing the following paragraph, I actually reviewed the patch
> from bottom to top, in the caller->callee direction.)
> 
> Ah. I see that this indeed is the case: there is only one pass in the C
> version. That's a useful piece of metadata for the commit message, I
> think, much more useful than describing the call tree of the functions.

Yup that it worth mentioning.

> Another thing worth mentioning in the commit message is that we use the
> combination of setting a child_process' working directory to the submodule
> path and then calling `prepare_submodule_repo_env()` which also sets
> `GIT_DIR` to `.git`, so that we can be certain that those spawned
> processes will not access the superproject's ODB by mistake.
> 
> When reading my suggestions, please keep in mind that I reviewed the
> functions in caller->callee order, i.e. I started at the end of the patch
> and then worked my way up.
> 
> All in all, I like the function structure, but I think there is still a
> bit room for improvement in a v2.

> > +static int verify_submodule_object_name(const char *sm_path,
> > +					  const char *sha1)
> > +{
> > +	struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> > + > > +	cp_rev_parse.git_cmd = 1;
> > +	cp_rev_parse.no_stdout = 1;
> > +	cp_rev_parse.dir = sm_path;
> 
> So here we specify `sm_path` as current working directory.
> 
> > +	prepare_submodule_repo_env(&cp_rev_parse.env_array);
> 
> And this implicitly sets `GIT_DIR=.git`. Good.
> 
> > +	argv_array_pushl(&cp_rev_parse.args, "rev-parse", "-q",
> > +			 "--verify", NULL);
> > +	argv_array_pushf(&cp_rev_parse.args, "%s^0", sha1);
> 
> After this, we should also append `--` to make sure that we're not parsing
> this as a file name.

Will do!

> Two comments about naming: `sha1` is pretty misleading here, as we do not
> require it to be a SHA-1 (especially in the future in which we switch to
> SHA-256). Besides, what we're really asking for (via that `^0` suffix) is
> a committish. Therefore, I would propose to use `committish` both in the
> parameter name as well as the function name.

I am not aware of this change. I will take this suggestion into account.

> > +
> > +	if (run_command(&cp_rev_parse))
> > +		return 1;
> > +
> > +	return 0;
> > +}
> > +
> > +static void print_submodule_summary(struct summary_cb *info, int errmsg,
> > +				      int total_commits, int missing_src,
> > +				      int missing_dst, const char *displaypath,
> > +				      int is_sm_git_dir, struct module_cb *p)
> > +{
> > +	if (p->status == 'T') {
> > +		if (S_ISGITLINK(p->mod_dst))
> > +			printf(_("* %s %s(blob)->%s(submodule)"),
> > +				 displaypath, find_unique_abbrev(&p->oid_src, 7),
> 
> The shell script version does this:
> 
>                 sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
>                         echo $sha1_src | cut -c1-7)
> 
> That is not quite the same, as it looks for the abbreviation _in the
> submodule_, not in the current project. So I think `find_unique_abbrev()`
> is not correct here.
> 
> The funny thing is that we _already_ will have called `git rev-parse
> --verify` for both `p->oid_src` and `p->oid_dst` in the submodule, in the
> caller of this function! And while we throw away the result, and while we
> do not pass `--short`, there is no reason why we shouldn't be able to do
> precisely that.

Okay so you are saying that there is no need of a 'find_unique_abbrev()'
since we would be easily able to obtain these values from the caller of
'print_submodule_summary()' right? Maybe we can pass 'oid_src' or
'oid_dst' as an argument?

> > +				 find_unique_abbrev(&p->oid_dst, 7));
> > +		else
> > +			printf(_("* %s %s(submodule)->%s(blob)"),
> > +				 displaypath, find_unique_abbrev(&p->oid_src, 7),
> > +				 find_unique_abbrev(&p->oid_dst, 7));
> > +	} else {
> > +		printf("* %s %s...%s",
> > +			displaypath, find_unique_abbrev(&p->oid_src, 7),
> > +			find_unique_abbrev(&p->oid_dst, 7));
> > +	}
> > +
> > +	if (total_commits < 0)
> > +		printf(":\n");
> > +	else
> > +		printf(" (%d):\n", total_commits);
> > +
> > +	if (errmsg) {
> > +		/*
> > +		 * Don't give error msg for modification whose dst is not
> > +		 * submodule, i.e. deleted or changed to blob
> > +		 */
> > +		if (S_ISGITLINK(p->mod_src)) {
> > +			if (missing_src && missing_dst) {
> > +				printf(_("  Warn: %s doesn't contain commits %s and %s\n"),
> > +				       displaypath, oid_to_hex(&p->oid_src),
> > +				       oid_to_hex(&p->oid_dst));
> > +			} else if (missing_src) {
> > +				printf(_("  Warn: %s doesn't contain commit %s\n"),
> > +				       displaypath, oid_to_hex(&p->oid_src));
> > +			} else {
> > +				printf(_("  Warn: %s doesn't contain commit %s\n"),
> > +				       displaypath, oid_to_hex(&p->oid_dst));
> > +			}
> > +		}
> > +	} else if (is_sm_git_dir) {
> > +		struct child_process cp_log = CHILD_PROCESS_INIT;
> > +
> > +		cp_log.git_cmd = 1;
> > +		cp_log.dir = p->sm_path;
> > +		prepare_submodule_repo_env(&cp_log.env_array);
> 
> Since the working directory is set to the top-level directory of the
> submodule, and since `prepare_submodule_repo_env()` sets `GIT_DIR` to
> `.git`, I think that the `is_sm_git_dir` condition is unnecessary. In
> fact, the entire `is_sm_git_dir` parameter (and local variable in the
> caller, see more on that below) can go away.

Because we already set the $GIT_DIR to .git/ so an extra check will not
be necessary right?

> > +		argv_array_pushl(&cp_log.args, "log", NULL);
> > +
> > +		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
> > +			if (info->summary_limit > 0)
> > +				argv_array_pushf(&cp_log.args, "-%d",
> > +						 info->summary_limit);
> > +
> > +			argv_array_pushl(&cp_log.args, "--pretty=  %m %s",
> > +					 "--first-parent", NULL);
> > +			argv_array_pushf(&cp_log.args, "%s...%s",
> > +					 oid_to_hex(&p->oid_src),
> > +					 oid_to_hex(&p->oid_dst));
> > +		} else if (S_ISGITLINK(p->mod_dst)) {
> > +			argv_array_pushl(&cp_log.args, "--pretty=  > %s",
> > +					 "-1", oid_to_hex(&p->oid_dst), NULL);
> > +		} else {
> > +			argv_array_pushl(&cp_log.args, "--pretty=  < %s",
> > +					 "-1", oid_to_hex(&p->oid_src), NULL);
> > +		}
> > +		run_command(&cp_log);
> > +	}
> > +	printf("\n");
> > +}
> 
> It looks as if there is a whole lot of `oid_to_hex(&p->oid_src)` in that
> function. Together with the realization that we need the abbreviated
> version of that at least in one place, and the other realization that we
> already call `rev-parse --verify` for both `oid_src` and `oid_dst` in the
> caller of this function, it seems to suggest itself that we would actually
> want to pass the `--short` option, too, and to capture the output, and
> pass it down to `print_submodule_summary()` _instead of_ `missing_src` and
> `missing_dst` (e.g. as `src_abbrev` and `dst_abbrev`).

Oh you have mentioned it here too. This seems quite a good approach. I
will adopt this.

> > +
> > +static void generate_submodule_summary(struct summary_cb *info,
> > +				       struct module_cb *p)
> > +{
> > +	int missing_src = 0;
> > +	int missing_dst = 0;
> > +	char *displaypath;
> > +	int errmsg = 0;
> > +	int total_commits = -1;
> > +	int is_sm_git_dir = 0;
> > +	struct strbuf sm_git_dir_sb = STRBUF_INIT;
> > +
> > +	if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
> > +		if (S_ISGITLINK(p->mod_dst)) {
> > +			/*
> > +			 * NEEDSWORK: avoid using separate process with
> > +			 * the help of the function head_ref_submodule()
> 
> I don't quite understand this comment. There is no `head_ref_submodule()`
> function.
> 
> > +			 */
> > +			struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> > +			struct strbuf sb_rev_parse = STRBUF_INIT;
> > +
> > +			cp_rev_parse.git_cmd = 1;
> > +			cp_rev_parse.no_stderr = 1;
> > +			cp_rev_parse.dir = p->sm_path;
> > +			prepare_submodule_repo_env(&cp_rev_parse.env_array);
> > +
> > +			argv_array_pushl(&cp_rev_parse.args, "rev-parse",
> > +					 "HEAD", NULL);
> > +			if (!capture_command(&cp_rev_parse, &sb_rev_parse, 0)) {
> > +				strbuf_strip_suffix(&sb_rev_parse, "\n");
> > +				get_oid_hex(sb_rev_parse.buf, &p->oid_dst);
> > +			}
> > +			strbuf_release(&sb_rev_parse);
> > +		} else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
> > +			struct child_process cp_hash_object = CHILD_PROCESS_INIT;
> > +			struct strbuf sb_hash_object = STRBUF_INIT;
> > +
> > +			cp_hash_object.git_cmd = 1;
> > +			argv_array_pushl(&cp_hash_object.args, "hash-object",
> > +					 p->sm_path, NULL);
> > +			if (!capture_command(&cp_hash_object,
> > +					     &sb_hash_object, 0)) {
> > +				strbuf_strip_suffix(&sb_hash_object, "\n");
> > +				get_oid_hex(sb_hash_object.buf, &p->oid_dst);
> > +			}
> > +			strbuf_release(&sb_hash_object);
> 
> It would probably be shorter, less error-prone, and quicker to use
> `index_fd()` directly.
>
> BTW I am not quite sure that this code does the correct thing in case of a
> symlink: it hashes the contents of the symlink target (if it is a file,
> otherwise it errors out). But that is hardly an issue introduced by the
> conversion, that's just copied from `git-submodule.sh`.
> 
> > +		} else {
> > +			if (p->mod_dst)
> > +				die(_("unexpected mode %d\n"), p->mod_dst);
> 
> Hmm. This does not match what the shell script version does:
> 
>                         *)
>                                 # unexpected type
>                                 eval_gettextln "unexpected mode \$mod_dst" >&2
>                                 continue ;;
> 
> I think we should also just write the message to `stderr` and continue,
> not `die()`.
> 
> In addition to that, I am missing the C code for this case:
> 
>                         000000)
>                                 ;; # removed
> 
> It is quite possible that our test suite does not cover this case (or did
> the test suite fail for you?). If that is indeed the case, it would be
> really good to add a test case as part of this patch series, to gain
> confidence in the correctness of the conversion.

The tests passed for me actually. Whether this is covered by the test
cases, I am not sure. I will have to check it.

> > +		}
> > +	}
> > +
> > +	strbuf_addstr(&sm_git_dir_sb, p->sm_path);
> 
> I have to admit that I am not loving the name `sm_git_dir_sb`. Why not
> `submodule_git_dir`? I guess you copied it from elsewhere in
> `submodule--helper.c`...
> 
> > +	if (is_nonbare_repository_dir(&sm_git_dir_sb))
> > +		is_sm_git_dir = 1;
> 
> So here, we verify whether there is a repository at `p->sm_path`. I don't
> see that in the shell script version:
> 
>                 missing_src=
>                 missing_dst=
> 
>                 test $mod_src = 160000 &&
>                 ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
>                 missing_src=t
> 
>                 test $mod_dst = 160000 &&
>                 ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
>                 missing_dst=t
> 
> Let's read a bit further.
> 
> > +
> > +	if (is_sm_git_dir && S_ISGITLINK(p->mod_src))
> > +		missing_src = verify_submodule_object_name(p->sm_path,
> > +							   oid_to_hex(&p->oid_src));
> 
> Ah, and `verify_submodule_object_name()` uses `p->sm_path` as working
> directory. But that's not what the shell script version did: it specified
> the `GIT_DIR` explicitly.
> 
> And by using the `prepare_submodule_repo_env()` function in
> `verify_submodule_object_name()`, we specify `GIT_DIR` implicitly, as I
> pointed out in my comment on that function.

Oh so you're saying that it will be better to call
'prepare_submodule_repo_env()' on some variable since we explicitly want to
store the path to GIT_DIR?

It would be of much help if you could explain this part just a little
more (for my own sake).

> So I think that `is_sm_git_dir` might be

I think you missed something here...

> > +
> > +	if (is_sm_git_dir && S_ISGITLINK(p->mod_dst))
> > +		missing_dst = verify_submodule_object_name(p->sm_path,
> > +							   oid_to_hex(&p->oid_dst));
> > +
> > +	displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
> > +
> > +	if (!missing_dst && !missing_src) {
> > +		if (is_sm_git_dir) {
> > +			struct child_process cp_rev_list = CHILD_PROCESS_INIT;
> > +			struct strbuf sb_rev_list = STRBUF_INIT;
> > +			char *range;
> > +
> > +			if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
> > +				range = xstrfmt("%s...%s", oid_to_hex(&p->oid_src),
> > +						oid_to_hex(&p->oid_dst));
> > +			else if (S_ISGITLINK(p->mod_src))
> > +				range = xstrdup(oid_to_hex(&p->oid_src));
> > +			else
> > +				range = xstrdup(oid_to_hex(&p->oid_dst));
> > +
> > +			cp_rev_list.git_cmd = 1;
> > +			cp_rev_list.dir = p->sm_path;
> > +			prepare_submodule_repo_env(&cp_rev_list.env_array);
> 
> Again, due to setting the working directory to `p->sm_path` and
> (implicitly, via `prepare_submodule_repo_env()`) `GIT_DIR` to `.git`, I do
> not think that we have to guard this block beind `is_sm_git_dir`.

> > +
> > +			argv_array_pushl(&cp_rev_list.args, "rev-list",
> > +					 "--first-parent", range, "--", NULL);
> 
> Since `argv_array_push()` duplicates the strings, anyway, we can totally
> avoid the need for the `range` variable:
> 
> 			if (IS_GITLINK(p->mod_src) && IS_GITLINK(p->mod_dst))
> 				argv_array_pushf(&cp_rev_list.args, "%s...%s",
> 						 oid_to_hex(&p->oid_src),
> 						 oid_to_hex(&p->oid_dst));
> 			else
> 				argv_array_push(&cp_rev_list.args, IS_GITLINK(p->mod_src) ?
> 						oid_to_hex(&p->oid_src) :
> 						oid_to_hex(&p->oid_dst));
> 
> > +			if (!capture_command(&cp_rev_list, &sb_rev_list, 0)) {
> > +				if (sb_rev_list.len)
> > +					total_commits = count_lines(sb_rev_list.buf,
> > +								    sb_rev_list.len);
> 
> That's actually not necessary. `git rev-list --count` will give you a nice
> number, no need to capture a potentially large amount of memory only to
> count the lines.
> 
> This may also make the patch obsolete that makes `count_lines()` public.

Therefore we eliminate count_lines() from here and instead do a 'git
rev-list --count'?

> > +				else
> > +					total_commits = 0;
> > +			}
> 
> > +
> > +			free(range);
> > +			strbuf_release(&sb_rev_list);
> > +		}
> > +	} else {
> > +		errmsg = 1;
> > +	}
> 
> I am missing the equivalent for these lines here:
> 
>                 t,)
>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
>                         ;;
>                 ,t)
>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
>                         ;;
>                 t,t)
>                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$ ha1_dst")"
>                         ;;

I will add them.

> I am not quite sure whether it is a good idea to leave it to the
> `print_submodule_summary()` function to generate the `errmsg`. I think I'd
> rather have it a `char *` than an `int`.

Would it be better to add these error messages in
'prepare_submodule_summary()'? If we have error messages as integers
then we will simply

> > +
> > +	print_submodule_summary(info, errmsg, total_commits,
> > +				missing_src, missing_dst,
> > +		      		displaypath, is_sm_git_dir, p);
> > +
> > +	free(displaypath);
> > +	strbuf_release(&sm_git_dir_sb);
> > +}
> > +
> > +static void prepare_submodule_summary(struct summary_cb *info,
> > +				      struct module_cb_list *list)
> > +{
> > +	int i;
> > +	for (i = 0; i < list->nr; i++) {
> > +		struct module_cb *p = list->entries[i];
> > +		struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> > +
> > +		if (p->status == 'D' || p->status == 'T') {
> > +			generate_submodule_summary(info, p);
> > +			continue;
> > +		}
> > +
> > +		if (info->for_status) {
> > +			char *config_key;
> 
> Since the `config_key` is only used within the `if()` block it would be
> better to declare it within that block.
> 
> > +			const char *ignore_config = "none";
> 
> Since the only value we ever care about is "all", how about turning this
> into an `int`, setting it to `0` here, and later assigning it to
> `!strcmp(value, "all")` and `!strcmp(sub->ignore, "all")`, respectively?

Alright will do!

> I mean, I get it. Unix shell scripts are all about passing around text.
> And it is much easier to just translate that to C faithfully. But that
> does not make it good C code. C has data types, and proper C code makes
> use of that.
> 
> > +			const char *value;
> 
> If you want to save on lines, you can cuddle this together with other
> declarations of the same type. Even so, it could be scoped more narrowly.
> 
> > +			const struct submodule *sub = submodule_from_path(the_repository,
> > +									  &null_oid,
> > +									  p->sm_path);
> > +
> > +			if (sub && p->status != 'A') {
> 
> Good. The shell script version _always_ retrieved the `.ignore` config
> value, even if the `status` is `A`. Your version is much better.
> 
> But why bother calling `submodule_from_path()` if the status is `A`?

What exactly does a status of 'A' or 'T' mean? I mean I know what we are
doing but what exactly do these translate into?

> I could actually see the `const struct submodule *sub;` declaration be
> pulled out of this scope, and combining the `if (info->for_status &&
> p->status != 'A'), and the moving the assignment of `sub` into the `else
> if ((sub = submodule_from_path(r, &null_oid, p->sm_path)) &&
> sub->ignore)`.
> 
> That would save us one entire indentation level.

That seems a good approach! I will try this out.

> > +				config_key = xstrfmt("submodule.%s.ignore",
> > +						     sub->name);
> > +				if (!git_config_get_string_const(config_key, &value))
> > +					ignore_config = value;
> > +				else if (sub->ignore)
> > +					ignore_config = sub->ignore;
> > +
> > +				free(config_key);
> > +				if (!strcmp(ignore_config, "all"))
> > +					continue;
> > +			}
> > +		}
> > +
> > +		/* Also show added or modified modules which are checked out */
> > +		cp_rev_parse.dir = p->sm_path;
> > +		cp_rev_parse.git_cmd = 1;
> > +		cp_rev_parse.no_stderr = 1;
> > +		cp_rev_parse.no_stdout = 1;
> > +
> > +		argv_array_pushl(&cp_rev_parse.args, "rev-parse",
> > +				 "--git-dir", NULL);
> > +
> > +		if (!run_command(&cp_rev_parse))
> 
> I wonder whether we really need to waste an entire spawned process on
> figuring out whether `p->sm_path` refers to an active repository. Wouldn't
> `is_submodule_active(r, p->sm_path)` fulfill the same purpose?

Yep! This is correct. I will change.

> > +			generate_submodule_summary(info, p);
> > +	}
> > +}
> > +
> > +static void submodule_summary_callback(struct diff_queue_struct *q,
> > +				       struct diff_options *options,
> > +				       void *data)
> > +{
> > +	int i;
> > +	struct module_cb_list *list = data;
> > +	for (i = 0; i < q->nr; i++) {
> > +		struct diff_filepair *p = q->queue[i];
> > +		struct module_cb *temp;
> > +
> > +		if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
> > +			continue;
> > +		temp = (struct module_cb*)malloc(sizeof(struct module_cb));
> > +		temp->mod_src = p->one->mode;
> > +		temp->mod_dst = p->two->mode;
> > +		temp->oid_src = p->one->oid;
> > +		temp->oid_dst = p->two->oid;
> > +		temp->status = p->status;
> > +		temp->sm_path = xstrdup(p->one->path);
> > +
> > +		ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
> > +		list->entries[list->nr++] = temp;
> > +	}
> > +}
> > +
> > +static const char *get_diff_cmd(enum diff_cmd diff_cmd)
> > +{
> > +	switch (diff_cmd) {
> > +	case DIFF_INDEX: return "diff-index";
> > +	case DIFF_FILES: return "diff-files";
> > +	default: BUG("bad diff_cmd value %d", diff_cmd);
> > +	}
> > +}
> > +
> > +static int compute_summary_module_list(char *head,
> > +				         struct summary_cb *info,
> > +				         enum diff_cmd diff_cmd)
> > +{
> > +	struct argv_array diff_args = ARGV_ARRAY_INIT;
> > +	struct rev_info rev;
> > +	struct module_cb_list list = MODULE_CB_LIST_INIT;
> > +
> > +	argv_array_push(&diff_args, get_diff_cmd(diff_cmd));
> > +	if (info->cached)
> > +		argv_array_push(&diff_args, "--cached");
> > +	argv_array_pushl(&diff_args, "--ignore-submodules=dirty", "--raw",
> > +			 NULL);
> > +	if (head)
> > +		argv_array_push(&diff_args, head);
> > +	argv_array_push(&diff_args, "--");
> > +	if (info->argc)
> > +		argv_array_pushv(&diff_args, info->argv);
> > +
> > +	git_config(git_diff_basic_config, NULL);
> > +	init_revisions(&rev, info->prefix);
> > +	rev.abbrev = 0;
> > +	precompose_argv(diff_args.argc, diff_args.argv);
> > +
> > +	diff_args.argc = setup_revisions(diff_args.argc, diff_args.argv,
> > +					 &rev, NULL);
> > +	rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
> > +	rev.diffopt.format_callback = submodule_summary_callback;
> > +	rev.diffopt.format_callback_data = &list;
> > +
> > +	if (!info->cached) {
> > +		if (diff_cmd ==  DIFF_INDEX)
> 
> Please substitute the double-space by a single one.

Will do!

> > +			setup_work_tree();
> > +		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
> > +			perror("read_cache_preload");
> > +			return -1;
> > +		}
> > +	} else if (read_cache() < 0) {
> > +		perror("read_cache");
> > +		return -1;
> > +	}
> > +
> > +	if (diff_cmd == DIFF_INDEX)
> > +		run_diff_index(&rev, info->cached);
> > +	else
> > +		run_diff_files(&rev, 0);
> > +	prepare_submodule_summary(info, &list);
> > +	return 0;
> > +}
> > +
> > +static int module_summary(int argc, const char **argv, const char *prefix)
> > +{
> > +	struct summary_cb info = SUMMARY_CB_INIT;
> > +	int cached = 0;
> > +	int for_status = 0;
> > +	int quiet = 0;
> > +	int files = 0;
> > +	int summary_limit = -1;
> > +	struct child_process cp_rev = CHILD_PROCESS_INIT;
> > +	struct strbuf sb = STRBUF_INIT;
> > +	enum diff_cmd diff_cmd = DIFF_INDEX;
> > +	int ret;
> > +
> > +	struct option module_summary_options[] = {
> > +		OPT__QUIET(&quiet, N_("Suppress output of summarising submodules")),
> > +		OPT_BOOL(0, "cached", &cached,
> > +			 N_("Use the commit stored in the index instead of the submodule HEAD")),
> > +		OPT_BOOL(0, "files", &files,
> > +			 N_("To compare the commit in the index with that in the submodule HEAD")),
> > +		OPT_BOOL(0, "for-status", &for_status,
> > +			 N_("Skip submodules with 'ignore_config' value set to 'all'")),
> > +		OPT_INTEGER('n', "summary-limit", &summary_limit,
> > +			     N_("Limit the summary size")),
> > +		OPT_END()
> > +	};
> > +
> > +	const char *const git_submodule_helper_usage[] = {
> > +		N_("git submodule--helper summary [<options>] [commit] [--] [<path>]"),
> > +		NULL
> > +	};
> > +
> > +	argc = parse_options(argc, argv, prefix, module_summary_options,
> > +			     git_submodule_helper_usage, 0);
> > +
> > +	if (!summary_limit)
> > +		return 0;
> > +
> > +	cp_rev.git_cmd = 1;
> > +	argv_array_pushl(&cp_rev.args, "rev-parse", "-q", "--verify",
> > +			 argc ? argv[0] : "HEAD", NULL);
> 
> Oy. Why not simply call `get_oid()`? No need to spawn a new process.

Then everytime we need 'rev-parse', we simply call 'get_oid()'? That
will save us a ton of processes?

But I think we do need to capture the output of 'git rev-parse --verify
....' so I think it will backfire to use 'get_oid()' or am I just being
too dumb and not catching on something?

> > +
> > +	if (!capture_command(&cp_rev, &sb, 0)) {
> > +		strbuf_strip_suffix(&sb, "\n");
> > +		if (argc) {
> > +			argv++;
> > +			argc--;
> > +		}
> > +	} else if (!argc || !strcmp(argv[0], "HEAD")) {
> > +		/* before the first commit: compare with an empty tree */
> > +		struct stat st;
> > +		struct object_id oid;
> > +		if (fstat(0, &st) < 0 || index_fd(&the_index, &oid, 0, &st, 2,
> > +						  prefix, 3))
> > +			die("Unable to add %s to database", oid.hash);
> 
> Umm. The original reads:
> 
>                 # before the first commit: compare with an empty tree
>                 head=$(git hash-object -w -t tree --stdin </dev/null)
> 
> It does not actually read from `stdin`. It reads from `/dev/null`,
> redirected to the input. And what it _actually_ does is to generate the
> OID of the empty tree.
> 
> But we already _have_ the OID of the empty tree! It's
> `the_hash_algo->empty_tree`.

I did not know this 'the_hash_algo'. I will use it. Thanks! :)

> I hope that this is covered by the test suite. Please check that. The test
> would succeed with your version, but only because tests are run with
> `stdin` redirected from `/dev/null` by default.

I guess yes. My work passed because the tests are written this way.

> > +		strbuf_addstr(&sb, oid_to_hex(&oid));
> > +		if (argc) {
> > +			argv++;
> > +			argc--;
> > +		}
> > +	} else {
> > +		strbuf_addstr(&sb, "HEAD");
> > +	}
> 
> The conversion to C would make for a fine excuse to simplify the logic.

This was kind of like the 'shift' in shell. What equivalent do you
suggest?

> > +	if (files) {
> > +		if (cached)
> > +			die(_("--cached and --files are mutually exclusive"));
> > +		diff_cmd = DIFF_FILES;
> > +	}
> > +
> > +	info.argc = argc;
> > +	info.argv = argv;
> > +	info.prefix = prefix;
> > +	info.cached = !!cached;
> > +	info.for_status = !!for_status;
> > +	info.quiet = quiet;
> > +	info.files = files;
> > +	info.summary_limit = summary_limit;
> > +
> > +	ret = compute_summary_module_list((diff_cmd == DIFF_FILES) ? NULL : sb.buf,
> > +					   &info, diff_cmd);
> 
> It would be better to pass the OID as `struct object_id *`, not as string.

Will do!

> Other than that, this patch nicely follows previous conversions from Unix
> shell scripts to C.
> 
> Well done,
> Johannes

Thank you! It was a highly detailed review! I am still learning tons of
stuff about Git's code and such a review does help a lot! :)

^ permalink raw reply	[relevance 2%]

* Re: [PATCH 4/4] submodule: port submodule subcommand 'summary' from shell to C
  2020-07-02 19:24 15% ` [PATCH 4/4] submodule: port submodule subcommand 'summary' from shell " Shourya Shukla
@ 2020-07-03 20:46  4%   ` Johannes Schindelin
  2020-07-05 17:34  2%     ` Shourya Shukla
  0 siblings, 1 reply; 200+ results
From: Johannes Schindelin @ 2020-07-03 20:46 UTC (permalink / raw)
  To: Shourya Shukla
  Cc: git, christian.couder, gitster, liu.denton, kaartic.sivaraam,
	pc44800, stefanbeller, pclouds

Hi Shourya,

[exchanging Stefan Beller's dysfunct @google address for their private
one; I encourage you to do the same in the next iteration, probably
by editing the `Mentored-by:` line.]

On Fri, 3 Jul 2020, Shourya Shukla wrote:

> From: Prathamesh Chavan <pc44800@gmail.com>
>
> The submodule subcommand 'summary' is ported in the process of
> making git-submodule a builtin. The function cmd_summary() from
> git-submodule.sh is ported to functions module_summary(),
> compute_summary_module_list(), prepare_submodule_summary() and
> generate_submodule_summary(), print_submodule_summary().
>
> The first function module_summary() parses the options of submodule
> subcommand and also acts as the front-end of this subcommand.
> After parsing them, it calls the compute_summary_module_list()

Missing full-stop, and probably the sentence also wanted to say "function"
at the end.

> The functions compute_summary_module_list() runs the diff_cmd,
> and generates the modules list, as required by the subcommand.
> The generation of this module list is done by the using the

s/the using/using/

> callback function submodule_summary_callback(), and stored in the
> structure module_cb.

This explains nicely what the patch does. But the commit message should
not really repeat what can be readily deduced from the patch; It should
focus on the motivation and on interesting background information that is
_not_ readily deduced from the patch.

For example, I see that `$diff_cmd` is called twice in the shell script
version, once to "get modified modules cared by user" and then _again_,
with that list of modified modules.

I would have liked to see a reasoning in the commit message that explains
why this has to be so in the C version. I get why it is complicated in a
shell script (which lacks proper objects, after all), but I would have
expected the C version to be able to accumulate the information with a
single pass.

(Before writing the following paragraph, I actually reviewed the patch
from bottom to top, in the caller->callee direction.)

Ah. I see that this indeed is the case: there is only one pass in the C
version. That's a useful piece of metadata for the commit message, I
think, much more useful than describing the call tree of the functions.

Another thing worth mentioning in the commit message is that we use the
combination of setting a child_process' working directory to the submodule
path and then calling `prepare_submodule_repo_env()` which also sets
`GIT_DIR` to `.git`, so that we can be certain that those spawned
processes will not access the superproject's ODB by mistake.

When reading my suggestions, please keep in mind that I reviewed the
functions in caller->callee order, i.e. I started at the end of the patch
and then worked my way up.

All in all, I like the function structure, but I think there is still a
bit room for improvement in a v2.

> Once the module list is generated, prepare_submodule_summary()
> further goes through the list and filters the list, for
> eventually calling the generate_submodule_summary() function.
>
> The function generate_submodule_summary() takes care of generating
> the summary for each submodule and then calls the function
> print_submodule_summary() for printing it.
>
> Mentored-by: Christian Couder <christian.couder@gmail.com>
> Mentored-by: Stefan Beller <sbeller@google.com>
> Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
> Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
> Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
> ---
>  builtin/submodule--helper.c | 451 ++++++++++++++++++++++++++++++++++++
>  git-submodule.sh            | 186 +--------------
>  2 files changed, 452 insertions(+), 185 deletions(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index eea3932c40..1dbdb934f1 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -927,6 +927,456 @@ static int module_name(int argc, const char **argv, const char *prefix)
>  	return 0;
>  }
>
> +struct module_cb {
> +	unsigned int mod_src;
> +	unsigned int mod_dst;
> +	struct object_id oid_src;
> +	struct object_id oid_dst;
> +	char status;
> +	const char *sm_path;
> +};
> +#define MODULE_CB_INIT { 0, 0, NULL, NULL, '\0', NULL }
> +
> +struct module_cb_list {
> +	struct module_cb **entries;
> +	int alloc, nr;
> +};
> +#define MODULE_CB_LIST_INIT { NULL, 0, 0 }
> +
> +struct summary_cb {
> +	int argc;
> +	const char **argv;
> +	const char *prefix;
> +	unsigned int cached: 1;
> +	unsigned int for_status: 1;
> +	unsigned int quiet: 1;
> +	unsigned int files: 1;
> +	int summary_limit;
> +};
> +#define SUMMARY_CB_INIT { 0, NULL, NULL, 0, 0, 0, 0, 0 }
> +
> +enum diff_cmd {
> +	DIFF_INDEX,
> +	DIFF_FILES
> +};
> +
> +static int verify_submodule_object_name(const char *sm_path,
> +					  const char *sha1)
> +{
> +	struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> +
> +	cp_rev_parse.git_cmd = 1;
> +	cp_rev_parse.no_stdout = 1;
> +	cp_rev_parse.dir = sm_path;

So here we specify `sm_path` as current working directory.

> +	prepare_submodule_repo_env(&cp_rev_parse.env_array);

And this implicitly sets `GIT_DIR=.git`. Good.

> +	argv_array_pushl(&cp_rev_parse.args, "rev-parse", "-q",
> +			 "--verify", NULL);
> +	argv_array_pushf(&cp_rev_parse.args, "%s^0", sha1);

After this, we should also append `--` to make sure that we're not parsing
this as a file name.

Two comments about naming: `sha1` is pretty misleading here, as we do not
require it to be a SHA-1 (especially in the future in which we switch to
SHA-256). Besides, what we're really asking for (via that `^0` suffix) is
a committish. Therefore, I would propose to use `committish` both in the
parameter name as well as the function name.

> +
> +	if (run_command(&cp_rev_parse))
> +		return 1;
> +
> +	return 0;
> +}
> +
> +static void print_submodule_summary(struct summary_cb *info, int errmsg,
> +				      int total_commits, int missing_src,
> +				      int missing_dst, const char *displaypath,
> +				      int is_sm_git_dir, struct module_cb *p)
> +{
> +	if (p->status == 'T') {
> +		if (S_ISGITLINK(p->mod_dst))
> +			printf(_("* %s %s(blob)->%s(submodule)"),
> +				 displaypath, find_unique_abbrev(&p->oid_src, 7),

The shell script version does this:

                sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
                        echo $sha1_src | cut -c1-7)

That is not quite the same, as it looks for the abbreviation _in the
submodule_, not in the current project. So I think `find_unique_abbrev()`
is not correct here.

The funny thing is that we _already_ will have called `git rev-parse
--verify` for both `p->oid_src` and `p->oid_dst` in the submodule, in the
caller of this function! And while we throw away the result, and while we
do not pass `--short`, there is no reason why we shouldn't be able to do
precisely that.

> +				 find_unique_abbrev(&p->oid_dst, 7));
> +		else
> +			printf(_("* %s %s(submodule)->%s(blob)"),
> +				 displaypath, find_unique_abbrev(&p->oid_src, 7),
> +				 find_unique_abbrev(&p->oid_dst, 7));
> +	} else {
> +		printf("* %s %s...%s",
> +			displaypath, find_unique_abbrev(&p->oid_src, 7),
> +			find_unique_abbrev(&p->oid_dst, 7));
> +	}
> +
> +	if (total_commits < 0)
> +		printf(":\n");
> +	else
> +		printf(" (%d):\n", total_commits);
> +
> +	if (errmsg) {
> +		/*
> +		 * Don't give error msg for modification whose dst is not
> +		 * submodule, i.e. deleted or changed to blob
> +		 */
> +		if (S_ISGITLINK(p->mod_src)) {
> +			if (missing_src && missing_dst) {
> +				printf(_("  Warn: %s doesn't contain commits %s and %s\n"),
> +				       displaypath, oid_to_hex(&p->oid_src),
> +				       oid_to_hex(&p->oid_dst));
> +			} else if (missing_src) {
> +				printf(_("  Warn: %s doesn't contain commit %s\n"),
> +				       displaypath, oid_to_hex(&p->oid_src));
> +			} else {
> +				printf(_("  Warn: %s doesn't contain commit %s\n"),
> +				       displaypath, oid_to_hex(&p->oid_dst));
> +			}
> +		}
> +	} else if (is_sm_git_dir) {
> +		struct child_process cp_log = CHILD_PROCESS_INIT;
> +
> +		cp_log.git_cmd = 1;
> +		cp_log.dir = p->sm_path;
> +		prepare_submodule_repo_env(&cp_log.env_array);

Since the working directory is set to the top-level directory of the
submodule, and since `prepare_submodule_repo_env()` sets `GIT_DIR` to
`.git`, I think that the `is_sm_git_dir` condition is unnecessary. In
fact, the entire `is_sm_git_dir` parameter (and local variable in the
caller, see more on that below) can go away.

> +		argv_array_pushl(&cp_log.args, "log", NULL);
> +
> +		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
> +			if (info->summary_limit > 0)
> +				argv_array_pushf(&cp_log.args, "-%d",
> +						 info->summary_limit);
> +
> +			argv_array_pushl(&cp_log.args, "--pretty=  %m %s",
> +					 "--first-parent", NULL);
> +			argv_array_pushf(&cp_log.args, "%s...%s",
> +					 oid_to_hex(&p->oid_src),
> +					 oid_to_hex(&p->oid_dst));
> +		} else if (S_ISGITLINK(p->mod_dst)) {
> +			argv_array_pushl(&cp_log.args, "--pretty=  > %s",
> +					 "-1", oid_to_hex(&p->oid_dst), NULL);
> +		} else {
> +			argv_array_pushl(&cp_log.args, "--pretty=  < %s",
> +					 "-1", oid_to_hex(&p->oid_src), NULL);
> +		}
> +		run_command(&cp_log);
> +	}
> +	printf("\n");
> +}

It looks as if there is a whole lot of `oid_to_hex(&p->oid_src)` in that
function. Together with the realization that we need the abbreviated
version of that at least in one place, and the other realization that we
already call `rev-parse --verify` for both `oid_src` and `oid_dst` in the
caller of this function, it seems to suggest itself that we would actually
want to pass the `--short` option, too, and to capture the output, and
pass it down to `print_submodule_summary()` _instead of_ `missing_src` and
`missing_dst` (e.g. as `src_abbrev` and `dst_abbrev`).
> +
> +static void generate_submodule_summary(struct summary_cb *info,
> +				       struct module_cb *p)
> +{
> +	int missing_src = 0;
> +	int missing_dst = 0;
> +	char *displaypath;
> +	int errmsg = 0;
> +	int total_commits = -1;
> +	int is_sm_git_dir = 0;
> +	struct strbuf sm_git_dir_sb = STRBUF_INIT;
> +
> +	if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
> +		if (S_ISGITLINK(p->mod_dst)) {
> +			/*
> +			 * NEEDSWORK: avoid using separate process with
> +			 * the help of the function head_ref_submodule()

I don't quite understand this comment. There is no `head_ref_submodule()`
function.

> +			 */
> +			struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> +			struct strbuf sb_rev_parse = STRBUF_INIT;
> +
> +			cp_rev_parse.git_cmd = 1;
> +			cp_rev_parse.no_stderr = 1;
> +			cp_rev_parse.dir = p->sm_path;
> +			prepare_submodule_repo_env(&cp_rev_parse.env_array);
> +
> +			argv_array_pushl(&cp_rev_parse.args, "rev-parse",
> +					 "HEAD", NULL);
> +			if (!capture_command(&cp_rev_parse, &sb_rev_parse, 0)) {
> +				strbuf_strip_suffix(&sb_rev_parse, "\n");
> +				get_oid_hex(sb_rev_parse.buf, &p->oid_dst);
> +			}
> +			strbuf_release(&sb_rev_parse);
> +		} else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
> +			struct child_process cp_hash_object = CHILD_PROCESS_INIT;
> +			struct strbuf sb_hash_object = STRBUF_INIT;
> +
> +			cp_hash_object.git_cmd = 1;
> +			argv_array_pushl(&cp_hash_object.args, "hash-object",
> +					 p->sm_path, NULL);
> +			if (!capture_command(&cp_hash_object,
> +					     &sb_hash_object, 0)) {
> +				strbuf_strip_suffix(&sb_hash_object, "\n");
> +				get_oid_hex(sb_hash_object.buf, &p->oid_dst);
> +			}
> +			strbuf_release(&sb_hash_object);

It would probably be shorter, less error-prone, and quicker to use
`index_fd()` directly.

BTW I am not quite sure that this code does the correct thing in case of a
symlink: it hashes the contents of the symlink target (if it is a file,
otherwise it errors out). But that is hardly an issue introduced by the
conversion, that's just copied from `git-submodule.sh`.

> +		} else {
> +			if (p->mod_dst)
> +				die(_("unexpected mode %d\n"), p->mod_dst);

Hmm. This does not match what the shell script version does:

                        *)
                                # unexpected type
                                eval_gettextln "unexpected mode \$mod_dst" >&2
                                continue ;;

I think we should also just write the message to `stderr` and continue,
not `die()`.

In addition to that, I am missing the C code for this case:

                        000000)
                                ;; # removed

It is quite possible that our test suite does not cover this case (or did
the test suite fail for you?). If that is indeed the case, it would be
really good to add a test case as part of this patch series, to gain
confidence in the correctness of the conversion.

> +		}
> +	}
> +
> +	strbuf_addstr(&sm_git_dir_sb, p->sm_path);

I have to admit that I am not loving the name `sm_git_dir_sb`. Why not
`submodule_git_dir`? I guess you copied it from elsewhere in
`submodule--helper.c`...

> +	if (is_nonbare_repository_dir(&sm_git_dir_sb))
> +		is_sm_git_dir = 1;

So here, we verify whether there is a repository at `p->sm_path`. I don't
see that in the shell script version:

                missing_src=
                missing_dst=

                test $mod_src = 160000 &&
                ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
                missing_src=t

                test $mod_dst = 160000 &&
                ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
                missing_dst=t

Let's read a bit further.

> +
> +	if (is_sm_git_dir && S_ISGITLINK(p->mod_src))
> +		missing_src = verify_submodule_object_name(p->sm_path,
> +							   oid_to_hex(&p->oid_src));

Ah, and `verify_submodule_object_name()` uses `p->sm_path` as working
directory. But that's not what the shell script version did: it specified
the `GIT_DIR` explicitly.

And by using the `prepare_submodule_repo_env()` function in
`verify_submodule_object_name()`, we specify `GIT_DIR` implicitly, as I
pointed out in my comment on that function.

So I think that `is_sm_git_dir` might be

> +
> +	if (is_sm_git_dir && S_ISGITLINK(p->mod_dst))
> +		missing_dst = verify_submodule_object_name(p->sm_path,
> +							   oid_to_hex(&p->oid_dst));
> +
> +	displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
> +
> +	if (!missing_dst && !missing_src) {
> +		if (is_sm_git_dir) {
> +			struct child_process cp_rev_list = CHILD_PROCESS_INIT;
> +			struct strbuf sb_rev_list = STRBUF_INIT;
> +			char *range;
> +
> +			if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
> +				range = xstrfmt("%s...%s", oid_to_hex(&p->oid_src),
> +						oid_to_hex(&p->oid_dst));
> +			else if (S_ISGITLINK(p->mod_src))
> +				range = xstrdup(oid_to_hex(&p->oid_src));
> +			else
> +				range = xstrdup(oid_to_hex(&p->oid_dst));
> +
> +			cp_rev_list.git_cmd = 1;
> +			cp_rev_list.dir = p->sm_path;
> +			prepare_submodule_repo_env(&cp_rev_list.env_array);

Again, due to setting the working directory to `p->sm_path` and
(implicitly, via `prepare_submodule_repo_env()`) `GIT_DIR` to `.git`, I do
not think that we have to guard this block beind `is_sm_git_dir`.

> +
> +			argv_array_pushl(&cp_rev_list.args, "rev-list",
> +					 "--first-parent", range, "--", NULL);

Since `argv_array_push()` duplicates the strings, anyway, we can totally
avoid the need for the `range` variable:

			if (IS_GITLINK(p->mod_src) && IS_GITLINK(p->mod_dst))
				argv_array_pushf(&cp_rev_list.args, "%s...%s",
						 oid_to_hex(&p->oid_src),
						 oid_to_hex(&p->oid_dst));
			else
				argv_array_push(&cp_rev_list.args, IS_GITLINK(p->mod_src) ?
						oid_to_hex(&p->oid_src) :
						oid_to_hex(&p->oid_dst));

> +			if (!capture_command(&cp_rev_list, &sb_rev_list, 0)) {
> +				if (sb_rev_list.len)
> +					total_commits = count_lines(sb_rev_list.buf,
> +								    sb_rev_list.len);

That's actually not necessary. `git rev-list --count` will give you a nice
number, no need to capture a potentially large amount of memory only to
count the lines.

This may also make the patch obsolete that makes `count_lines()` public.

> +				else
> +					total_commits = 0;
> +			}

> +
> +			free(range);
> +			strbuf_release(&sb_rev_list);
> +		}
> +	} else {
> +		errmsg = 1;
> +	}

I am missing the equivalent for these lines here:

                t,)
                        errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
                        ;;
                ,t)
                        errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
                        ;;
                t,t)
                        errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$ ha1_dst")"
                        ;;

I am not quite sure whether it is a good idea to leave it to the
`print_submodule_summary()` function to generate the `errmsg`. I think I'd
rather have it a `char *` than an `int`.

> +
> +	print_submodule_summary(info, errmsg, total_commits,
> +				missing_src, missing_dst,
> +		      		displaypath, is_sm_git_dir, p);
> +
> +	free(displaypath);
> +	strbuf_release(&sm_git_dir_sb);
> +}
> +
> +static void prepare_submodule_summary(struct summary_cb *info,
> +				      struct module_cb_list *list)
> +{
> +	int i;
> +	for (i = 0; i < list->nr; i++) {
> +		struct module_cb *p = list->entries[i];
> +		struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
> +
> +		if (p->status == 'D' || p->status == 'T') {
> +			generate_submodule_summary(info, p);
> +			continue;
> +		}
> +
> +		if (info->for_status) {
> +			char *config_key;

Since the `config_key` is only used within the `if()` block it would be
better to declare it within that block.

> +			const char *ignore_config = "none";

Since the only value we ever care about is "all", how about turning this
into an `int`, setting it to `0` here, and later assigning it to
`!strcmp(value, "all")` and `!strcmp(sub->ignore, "all")`, respectively?

I mean, I get it. Unix shell scripts are all about passing around text.
And it is much easier to just translate that to C faithfully. But that
does not make it good C code. C has data types, and proper C code makes
use of that.

> +			const char *value;

If you want to save on lines, you can cuddle this together with other
declarations of the same type. Even so, it could be scoped more narrowly.

> +			const struct submodule *sub = submodule_from_path(the_repository,
> +									  &null_oid,
> +									  p->sm_path);
> +
> +			if (sub && p->status != 'A') {

Good. The shell script version _always_ retrieved the `.ignore` config
value, even if the `status` is `A`. Your version is much better.

But why bother calling `submodule_from_path()` if the status is `A`?

I could actually see the `const struct submodule *sub;` declaration be
pulled out of this scope, and combining the `if (info->for_status &&
p->status != 'A'), and the moving the assignment of `sub` into the `else
if ((sub = submodule_from_path(r, &null_oid, p->sm_path)) &&
sub->ignore)`.

That would save us one entire indentation level.

> +				config_key = xstrfmt("submodule.%s.ignore",
> +						     sub->name);
> +				if (!git_config_get_string_const(config_key, &value))
> +					ignore_config = value;
> +				else if (sub->ignore)
> +					ignore_config = sub->ignore;
> +
> +				free(config_key);
> +				if (!strcmp(ignore_config, "all"))
> +					continue;
> +			}
> +		}
> +
> +		/* Also show added or modified modules which are checked out */
> +		cp_rev_parse.dir = p->sm_path;
> +		cp_rev_parse.git_cmd = 1;
> +		cp_rev_parse.no_stderr = 1;
> +		cp_rev_parse.no_stdout = 1;
> +
> +		argv_array_pushl(&cp_rev_parse.args, "rev-parse",
> +				 "--git-dir", NULL);
> +
> +		if (!run_command(&cp_rev_parse))

I wonder whether we really need to waste an entire spawned process on
figuring out whether `p->sm_path` refers to an active repository. Wouldn't
`is_submodule_active(r, p->sm_path)` fulfill the same purpose?

> +			generate_submodule_summary(info, p);
> +	}
> +}
> +
> +static void submodule_summary_callback(struct diff_queue_struct *q,
> +				       struct diff_options *options,
> +				       void *data)
> +{
> +	int i;
> +	struct module_cb_list *list = data;
> +	for (i = 0; i < q->nr; i++) {
> +		struct diff_filepair *p = q->queue[i];
> +		struct module_cb *temp;
> +
> +		if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
> +			continue;
> +		temp = (struct module_cb*)malloc(sizeof(struct module_cb));
> +		temp->mod_src = p->one->mode;
> +		temp->mod_dst = p->two->mode;
> +		temp->oid_src = p->one->oid;
> +		temp->oid_dst = p->two->oid;
> +		temp->status = p->status;
> +		temp->sm_path = xstrdup(p->one->path);
> +
> +		ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
> +		list->entries[list->nr++] = temp;
> +	}
> +}
> +
> +static const char *get_diff_cmd(enum diff_cmd diff_cmd)
> +{
> +	switch (diff_cmd) {
> +	case DIFF_INDEX: return "diff-index";
> +	case DIFF_FILES: return "diff-files";
> +	default: BUG("bad diff_cmd value %d", diff_cmd);
> +	}
> +}
> +
> +static int compute_summary_module_list(char *head,
> +				         struct summary_cb *info,
> +				         enum diff_cmd diff_cmd)
> +{
> +	struct argv_array diff_args = ARGV_ARRAY_INIT;
> +	struct rev_info rev;
> +	struct module_cb_list list = MODULE_CB_LIST_INIT;
> +
> +	argv_array_push(&diff_args, get_diff_cmd(diff_cmd));
> +	if (info->cached)
> +		argv_array_push(&diff_args, "--cached");
> +	argv_array_pushl(&diff_args, "--ignore-submodules=dirty", "--raw",
> +			 NULL);
> +	if (head)
> +		argv_array_push(&diff_args, head);
> +	argv_array_push(&diff_args, "--");
> +	if (info->argc)
> +		argv_array_pushv(&diff_args, info->argv);
> +
> +	git_config(git_diff_basic_config, NULL);
> +	init_revisions(&rev, info->prefix);
> +	rev.abbrev = 0;
> +	precompose_argv(diff_args.argc, diff_args.argv);
> +
> +	diff_args.argc = setup_revisions(diff_args.argc, diff_args.argv,
> +					 &rev, NULL);
> +	rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
> +	rev.diffopt.format_callback = submodule_summary_callback;
> +	rev.diffopt.format_callback_data = &list;
> +
> +	if (!info->cached) {
> +		if (diff_cmd ==  DIFF_INDEX)

Please substitute the double-space by a single one.

> +			setup_work_tree();
> +		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
> +			perror("read_cache_preload");
> +			return -1;
> +		}
> +	} else if (read_cache() < 0) {
> +		perror("read_cache");
> +		return -1;
> +	}
> +
> +	if (diff_cmd == DIFF_INDEX)
> +		run_diff_index(&rev, info->cached);
> +	else
> +		run_diff_files(&rev, 0);
> +	prepare_submodule_summary(info, &list);
> +	return 0;
> +}
> +
> +static int module_summary(int argc, const char **argv, const char *prefix)
> +{
> +	struct summary_cb info = SUMMARY_CB_INIT;
> +	int cached = 0;
> +	int for_status = 0;
> +	int quiet = 0;
> +	int files = 0;
> +	int summary_limit = -1;
> +	struct child_process cp_rev = CHILD_PROCESS_INIT;
> +	struct strbuf sb = STRBUF_INIT;
> +	enum diff_cmd diff_cmd = DIFF_INDEX;
> +	int ret;
> +
> +	struct option module_summary_options[] = {
> +		OPT__QUIET(&quiet, N_("Suppress output of summarising submodules")),
> +		OPT_BOOL(0, "cached", &cached,
> +			 N_("Use the commit stored in the index instead of the submodule HEAD")),
> +		OPT_BOOL(0, "files", &files,
> +			 N_("To compare the commit in the index with that in the submodule HEAD")),
> +		OPT_BOOL(0, "for-status", &for_status,
> +			 N_("Skip submodules with 'ignore_config' value set to 'all'")),
> +		OPT_INTEGER('n', "summary-limit", &summary_limit,
> +			     N_("Limit the summary size")),
> +		OPT_END()
> +	};
> +
> +	const char *const git_submodule_helper_usage[] = {
> +		N_("git submodule--helper summary [<options>] [commit] [--] [<path>]"),
> +		NULL
> +	};
> +
> +	argc = parse_options(argc, argv, prefix, module_summary_options,
> +			     git_submodule_helper_usage, 0);
> +
> +	if (!summary_limit)
> +		return 0;
> +
> +	cp_rev.git_cmd = 1;
> +	argv_array_pushl(&cp_rev.args, "rev-parse", "-q", "--verify",
> +			 argc ? argv[0] : "HEAD", NULL);

Oy. Why not simply call `get_oid()`? No need to spawn a new process.

> +
> +	if (!capture_command(&cp_rev, &sb, 0)) {
> +		strbuf_strip_suffix(&sb, "\n");
> +		if (argc) {
> +			argv++;
> +			argc--;
> +		}
> +	} else if (!argc || !strcmp(argv[0], "HEAD")) {
> +		/* before the first commit: compare with an empty tree */
> +		struct stat st;
> +		struct object_id oid;
> +		if (fstat(0, &st) < 0 || index_fd(&the_index, &oid, 0, &st, 2,
> +						  prefix, 3))
> +			die("Unable to add %s to database", oid.hash);

Umm. The original reads:

                # before the first commit: compare with an empty tree
                head=$(git hash-object -w -t tree --stdin </dev/null)

It does not actually read from `stdin`. It reads from `/dev/null`,
redirected to the input. And what it _actually_ does is to generate the
OID of the empty tree.

But we already _have_ the OID of the empty tree! It's
`the_hash_algo->empty_tree`.

I hope that this is covered by the test suite. Please check that. The test
would succeed with your version, but only because tests are run with
`stdin` redirected from `/dev/null` by default.

> +		strbuf_addstr(&sb, oid_to_hex(&oid));
> +		if (argc) {
> +			argv++;
> +			argc--;
> +		}
> +	} else {
> +		strbuf_addstr(&sb, "HEAD");
> +	}

The conversion to C would make for a fine excuse to simplify the logic.

> +	if (files) {
> +		if (cached)
> +			die(_("--cached and --files are mutually exclusive"));
> +		diff_cmd = DIFF_FILES;
> +	}
> +
> +	info.argc = argc;
> +	info.argv = argv;
> +	info.prefix = prefix;
> +	info.cached = !!cached;
> +	info.for_status = !!for_status;
> +	info.quiet = quiet;
> +	info.files = files;
> +	info.summary_limit = summary_limit;
> +
> +	ret = compute_summary_module_list((diff_cmd == DIFF_FILES) ? NULL : sb.buf,
> +					   &info, diff_cmd);

It would be better to pass the OID as `struct object_id *`, not as string.

Other than that, this patch nicely follows previous conversions from Unix
shell scripts to C.

Well done,
Johannes

> +	strbuf_release(&sb);
> +	return ret;
> +}
> +
>  struct sync_cb {
>  	const char *prefix;
>  	unsigned int flags;
> @@ -2341,6 +2791,7 @@ static struct cmd_struct commands[] = {
>  	{"print-default-remote", print_default_remote, 0},
>  	{"sync", module_sync, SUPPORT_SUPER_PREFIX},
>  	{"deinit", module_deinit, 0},
> +	{"summary", module_summary, SUPPORT_SUPER_PREFIX},
>  	{"remote-branch", resolve_remote_submodule_branch, 0},
>  	{"push-check", push_check, 0},
>  	{"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 43eb6051d2..899b8a409a 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -59,31 +59,6 @@ die_if_unmatched ()
>  	fi
>  }
>
> -#
> -# Print a submodule configuration setting
> -#
> -# $1 = submodule name
> -# $2 = option name
> -# $3 = default value
> -#
> -# Checks in the usual git-config places first (for overrides),
> -# otherwise it falls back on .gitmodules.  This allows you to
> -# distribute project-wide defaults in .gitmodules, while still
> -# customizing individual repositories if necessary.  If the option is
> -# not in .gitmodules either, print a default value.
> -#
> -get_submodule_config () {
> -	name="$1"
> -	option="$2"
> -	default="$3"
> -	value=$(git config submodule."$name"."$option")
> -	if test -z "$value"
> -	then
> -		value=$(git submodule--helper config submodule."$name"."$option")
> -	fi
> -	printf '%s' "${value:-$default}"
> -}
> -
>  isnumber()
>  {
>  	n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
> @@ -831,166 +806,7 @@ cmd_summary() {
>  		shift
>  	done
>
> -	test $summary_limit = 0 && return
> -
> -	if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
> -	then
> -		head=$rev
> -		test $# = 0 || shift
> -	elif test -z "$1" || test "$1" = "HEAD"
> -	then
> -		# before the first commit: compare with an empty tree
> -		head=$(git hash-object -w -t tree --stdin </dev/null)
> -		test -z "$1" || shift
> -	else
> -		head="HEAD"
> -	fi
> -
> -	if [ -n "$files" ]
> -	then
> -		test -n "$cached" &&
> -		die "$(gettext "The --cached option cannot be used with the --files option")"
> -		diff_cmd=diff-files
> -		head=
> -	fi
> -
> -	cd_to_toplevel
> -	eval "set $(git rev-parse --sq --prefix "$wt_prefix" -- "$@")"
> -	# Get modified modules cared by user
> -	modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
> -		sane_egrep '^:([0-7]* )?160000' |
> -		while read -r mod_src mod_dst sha1_src sha1_dst status sm_path
> -		do
> -			# Always show modules deleted or type-changed (blob<->module)
> -			if test "$status" = D || test "$status" = T
> -			then
> -				printf '%s\n' "$sm_path"
> -				continue
> -			fi
> -			# Respect the ignore setting for --for-status.
> -			if test -n "$for_status"
> -			then
> -				name=$(git submodule--helper name "$sm_path")
> -				ignore_config=$(get_submodule_config "$name" ignore none)
> -				test $status != A && test $ignore_config = all && continue
> -			fi
> -			# Also show added or modified modules which are checked out
> -			GIT_DIR="$sm_path/.git" git rev-parse --git-dir >/dev/null 2>&1 &&
> -			printf '%s\n' "$sm_path"
> -		done
> -	)
> -
> -	test -z "$modules" && return
> -
> -	git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
> -	sane_egrep '^:([0-7]* )?160000' |
> -	cut -c2- |
> -	while read -r mod_src mod_dst sha1_src sha1_dst status name
> -	do
> -		if test -z "$cached" &&
> -			is_zero_oid $sha1_dst
> -		then
> -			case "$mod_dst" in
> -			160000)
> -				sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
> -				;;
> -			100644 | 100755 | 120000)
> -				sha1_dst=$(git hash-object $name)
> -				;;
> -			000000)
> -				;; # removed
> -			*)
> -				# unexpected type
> -				eval_gettextln "unexpected mode \$mod_dst" >&2
> -				continue ;;
> -			esac
> -		fi
> -		missing_src=
> -		missing_dst=
> -
> -		test $mod_src = 160000 &&
> -		! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
> -		missing_src=t
> -
> -		test $mod_dst = 160000 &&
> -		! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
> -		missing_dst=t
> -
> -		display_name=$(git submodule--helper relative-path "$name" "$wt_prefix")
> -
> -		total_commits=
> -		case "$missing_src,$missing_dst" in
> -		t,)
> -			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
> -			;;
> -		,t)
> -			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
> -			;;
> -		t,t)
> -			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$sha1_dst")"
> -			;;
> -		*)
> -			errmsg=
> -			total_commits=$(
> -			if test $mod_src = 160000 && test $mod_dst = 160000
> -			then
> -				range="$sha1_src...$sha1_dst"
> -			elif test $mod_src = 160000
> -			then
> -				range=$sha1_src
> -			else
> -				range=$sha1_dst
> -			fi
> -			GIT_DIR="$name/.git" \
> -			git rev-list --first-parent $range -- | wc -l
> -			)
> -			total_commits=" ($(($total_commits + 0)))"
> -			;;
> -		esac
> -
> -		sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
> -			echo $sha1_src | cut -c1-7)
> -		sha1_abbr_dst=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_dst 2>/dev/null ||
> -			echo $sha1_dst | cut -c1-7)
> -
> -		if test $status = T
> -		then
> -			blob="$(gettext "blob")"
> -			submodule="$(gettext "submodule")"
> -			if test $mod_dst = 160000
> -			then
> -				echo "* $display_name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:"
> -			else
> -				echo "* $display_name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:"
> -			fi
> -		else
> -			echo "* $display_name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
> -		fi
> -		if test -n "$errmsg"
> -		then
> -			# Don't give error msg for modification whose dst is not submodule
> -			# i.e. deleted or changed to blob
> -			test $mod_dst = 160000 && echo "$errmsg"
> -		else
> -			if test $mod_src = 160000 && test $mod_dst = 160000
> -			then
> -				limit=
> -				test $summary_limit -gt 0 && limit="-$summary_limit"
> -				GIT_DIR="$name/.git" \
> -				git log $limit --pretty='format:  %m %s' \
> -				--first-parent $sha1_src...$sha1_dst
> -			elif test $mod_dst = 160000
> -			then
> -				GIT_DIR="$name/.git" \
> -				git log --pretty='format:  > %s' -1 $sha1_dst
> -			else
> -				GIT_DIR="$name/.git" \
> -				git log --pretty='format:  < %s' -1 $sha1_src
> -			fi
> -			echo
> -		fi
> -		echo
> -	done
> +	git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${GIT_QUIET:+--quiet} ${prefix:+--prefix "$prefix"} ${for_status:+--for-status} ${files:+--files} ${cached:+--cached} ${summary_limit:+-n $summary_limit} "$@"
>  }
>  #
>  # List all submodules, prefixed with:
> --
> 2.27.0
>
>

^ permalink raw reply	[relevance 4%]

* [PATCH 4/4] submodule: port submodule subcommand 'summary' from shell to C
  2020-07-02 19:24  5% [GSoC][PATCH 0/4] submodule: port 'summary' from Shell to C Shourya Shukla
@ 2020-07-02 19:24 15% ` Shourya Shukla
  2020-07-03 20:46  4%   ` Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-07-02 19:24 UTC (permalink / raw)
  To: git
  Cc: christian.couder, gitster, liu.denton, kaartic.sivaraam, pc44800,
	sbeller, pclouds, Shourya Shukla

From: Prathamesh Chavan <pc44800@gmail.com>

The submodule subcommand 'summary' is ported in the process of
making git-submodule a builtin. The function cmd_summary() from
git-submodule.sh is ported to functions module_summary(),
compute_summary_module_list(), prepare_submodule_summary() and
generate_submodule_summary(), print_submodule_summary().

The first function module_summary() parses the options of submodule
subcommand and also acts as the front-end of this subcommand.
After parsing them, it calls the compute_summary_module_list()

The functions compute_summary_module_list() runs the diff_cmd,
and generates the modules list, as required by the subcommand.
The generation of this module list is done by the using the
callback function submodule_summary_callback(), and stored in the
structure module_cb.

Once the module list is generated, prepare_submodule_summary()
further goes through the list and filters the list, for
eventually calling the generate_submodule_summary() function.

The function generate_submodule_summary() takes care of generating
the summary for each submodule and then calls the function
print_submodule_summary() for printing it.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Stefan Beller <sbeller@google.com>
Mentored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
Signed-off-by: Shourya Shukla <shouryashukla.oo@gmail.com>
---
 builtin/submodule--helper.c | 451 ++++++++++++++++++++++++++++++++++++
 git-submodule.sh            | 186 +--------------
 2 files changed, 452 insertions(+), 185 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index eea3932c40..1dbdb934f1 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -927,6 +927,456 @@ static int module_name(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+struct module_cb {
+	unsigned int mod_src;
+	unsigned int mod_dst;
+	struct object_id oid_src;
+	struct object_id oid_dst;
+	char status;
+	const char *sm_path;
+};
+#define MODULE_CB_INIT { 0, 0, NULL, NULL, '\0', NULL }
+
+struct module_cb_list {
+	struct module_cb **entries;
+	int alloc, nr;
+};
+#define MODULE_CB_LIST_INIT { NULL, 0, 0 }
+
+struct summary_cb {
+	int argc;
+	const char **argv;
+	const char *prefix;
+	unsigned int cached: 1;
+	unsigned int for_status: 1;
+	unsigned int quiet: 1;
+	unsigned int files: 1;
+	int summary_limit;
+};
+#define SUMMARY_CB_INIT { 0, NULL, NULL, 0, 0, 0, 0, 0 }
+
+enum diff_cmd {
+	DIFF_INDEX,
+	DIFF_FILES
+};
+
+static int verify_submodule_object_name(const char *sm_path,
+					  const char *sha1)
+{
+	struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
+
+	cp_rev_parse.git_cmd = 1;
+	cp_rev_parse.no_stdout = 1;
+	cp_rev_parse.dir = sm_path;
+	prepare_submodule_repo_env(&cp_rev_parse.env_array);
+	argv_array_pushl(&cp_rev_parse.args, "rev-parse", "-q",
+			 "--verify", NULL);
+	argv_array_pushf(&cp_rev_parse.args, "%s^0", sha1);
+
+	if (run_command(&cp_rev_parse))
+		return 1;
+
+	return 0;
+}
+
+static void print_submodule_summary(struct summary_cb *info, int errmsg,
+				      int total_commits, int missing_src,
+				      int missing_dst, const char *displaypath,
+				      int is_sm_git_dir, struct module_cb *p)
+{
+	if (p->status == 'T') {
+		if (S_ISGITLINK(p->mod_dst))
+			printf(_("* %s %s(blob)->%s(submodule)"),
+				 displaypath, find_unique_abbrev(&p->oid_src, 7),
+				 find_unique_abbrev(&p->oid_dst, 7));
+		else
+			printf(_("* %s %s(submodule)->%s(blob)"),
+				 displaypath, find_unique_abbrev(&p->oid_src, 7),
+				 find_unique_abbrev(&p->oid_dst, 7));
+	} else {
+		printf("* %s %s...%s",
+			displaypath, find_unique_abbrev(&p->oid_src, 7),
+			find_unique_abbrev(&p->oid_dst, 7));
+	}
+
+	if (total_commits < 0)
+		printf(":\n");
+	else
+		printf(" (%d):\n", total_commits);
+
+	if (errmsg) {
+		/*
+		 * Don't give error msg for modification whose dst is not
+		 * submodule, i.e. deleted or changed to blob
+		 */
+		if (S_ISGITLINK(p->mod_src)) {
+			if (missing_src && missing_dst) {
+				printf(_("  Warn: %s doesn't contain commits %s and %s\n"),
+				       displaypath, oid_to_hex(&p->oid_src),
+				       oid_to_hex(&p->oid_dst));
+			} else if (missing_src) {
+				printf(_("  Warn: %s doesn't contain commit %s\n"),
+				       displaypath, oid_to_hex(&p->oid_src));
+			} else {
+				printf(_("  Warn: %s doesn't contain commit %s\n"),
+				       displaypath, oid_to_hex(&p->oid_dst));
+			}
+		}
+	} else if (is_sm_git_dir) {
+		struct child_process cp_log = CHILD_PROCESS_INIT;
+
+		cp_log.git_cmd = 1;
+		cp_log.dir = p->sm_path;
+		prepare_submodule_repo_env(&cp_log.env_array);
+		argv_array_pushl(&cp_log.args, "log", NULL);
+
+		if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) {
+			if (info->summary_limit > 0)
+				argv_array_pushf(&cp_log.args, "-%d",
+						 info->summary_limit);
+
+			argv_array_pushl(&cp_log.args, "--pretty=  %m %s",
+					 "--first-parent", NULL);
+			argv_array_pushf(&cp_log.args, "%s...%s",
+					 oid_to_hex(&p->oid_src),
+					 oid_to_hex(&p->oid_dst));
+		} else if (S_ISGITLINK(p->mod_dst)) {
+			argv_array_pushl(&cp_log.args, "--pretty=  > %s",
+					 "-1", oid_to_hex(&p->oid_dst), NULL);
+		} else {
+			argv_array_pushl(&cp_log.args, "--pretty=  < %s",
+					 "-1", oid_to_hex(&p->oid_src), NULL);
+		}
+		run_command(&cp_log);
+	}
+	printf("\n");
+}
+
+static void generate_submodule_summary(struct summary_cb *info,
+				       struct module_cb *p)
+{
+	int missing_src = 0;
+	int missing_dst = 0;
+	char *displaypath;
+	int errmsg = 0;
+	int total_commits = -1;
+	int is_sm_git_dir = 0;
+	struct strbuf sm_git_dir_sb = STRBUF_INIT;
+
+	if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
+		if (S_ISGITLINK(p->mod_dst)) {
+			/*
+			 * NEEDSWORK: avoid using separate process with
+			 * the help of the function head_ref_submodule()
+			 */
+			struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
+			struct strbuf sb_rev_parse = STRBUF_INIT;
+
+			cp_rev_parse.git_cmd = 1;
+			cp_rev_parse.no_stderr = 1;
+			cp_rev_parse.dir = p->sm_path;
+			prepare_submodule_repo_env(&cp_rev_parse.env_array);
+
+			argv_array_pushl(&cp_rev_parse.args, "rev-parse",
+					 "HEAD", NULL);
+			if (!capture_command(&cp_rev_parse, &sb_rev_parse, 0)) {
+				strbuf_strip_suffix(&sb_rev_parse, "\n");
+				get_oid_hex(sb_rev_parse.buf, &p->oid_dst);
+			}
+			strbuf_release(&sb_rev_parse);
+		} else if (S_ISLNK(p->mod_dst) || S_ISREG(p->mod_dst)) {
+			struct child_process cp_hash_object = CHILD_PROCESS_INIT;
+			struct strbuf sb_hash_object = STRBUF_INIT;
+
+			cp_hash_object.git_cmd = 1;
+			argv_array_pushl(&cp_hash_object.args, "hash-object",
+					 p->sm_path, NULL);
+			if (!capture_command(&cp_hash_object,
+					     &sb_hash_object, 0)) {
+				strbuf_strip_suffix(&sb_hash_object, "\n");
+				get_oid_hex(sb_hash_object.buf, &p->oid_dst);
+			}
+			strbuf_release(&sb_hash_object);
+		} else {
+			if (p->mod_dst)
+				die(_("unexpected mode %d\n"), p->mod_dst);
+		}
+	}
+
+	strbuf_addstr(&sm_git_dir_sb, p->sm_path);
+	if (is_nonbare_repository_dir(&sm_git_dir_sb))
+		is_sm_git_dir = 1;
+
+	if (is_sm_git_dir && S_ISGITLINK(p->mod_src))
+		missing_src = verify_submodule_object_name(p->sm_path,
+							   oid_to_hex(&p->oid_src));
+
+	if (is_sm_git_dir && S_ISGITLINK(p->mod_dst))
+		missing_dst = verify_submodule_object_name(p->sm_path,
+							   oid_to_hex(&p->oid_dst));
+
+	displaypath = get_submodule_displaypath(p->sm_path, info->prefix);
+
+	if (!missing_dst && !missing_src) {
+		if (is_sm_git_dir) {
+			struct child_process cp_rev_list = CHILD_PROCESS_INIT;
+			struct strbuf sb_rev_list = STRBUF_INIT;
+			char *range;
+
+			if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst))
+				range = xstrfmt("%s...%s", oid_to_hex(&p->oid_src),
+						oid_to_hex(&p->oid_dst));
+			else if (S_ISGITLINK(p->mod_src))
+				range = xstrdup(oid_to_hex(&p->oid_src));
+			else
+				range = xstrdup(oid_to_hex(&p->oid_dst));
+
+			cp_rev_list.git_cmd = 1;
+			cp_rev_list.dir = p->sm_path;
+			prepare_submodule_repo_env(&cp_rev_list.env_array);
+
+			argv_array_pushl(&cp_rev_list.args, "rev-list",
+					 "--first-parent", range, "--", NULL);
+			if (!capture_command(&cp_rev_list, &sb_rev_list, 0)) {
+				if (sb_rev_list.len)
+					total_commits = count_lines(sb_rev_list.buf,
+								    sb_rev_list.len);
+				else
+					total_commits = 0;
+			}
+
+			free(range);
+			strbuf_release(&sb_rev_list);
+		}
+	} else {
+		errmsg = 1;
+	}
+
+	print_submodule_summary(info, errmsg, total_commits,
+				missing_src, missing_dst,
+		      		displaypath, is_sm_git_dir, p);
+
+	free(displaypath);
+	strbuf_release(&sm_git_dir_sb);
+}
+
+static void prepare_submodule_summary(struct summary_cb *info,
+				      struct module_cb_list *list)
+{
+	int i;
+	for (i = 0; i < list->nr; i++) {
+		struct module_cb *p = list->entries[i];
+		struct child_process cp_rev_parse = CHILD_PROCESS_INIT;
+
+		if (p->status == 'D' || p->status == 'T') {
+			generate_submodule_summary(info, p);
+			continue;
+		}
+
+		if (info->for_status) {
+			char *config_key;
+			const char *ignore_config = "none";
+			const char *value;
+			const struct submodule *sub = submodule_from_path(the_repository,
+									  &null_oid,
+									  p->sm_path);
+
+			if (sub && p->status != 'A') {
+				config_key = xstrfmt("submodule.%s.ignore",
+						     sub->name);
+				if (!git_config_get_string_const(config_key, &value))
+					ignore_config = value;
+				else if (sub->ignore)
+					ignore_config = sub->ignore;
+
+				free(config_key);
+				if (!strcmp(ignore_config, "all"))
+					continue;
+			}
+		}
+
+		/* Also show added or modified modules which are checked out */
+		cp_rev_parse.dir = p->sm_path;
+		cp_rev_parse.git_cmd = 1;
+		cp_rev_parse.no_stderr = 1;
+		cp_rev_parse.no_stdout = 1;
+
+		argv_array_pushl(&cp_rev_parse.args, "rev-parse",
+				 "--git-dir", NULL);
+
+		if (!run_command(&cp_rev_parse))
+			generate_submodule_summary(info, p);
+	}
+}
+
+static void submodule_summary_callback(struct diff_queue_struct *q,
+				       struct diff_options *options,
+				       void *data)
+{
+	int i;
+	struct module_cb_list *list = data;
+	for (i = 0; i < q->nr; i++) {
+		struct diff_filepair *p = q->queue[i];
+		struct module_cb *temp;
+
+		if (!S_ISGITLINK(p->one->mode) && !S_ISGITLINK(p->two->mode))
+			continue;
+		temp = (struct module_cb*)malloc(sizeof(struct module_cb));
+		temp->mod_src = p->one->mode;
+		temp->mod_dst = p->two->mode;
+		temp->oid_src = p->one->oid;
+		temp->oid_dst = p->two->oid;
+		temp->status = p->status;
+		temp->sm_path = xstrdup(p->one->path);
+
+		ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
+		list->entries[list->nr++] = temp;
+	}
+}
+
+static const char *get_diff_cmd(enum diff_cmd diff_cmd)
+{
+	switch (diff_cmd) {
+	case DIFF_INDEX: return "diff-index";
+	case DIFF_FILES: return "diff-files";
+	default: BUG("bad diff_cmd value %d", diff_cmd);
+	}
+}
+
+static int compute_summary_module_list(char *head,
+				         struct summary_cb *info,
+				         enum diff_cmd diff_cmd)
+{
+	struct argv_array diff_args = ARGV_ARRAY_INIT;
+	struct rev_info rev;
+	struct module_cb_list list = MODULE_CB_LIST_INIT;
+
+	argv_array_push(&diff_args, get_diff_cmd(diff_cmd));
+	if (info->cached)
+		argv_array_push(&diff_args, "--cached");
+	argv_array_pushl(&diff_args, "--ignore-submodules=dirty", "--raw",
+			 NULL);
+	if (head)
+		argv_array_push(&diff_args, head);
+	argv_array_push(&diff_args, "--");
+	if (info->argc)
+		argv_array_pushv(&diff_args, info->argv);
+
+	git_config(git_diff_basic_config, NULL);
+	init_revisions(&rev, info->prefix);
+	rev.abbrev = 0;
+	precompose_argv(diff_args.argc, diff_args.argv);
+
+	diff_args.argc = setup_revisions(diff_args.argc, diff_args.argv,
+					 &rev, NULL);
+	rev.diffopt.output_format = DIFF_FORMAT_NO_OUTPUT | DIFF_FORMAT_CALLBACK;
+	rev.diffopt.format_callback = submodule_summary_callback;
+	rev.diffopt.format_callback_data = &list;
+
+	if (!info->cached) {
+		if (diff_cmd ==  DIFF_INDEX)
+			setup_work_tree();
+		if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
+			perror("read_cache_preload");
+			return -1;
+		}
+	} else if (read_cache() < 0) {
+		perror("read_cache");
+		return -1;
+	}
+
+	if (diff_cmd == DIFF_INDEX)
+		run_diff_index(&rev, info->cached);
+	else
+		run_diff_files(&rev, 0);
+	prepare_submodule_summary(info, &list);
+	return 0;
+}
+
+static int module_summary(int argc, const char **argv, const char *prefix)
+{
+	struct summary_cb info = SUMMARY_CB_INIT;
+	int cached = 0;
+	int for_status = 0;
+	int quiet = 0;
+	int files = 0;
+	int summary_limit = -1;
+	struct child_process cp_rev = CHILD_PROCESS_INIT;
+	struct strbuf sb = STRBUF_INIT;
+	enum diff_cmd diff_cmd = DIFF_INDEX;
+	int ret;
+
+	struct option module_summary_options[] = {
+		OPT__QUIET(&quiet, N_("Suppress output of summarising submodules")),
+		OPT_BOOL(0, "cached", &cached,
+			 N_("Use the commit stored in the index instead of the submodule HEAD")),
+		OPT_BOOL(0, "files", &files,
+			 N_("To compare the commit in the index with that in the submodule HEAD")),
+		OPT_BOOL(0, "for-status", &for_status,
+			 N_("Skip submodules with 'ignore_config' value set to 'all'")),
+		OPT_INTEGER('n', "summary-limit", &summary_limit,
+			     N_("Limit the summary size")),
+		OPT_END()
+	};
+
+	const char *const git_submodule_helper_usage[] = {
+		N_("git submodule--helper summary [<options>] [commit] [--] [<path>]"),
+		NULL
+	};
+
+	argc = parse_options(argc, argv, prefix, module_summary_options,
+			     git_submodule_helper_usage, 0);
+
+	if (!summary_limit)
+		return 0;
+
+	cp_rev.git_cmd = 1;
+	argv_array_pushl(&cp_rev.args, "rev-parse", "-q", "--verify",
+			 argc ? argv[0] : "HEAD", NULL);
+
+	if (!capture_command(&cp_rev, &sb, 0)) {
+		strbuf_strip_suffix(&sb, "\n");
+		if (argc) {
+			argv++;
+			argc--;
+		}
+	} else if (!argc || !strcmp(argv[0], "HEAD")) {
+		/* before the first commit: compare with an empty tree */
+		struct stat st;
+		struct object_id oid;
+		if (fstat(0, &st) < 0 || index_fd(&the_index, &oid, 0, &st, 2,
+						  prefix, 3))
+			die("Unable to add %s to database", oid.hash);
+		strbuf_addstr(&sb, oid_to_hex(&oid));
+		if (argc) {
+			argv++;
+			argc--;
+		}
+	} else {
+		strbuf_addstr(&sb, "HEAD");
+	}
+
+	if (files) {
+		if (cached)
+			die(_("--cached and --files are mutually exclusive"));
+		diff_cmd = DIFF_FILES;
+	}
+
+	info.argc = argc;
+	info.argv = argv;
+	info.prefix = prefix;
+	info.cached = !!cached;
+	info.for_status = !!for_status;
+	info.quiet = quiet;
+	info.files = files;
+	info.summary_limit = summary_limit;
+
+	ret = compute_summary_module_list((diff_cmd == DIFF_FILES) ? NULL : sb.buf,
+					   &info, diff_cmd);
+	strbuf_release(&sb);
+	return ret;
+}
+
 struct sync_cb {
 	const char *prefix;
 	unsigned int flags;
@@ -2341,6 +2791,7 @@ static struct cmd_struct commands[] = {
 	{"print-default-remote", print_default_remote, 0},
 	{"sync", module_sync, SUPPORT_SUPER_PREFIX},
 	{"deinit", module_deinit, 0},
+	{"summary", module_summary, SUPPORT_SUPER_PREFIX},
 	{"remote-branch", resolve_remote_submodule_branch, 0},
 	{"push-check", push_check, 0},
 	{"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
diff --git a/git-submodule.sh b/git-submodule.sh
index 43eb6051d2..899b8a409a 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -59,31 +59,6 @@ die_if_unmatched ()
 	fi
 }
 
-#
-# Print a submodule configuration setting
-#
-# $1 = submodule name
-# $2 = option name
-# $3 = default value
-#
-# Checks in the usual git-config places first (for overrides),
-# otherwise it falls back on .gitmodules.  This allows you to
-# distribute project-wide defaults in .gitmodules, while still
-# customizing individual repositories if necessary.  If the option is
-# not in .gitmodules either, print a default value.
-#
-get_submodule_config () {
-	name="$1"
-	option="$2"
-	default="$3"
-	value=$(git config submodule."$name"."$option")
-	if test -z "$value"
-	then
-		value=$(git submodule--helper config submodule."$name"."$option")
-	fi
-	printf '%s' "${value:-$default}"
-}
-
 isnumber()
 {
 	n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
@@ -831,166 +806,7 @@ cmd_summary() {
 		shift
 	done
 
-	test $summary_limit = 0 && return
-
-	if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
-	then
-		head=$rev
-		test $# = 0 || shift
-	elif test -z "$1" || test "$1" = "HEAD"
-	then
-		# before the first commit: compare with an empty tree
-		head=$(git hash-object -w -t tree --stdin </dev/null)
-		test -z "$1" || shift
-	else
-		head="HEAD"
-	fi
-
-	if [ -n "$files" ]
-	then
-		test -n "$cached" &&
-		die "$(gettext "The --cached option cannot be used with the --files option")"
-		diff_cmd=diff-files
-		head=
-	fi
-
-	cd_to_toplevel
-	eval "set $(git rev-parse --sq --prefix "$wt_prefix" -- "$@")"
-	# Get modified modules cared by user
-	modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
-		sane_egrep '^:([0-7]* )?160000' |
-		while read -r mod_src mod_dst sha1_src sha1_dst status sm_path
-		do
-			# Always show modules deleted or type-changed (blob<->module)
-			if test "$status" = D || test "$status" = T
-			then
-				printf '%s\n' "$sm_path"
-				continue
-			fi
-			# Respect the ignore setting for --for-status.
-			if test -n "$for_status"
-			then
-				name=$(git submodule--helper name "$sm_path")
-				ignore_config=$(get_submodule_config "$name" ignore none)
-				test $status != A && test $ignore_config = all && continue
-			fi
-			# Also show added or modified modules which are checked out
-			GIT_DIR="$sm_path/.git" git rev-parse --git-dir >/dev/null 2>&1 &&
-			printf '%s\n' "$sm_path"
-		done
-	)
-
-	test -z "$modules" && return
-
-	git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
-	sane_egrep '^:([0-7]* )?160000' |
-	cut -c2- |
-	while read -r mod_src mod_dst sha1_src sha1_dst status name
-	do
-		if test -z "$cached" &&
-			is_zero_oid $sha1_dst
-		then
-			case "$mod_dst" in
-			160000)
-				sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
-				;;
-			100644 | 100755 | 120000)
-				sha1_dst=$(git hash-object $name)
-				;;
-			000000)
-				;; # removed
-			*)
-				# unexpected type
-				eval_gettextln "unexpected mode \$mod_dst" >&2
-				continue ;;
-			esac
-		fi
-		missing_src=
-		missing_dst=
-
-		test $mod_src = 160000 &&
-		! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
-		missing_src=t
-
-		test $mod_dst = 160000 &&
-		! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
-		missing_dst=t
-
-		display_name=$(git submodule--helper relative-path "$name" "$wt_prefix")
-
-		total_commits=
-		case "$missing_src,$missing_dst" in
-		t,)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
-			;;
-		,t)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
-			;;
-		t,t)
-			errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$sha1_dst")"
-			;;
-		*)
-			errmsg=
-			total_commits=$(
-			if test $mod_src = 160000 && test $mod_dst = 160000
-			then
-				range="$sha1_src...$sha1_dst"
-			elif test $mod_src = 160000
-			then
-				range=$sha1_src
-			else
-				range=$sha1_dst
-			fi
-			GIT_DIR="$name/.git" \
-			git rev-list --first-parent $range -- | wc -l
-			)
-			total_commits=" ($(($total_commits + 0)))"
-			;;
-		esac
-
-		sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
-			echo $sha1_src | cut -c1-7)
-		sha1_abbr_dst=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_dst 2>/dev/null ||
-			echo $sha1_dst | cut -c1-7)
-
-		if test $status = T
-		then
-			blob="$(gettext "blob")"
-			submodule="$(gettext "submodule")"
-			if test $mod_dst = 160000
-			then
-				echo "* $display_name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:"
-			else
-				echo "* $display_name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:"
-			fi
-		else
-			echo "* $display_name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
-		fi
-		if test -n "$errmsg"
-		then
-			# Don't give error msg for modification whose dst is not submodule
-			# i.e. deleted or changed to blob
-			test $mod_dst = 160000 && echo "$errmsg"
-		else
-			if test $mod_src = 160000 && test $mod_dst = 160000
-			then
-				limit=
-				test $summary_limit -gt 0 && limit="-$summary_limit"
-				GIT_DIR="$name/.git" \
-				git log $limit --pretty='format:  %m %s' \
-				--first-parent $sha1_src...$sha1_dst
-			elif test $mod_dst = 160000
-			then
-				GIT_DIR="$name/.git" \
-				git log --pretty='format:  > %s' -1 $sha1_dst
-			else
-				GIT_DIR="$name/.git" \
-				git log --pretty='format:  < %s' -1 $sha1_src
-			fi
-			echo
-		fi
-		echo
-	done
+	git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${GIT_QUIET:+--quiet} ${prefix:+--prefix "$prefix"} ${for_status:+--for-status} ${files:+--files} ${cached:+--cached} ${summary_limit:+-n $summary_limit} "$@"
 }
 #
 # List all submodules, prefixed with:
-- 
2.27.0


^ permalink raw reply related	[relevance 15%]

* [GSoC][PATCH 0/4] submodule: port 'summary' from Shell to C
@ 2020-07-02 19:24  5% Shourya Shukla
  2020-07-02 19:24 15% ` [PATCH 4/4] submodule: port submodule subcommand 'summary' from shell " Shourya Shukla
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-07-02 19:24 UTC (permalink / raw)
  To: git
  Cc: christian.couder, gitster, liu.denton, kaartic.sivaraam, pc44800,
	sbeller, pclouds, Shourya Shukla

Hello all!

This is third subcommand in line to be converted as a part of my GSoC
project. The other two were 'set-url' and 'set-branch' both of which
have been merged into Git. This port has been taken off from what
Prathamesh Chavan left as a part of his GSoC project in 2017 under
Stefan Beller and Christian Couder. As written in my proposal and
advised by my mentors Kaartic and Christian, it was decided to re-use
PC's work for multiple reasons.

Here is the link to the v1 of his patch:
https://lore.kernel.org/git/20170731205621.24305-9-pc44800@gmail.com/

Here is the link to the v2 of his patch:
https://lore.kernel.org/git/20170807211900.15001-9-pc44800@gmail.com/

Even though this patch series draws on Prathamesh' work, a lot extra
features had to be added along with some remodelling. A summary of the 4
commits in this patch are as follows: the patch consists of 3
preparatory patches preceding the main commit porting 'git submodule summary'.

Being a bit more verbose about the prepatory patches:

    1. a8dcc59a6a amends an extra linefeed between callback struct(s)
       macro(s) of subcommands 'init', 'status' and 'sync' so as to make
       the whole format of subcommands a bit more uniform and
       consistent.

    2. 5f17ca37e0 renames the helper functions
       'show_submodule_summary()', 'prepare_submodule_summary()' and
       'print_submodule_summary()' used by the 'builtin_diff()' function
       of diff.c This was done so as to avoid any ambiguity later on
       when the helper functions used by 'summary' will be defined in
       the upcoming port. The functions are renamed to
       '*_diff_submodule_summary()' so as to classify them as the one
       being used by the diff machinery.

    3. 5945ab4113 changes the scope of the 'count_lines()' function
       defined in diff.c so as to make it usable by other entities of
       the code. This was originally a patch authored by PC with a small
       change that the function instead of being defined as an 'extern
       int', it is now defined as 'int' since f758a7f8ac4 by Nguyễn Thái
       Ngọc Duy removed extern from the function declarations in diff.h

Now moving on to the main patch 4/4 that will port summary.

    17738e9df4 ports the subcommand summary from Shell to C. I will not
    be repetitive by stating how all the functions communicate since
    this is covered in the commit message. What I will focus on is the
    bits I had to tweak along with any extra functions added. Originally
    the functions were: module_summary(),
    compute_summary_submodule_list(), submodule_summary_callback(),
    prepare_submodule_summary(), generate_submodule_summary(),
    print_submodule_summary() and verify_submodule_object_name. I had to
    add another function called get_diff_cmd() which fetches a const
    char * (a diff-index or a diff-files) in response to the enum provided
    to it and bugs out in case of an unexpected enum value. I also had
    to tweak the enum declared by PC by NOT keeping it static and
    tweaking its definition just a little. These were suggested by
    Christian on PC's patch at the time.

    There were also some changes to function parameters such as those
    of index_fd() by passing the the_index parameter to it or the case
    of submodule_from_path() where it was needed to add another parameter
    of the_repository. This all must have been due to change of function
    defintions in the past 3 years.

    Even after all this, there were two problems: t7418 had been failing
    (something which I feel might have been overlooked/not tested by PC
    during his time) and the CI build failed. First let's cover the test
    failure.

    The main test for testing summary is t7401. t7418 is another test
    which involves sparse checkouts and submodules. The test creates a
    sparse checkout clone excluding the .gitmodules file to test the
    functionality of the '--for-status' option. After quite a thorough
    investigation me, Kaartic and Christian figured out that this port
    fails to handle cases where a gitfile exists instead of a .git dir
    since all the tests in t7401 did not any submodules which were
    cloned in any way but rather just exist in a nearby directory and
    are used in our tests (this is something I feel should be fixed and
    hence I am saving this for later). But anyway, we decided that it
    will be excellent to check for a non-bare repo instead of checking
    for a gitdir therefore replacing the function is_git_directory()
    with is_nonbare_repository() in the first non-nested if-check in
    generate_submodule_summary().

    Regarding the CI failure. The build was failing due to the
    function oidcmp() in the first if-check of
    generate_submodule_summary(). The CI build suggested that we use
    oideq() instead so that the build passes and on doing the change, it
    did!

    There were some other cosmetic changes such as wrapping of
    columns upto 80 chars (to follow the CodingGuidelines) and
    improving some error messages and option descriptions,

Finally, since it was originally PC's work, I have kept him as the author
for the final 2 commits and kept the date as-is (from 2017). This patch
is not perfect and hence needs the feedback from all of you :)

Here is a 'git log --oneline' of the commits:

    17738e9df4 submodule: port submodule subcommand 'summary' from shell to C
    5945ab4113 diff: change scope of the function count_lines()
    5f17ca37e0 submodule: rename helper functions to avoid ambiguity
    a8dcc59a6a submodule: amend extra line feed between callback struct and macro

Thanks,
Shourya Shukla


Prathamesh Chavan (2):
  diff: change scope of the function count_lines()
  submodule: port submodule subcommand 'summary' from shell to C

Shourya Shukla (2):
  submodule: amend extra line feed between callback struct and macro
  submodule: rename helper functions to avoid ambiguity

 builtin/submodule--helper.c | 454 +++++++++++++++++++++++++++++++++++-
 diff.c                      |   4 +-
 diff.h                      |   1 +
 git-submodule.sh            | 186 +--------------
 submodule.c                 |  10 +-
 submodule.h                 |   2 +-
 6 files changed, 461 insertions(+), 196 deletions(-)

-- 
2.27.0


^ permalink raw reply	[relevance 5%]

* [GSoC][RFC][Proposal v5] Convert submodule to builtin
@ 2020-03-25 18:50  4% Shourya Shukla
  0 siblings, 0 replies; 200+ results
From: Shourya Shukla @ 2020-03-25 18:50 UTC (permalink / raw)
  To: git
  Cc: christian.couder, peff, heba.waly, newren, Johannes.Schindelin,
	Shourya Shukla

Hello everyone,

Thank you so much for reviewing my proposal v3 and v4 Christian! :)
This is the fifth draft of my GSoC Proposal. After discussions with Christian, I decided to improve the timeline and made some changes accordingly.

Also, could you please tell me which contributions are worth keeping in the 'Contributions to Git' section? I listed almost everything here. I have
answered multiple questions on StackOverflow as well. There is no need to separately link them right? I have mentioned my StackOverflow profile below BTW.

Changes made:
	1. Added more entries in the 'Contributions to Git' section
	2. Improved the 'Outline' section
	3. Added the 'Submodules and git submodule' section
	4. Added more links in the 'Contribution process and interaction with the mentors' section
	5. Improved the 'Project Timeline' section. Made some changes to the timeline
	6. Made some additions in the 'Workflow' section
	7. Corrected grammatical errors and spelling mistakes

PS: A prettier version of this proposal is on Docs, it is more readable than the plain-text version :)
Google Docs: https://docs.google.com/document/d/1vqu84h0E83BnNyuj19HkgoWsGYHsGgY2Jkc5kTB4fSs/edit?usp=sharing

Thanks,
Shourya

-x-x-x-x-x-x-x-x-x-x-x-x-x--x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x


# Convert submodule to builtin

## Contact Information
--------------------

Name          : Shourya Shukla
Major         : Computer Science and Engineering
E-mail        : shouryashukla.oo@gmail.com
IRC           : rasengan_chidori on #git & #git-devel
Mobile no     : <<mobile no>>
GitHub        : periperidip[https://github.com/periperidip]
Linkedin      : shuklashourya[https://www.linkedin.com/in/shuklashourya]
StackOverflow : rasengan__[https://stackoverflow.com/users/10751129/rasengan]
Website	      : https://sites.google.com/view/periperidip
Address       : <<address>>
Time Zone     : IST (UTC +0530)


## Background

I am Shourya Shukla, a sophomore in Computer Science and Engineering at the Indian Institute of Technology Roorkee[https://www.iitr.ac.in/].
I was introduced to programming at a young age and I have been trying to learn new concepts everyday since. My
interests include modern mobile networks, Internet of Things, system software development and Cryptography. I have been working
on a research project[https://github.com/periperidip/UAV-based-wireless-networks-2] which involves providing cellular network
access to users in a disaster-struck area via drones. I love low-level coding and FLOSS as well. I have been an active part of
the Git community since January of this year, contributing to Git.


## Work Environment

I am fluent in C/C++, Java and Shell script, and have an understanding of Python
as well. I use Git as my VCS and Visual Studio Code with integrated GDB as my
primary code editor and Ubuntu 19.10 as my primary Operating System unless the
work specifically needs Windows.


## Contributions to Git

Contributing to Git helped me understand a lot about how modern & robust software
work as well as how real world development takes place. I plan on contributing even
more to Git and make my contributions count. As of now, my contributions at Git are:

---------------
status: merged
git/git:
[Microproject]: Modernise tests and use helper functions in test script.
GitHub: https://github.com/git/git/commit/c513a958b69090c02ad422b0cd4622009bb4b9f5
List: https://lore.kernel.org/git/20200116203622.4694-1-shouryashukla.oo@gmail.com/

List
[Solved doubt]: fatal: cannot rebase with locally recorded submodule modifications
List:https://lore.kernel.org/git/20200207220403.28961-1-shouryashukla.oo@gmail.com/

List
[Aided a new contributor]: Need help to start contributing
List:https://lore.kernel.org/git/20200205032925.5272-1-shouryashukla.oo@gmail.com/

List
[Aided a potential GSoC student]: [GSoC] Microproject for git
List:https://lore.kernel.org/git/20200318192719.1127-1-shouryashukla.oo@gmail.com/

List
[Reviewed a Microproject]: [GSoC][PATCH 1/2] t4131: modernize style
List:https://lore.kernel.org/git/20200319163817.4239-1-shouryashukla.oo@gmail.com/


## The Project: Convert submodule to builtin

#### Outline

Some Git commands were initially implemented directly in shell script with some instances of Perl as well. As times progressed, various platforms to run Git emerged & projects became large(spanning millions of lines of code), enter, problems in production level code:

- There were issues with portability of code. The submodule shell script uses commands such as echo, grep, cd, test and printf to name a few. When switching to non-POSIX compliant systems, one
will have to re-implement these commands specific to the system. There are also POSIX-to-Windows path conversion issues. To fix these issues, it was decided to convert these scripts into
portable C code(the original intention C was developed with, to have portable code and software).

- There is large overhead involved in calling the command. As these commands implemented in shell script are not buitlins, they tend to call multiple fork() and exec() syscalls for creating more child processes hence creating another shell. This is the aforementioned overhead we are talking about and it rather takes a huge toll on big repositories in terms of the time elapsed to run a command as well as the extra memory consumed.

- If commands tend to use other commands inside of them(such as git submodule using git rev-parse, git ls-files and git add to name a few), the overhead mentioned in the point above tends to rise exponentially which again would contribute to the slowing down of the whole git suite.

Various commands have been converted as of now due to the reasons mentioned above, such as add, blame, bisect(work in progress), etc. In my project, I intend to convert submodule into C fully, hence making it a ‘builtin’.


#### Submodules and git submodule

Submodule, as defined in the gitglossary is, “A repository that holds the history of a separate project inside another repository (the latter of which is called superproject).”, which translates to, an independent git repository inside another git repository.

Submodules are used when we need to use some work from an external repository(say we need a particular library(eg: boost) to implement in our code) but at the same time keep it “independent” from our repository, meaning that they do not really interfere with our superproject’s tree as the submodules commit are not put on the top of, or in fact, anywhere into the superprojects tree. Any changes in the submodule are reflected as a change in any other directory w.r.t the superproject. In a nutshell, the submodule’s tree is independent of the superproject’s tree.

Git, for instance, uses the sha1collisiondetection repository[https://github.com/cr-marcstevens/sha1collisiondetection/tree/855827c583bc30645ba427885caa40c5b81764d2] as a submodule.
git submodule is a command to manipulate and deal with submodules. Our aim is to convert this command from its shell form into its C form.


#### Previous Work

There has been an ongoing work in the conversion of various Git commands such as 'add', 'commit', 'blame', etc. from their shell form into their C form. 'git submodule' is one of the commands left to fully convert into its C form. Stefan Beller <stefanbeller@gmail.com> converted a large part of this command up until 2019. Prathamesh Chavan <pc44800@gmail.com> also aided in the conversion of the command during his GSoC project in the year 2017. In its current state, four git submodule subcommands are due for conversion, namely: 'add', 'set-branch', 'set-url' and 'summary'. Also, the Command Line parsing Interface needs improvements, such as better error messages and support for more subcommands.

Prathamesh implemented and improved the subcommands status[https://lore.kernel.org/git/20170713200538.25806-4-pc44800@gmail.com/], sync[https://lore.kernel.org/git/20180114211529.6391-2-pc44800@gmail.com/], deinit[https://lore.kernel.org/git/20180114211529.6391-3-pc44800@gmail.com/] and some more. The relevancy of this to my project is that some helper functions(located in submodule.c) such as print_submodule_summary(),prepare_submodule_summary(), etc. have been implemented beforehand. In the case of subcommand summary, use these functions, integrate them with the basic scaffolding(mentioned in the table below) and implement the module_summary() frontend function. He also ported various helper functions such as set_name_rev()[https://lore.kernel.org/git/20170619215025.10086-3-pc44800@gmail.com/]. He kept offering improvements to his conversions till around January of 2018.

Stefan Beller finished the implementation of the subcommand init[https://lore.kernel.org/git/1453418323-29587-1-git-send-email-sbeller@google.com/] as well as laid its foundation[https://lore.kernel.org/git/1453255396-31942-3-git-send-email-sbeller@google.com/]. He implemented foreach[https://lore.kernel.org/git/20180509002952.172347-5-sbeller@google.com/] and improved deinit[https://lore.kernel.org/git/20180327232824.112539-1-sbeller@google.com/] & update[https://lore.kernel.org/git/1444960333-16003-6-git-send-email-sbeller@google.com/] as well. He also ported various helper functions such as resolve_relative_url()[https://lore.kernel.org/git/1460767813-25916-2-git-send-email-sbeller@google.com/].


#### Current Status of the subcommand and future vision

The current status of the conversion as well as the direction I will take for the conversion of the subcommands are as follows:

add: pending conversion, full code needs to be written for the same. Need to implement callback macros and structures, i.e. struct add_cb,
ADD_CB_INIT, as well as frontend function module_add(). Other helper functions may be needed in the process as well. Compare with shell
script and try to “translate” it into C. I guesstimate around 400-500 lines of code for this(including helper functions).

set-branch: pending conversion, full code needs to be written for the same. Need to implement macros and structures, i.e. struct setbranch,
SETBRANCH_CB_INIT, as well as frontend function module_setbranch(). Other helper functions(such as remote_submodule_branch() &
get_default_remote() which are already implemented may prove helpful later) may be needed in the process as well. Compare with shell
script and try to “translate” it into C. This subcommand may take about 200 lines of C code to implement(including helper functions).

set-url: pending conversion, full code needs to be written for the same. Need to implement macros and structures, i.e. struct seturl,
SETURL_CB_INIT, as well as frontend function module_seturl(). Other helper functions(such as remote_url() & resolve_resolve_url() which
are already implemented may prove helpful later) may be needed in the process as well. Compare with shell script and try to “translate” it
into C. It will have a similar implementation to set-branch because they are “setter” functions. This subcommand may take about 200 lines
of C code to implement(including helper functions).

summary: pending conversion, work in progress; callback structures, functions and macros have been created, also, basic scaffolding of the command
is done, i.e., functions module_summary(), summary_submodule(), summary_submodule_cb(). As this is a prototype, some functions may be scrapped
or added later. Other functions to complement the subcommand have already been created; learn from Prathamesh's mistakes and implement a better code.
After discussions with Junio C Hamano[https://lore.kernel.org/git/20200318163234.21628-1-shouryashukla.oo@gmail.com/T/#ma3912b761b6deda937691a19c1a070e5e9b34bd7],
I intend to add a “--recursive” option as well for summary so as to obtain summaries of nested submodules as well.
I estimate about 400 lines of code for this subcommand(excluding the  “--recursive” option, yet including the helper functions)

status: conversion complete, currently in a functional state.
	
init: conversion complete, currently in a functional state.

deinit: conversion complete, currently in a functional state.
	
update: conversion complete, currently in a functional state.
	
foreach: conversion complete, currently in a functional state.

sync: conversion complete, currently in a functional state.

absorbgitdirs: conversion complete, currently in a functional state.

I aim to follow the same approach as Stefan and Prathamesh as mentioned above, that is, I will also create a scaffolding first(which will be based on the already implemented commands). Followed by a comparison with the shell script and then picking out which helper functions might be needed and also reusing already implemented functions in 'submodule.c' and 'submodule--helper.c'.

Though, there is about a 3 year gap between their work and mine, the model for porting seems to be consistent even if coding style may vary and might even give out improvements over previous implementations.


#### Contribution process and interaction with the mentors

I will keep committing changes on my GitHub fork[https://github.com/periperidip/git] and finally post a patch series on the Mailing List. I will make sure to keep interacting with the community as well as the mentors regularly. I aim to write weekly “progress report” blogs, which I will post on my website[https://sites.google.com/view/periperidip] as well as the List. Apart from that, I will document anything new I learn as well as my journey in the GSoC program on my blogs and maybe as self-answered questions on StackOverflow with the aim that they will help me as well as others in case of reference.


#### Project Timeline

I have been studying the code of 'submodule.c', 'submodule--helper.c' and 'git-submodule.sh'
since the submission of my microproject. After studying the codes, I tried to devise an effective
conversion strategy for 'submodule'. I noticed that 'submodule.c' contains various helper functions
for 'submodule--helper.c' whereas the latter houses the main "converted" command as of now.
      
The subcommands ‘set-branch’ and ‘set-url’ will provide easy conversion due to the vast array of helper functions already available for them. Hence, I intend to implement them before the other subcommands due to their simplicity in implementation as well as the motivation it will give me to do more.

After considering a lot of things, and important advice from Christian Couder, I have decided that I will first implement ‘set-url’ and ‘set-branch’, followed by ‘summary’ and finally ‘add’. Integration testing and documentation updates will keep following the implementations. To add on, the conversion of summary might become a tad bit easier due to the existence of a patch[https://lore.kernel.org/git/20170731205621.24305-9-pc44800@gmail.com/] to convert it, which will aid me in learning from the mistakes committed before and thus help me offer an even more improved version of the subcommand. .


Therefore, after all these considerations, the timeline looks like:

- Empty Period (Present - April 26)
--> I am writing a paper(on the project[https://github.com/periperidip/UAV-based-wireless-networks-2] I have been working upon) for a conference which I have to finalise and submit by first week of April. Hence, I might be inactive in that period
--> My end-semester exams begin on April 23(tentative, may change due to the Corona pandemic) hence I might be a bit busy a week or so before their commencement as well as the 14 days in which exams take place
--> I plan on starting the conversion of set-url’ and 'set-branch’ in this period. Although I am busy, I will try my best to implement a basic scaffolding and maybe even complete some good portion of the subcommands and will keep my mentors posted regarding the same


- Community Bonding Period (April 27 - May 18)
--> Get familiar with the community
--> Improve the project workflow: make some timeline changes if necessary
--> Finish implementation of set-url’ and 'set-branch’ subcommands
--> Update the Documentation


- Phase 1 (May 19 - June 6)
--> Convert ‘summary’ subcommand
--> Improve CLI parsing(give out better error messages)
--> Update the Documentation
--> Add appropriate tests for integration testing of ‘set-url’, ‘set-branch’ and ‘summary’

    
- Phase 2 (June 7- August 8)
--> Convert 'add' subcommand
--> Improve the remaining bits of the CLI parsing
--> Update the Documentation
--> Add appropriate tests for integration testing of ‘add’ with the whole system


- Final Phase (August 9 - August 17)
--> Improve and add Documentation(if there is any still left)
--> Apply final touch-ups to code

If there is some extra time left, I will try to implement some BONUS features.

**BONUS features:** Consist of command touch ups and improving some bugs such as code sections with 'NEEDSWORK' tags, improving the test files and maybe improve some previous implementations of helper functions. Also, there are some incomplete bits[https://github.com/git/git/blob/v2.26.0/git-submodule.sh#L451-L712] of the ‘update’ subcommand as well in the shell file, as pointed out by Dscho[https://github.com/gitgitgadget/git/issues/541#issuecomment-602613250], which may need to be corrected.


## Workflow

I have divided the project into 3 subprojects(SP).

1. **SP 1:** Convert ‘set-branch’ and set-url’
2. **SP 2:** Convert ‘summary’ and and improve CLI(Command Line Interface) parsing
3. **SP 3:** Convert ‘add’ and improve CLI parsing

After discussions with Christian Couder, I plan to start SP1 before GSoC itself. Currently,
I am studying the code in detail and constructing a scaffolding for this implementation.
I aim to complete the leftover bits of SP1 during Phase 1 and SP2 & SP3 during Phase 2 of
GSoC.

As Derrick Stolee advised[https://lore.kernel.org/git/nycvar.QRO 7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m232941f6cdcf92b97b3531f6fc582935c06734cf],
the conversion may not be possible in one whole summer, hence, I think an early start might be needed to finish things in time if possible.

As of now(March 21(UTC)), my progress is described by the following commit[https://github.com/periperidip/git/commit/db3604f653e02a90145abb56cffb2d4860ececa2].
I have implemented the frontend function(almost) module_summary(). I hope to increase my work speed once I get a hang of the inner working and coding style
of the command.


## Availability

The official GSoC period starts from April 27 and ends on August 17. My vacations start
from May 10 and will be over by July 13. I can easily devote 45-50 hours per week until
the commencement of my Semester. Other than this project, I have no commitments planned
for my vacations. I shall keep the community posted in case of any change in plans.


## Post GSoC

Even after the completion of Google Summer of Code, I plan on continuing my contributions
to Git, on the technical front(in terms of code and documentation contributions) as well
as on the social front(solving people's doubts/problems on the List as well as on StackOverflow).
I vision to convert the remaining of the commands as pointed out by Dscho[https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m637c5c97d42dc68aab85420b5ffcaeb34c270ad3]
as well as improve the test files.

I aim to develop mentorship skills as well as the ability to guide others and try to give back to
the community by mentoring and guiding others as well(by reviewing their code, helping them out, etc.)


## Final Remarks

I have a habit of not giving up. I will keep trying things until I succeed at them. Same was my case with learning to use Git in my freshman year. I was so scared of it for some reason that I refrained from using ‘git bash’. But I knew that I had to master this tool(or at least learn it to a satisfactory extent) because of the utility it has in a programmer’s life. I kept going, watching tons of tutorials, reading the documentation and articles and lo, here I am writing code for Git.

I hope that you give me the chance to showcase my abilities by considering my proposal for working with you during the summer of 2020. Really looking forward to learning from you :)


^ permalink raw reply	[relevance 4%]

* Re: [GSoC][RFC][Proposal v4] Convert submodule to builtin
  2020-03-23 17:15  4% [GSoC][RFC][Proposal v4] " Shourya Shukla
@ 2020-03-24  9:08  2% ` Christian Couder
  0 siblings, 0 replies; 200+ results
From: Christian Couder @ 2020-03-24  9:08 UTC (permalink / raw)
  To: Shourya Shukla
  Cc: git, Jeff King, Heba Waly, Elijah Newren, Johannes Schindelin

Hi,

On Mon, Mar 23, 2020 at 6:16 PM Shourya Shukla
<shouryashukla.oo@gmail.com> wrote:

> Prathamesh implemented and improved the subcommands status[https://lore.kernel.org/git/20170713200538.25806-4-pc44800@gmail.com/], sync[https://lore.kernel.org/git/20180114211529.6391-2-pc44800@gmail.com/], deinit[https://lore.kernel.org/git/20180114211529.6391-3-pc44800@gmail.com/] and some more. The relevancy of this to my project is that some helper functions(located in submodule.c) such as print_submodule_summary(),prepare_submodule_summary(), etc. have been implemented beforehand. In the case of subcommand summary, use these functions, integrate them with the basic scaffolding(mentioned in the table below) and implement the module_summary() frontend function.

The last sentence above is not very clear to me. Do you mean "In the
case of subcommand summary, I should use these functions, integrate
them ..."? Or maybe  "In the case of subcommand summary, the things
left to do are to use these functions, integrate them ..."?

> He also ported various helper functions such as set_name_rev()[https://lore.kernel.org/git/20170619215025.10086-3-pc44800@gmail.com/]. He kept offering improvements to his conversions till around January of 2018.

Nice!

> Stefan Beller finished the implementation of the subcommand init[https://lore.kernel.org/git/1453418323-29587-1-git-send-email-sbeller@google.com/] as well as laid its foundation[https://lore.kernel.org/git/1453255396-31942-3-git-send-email-sbeller@google.com/]. He implemented foreach[https://lore.kernel.org/git/20180509002952.172347-5-sbeller@google.com/] and improved deinit[https://lore.kernel.org/git/20180327232824.112539-1-sbeller@google.com/] & update[https://lore.kernel.org/git/1444960333-16003-6-git-send-email-sbeller@google.com/] as well. He also ported various helper functions such as resolve_relative_url()[https://lore.kernel.org/git/1460767813-25916-2-git-send-email-sbeller@google.com/].

Nice!

> #### Current Status of the subcommand and future vision
>
> The current status of the conversion as well as the direction I will take for the conversion of the subcommands are as follows:
>
>         add: pending conversion, full code needs to be written for the same. Need to implement callback macros and structures, i.e. struct add_cb,
>              ADD_CB_INIT, as well as frontend function module_add(). Other helper functions may be needed in the process as well. Compare with shell
>              script and try to “translate” it into C. I guesstimate around 400-500 lines of code for this(including helper functions).

Happy to see a guesstimation!

>         set-branch: pending conversion, full code needs to be written for the same. Need to implement macros and structures, i.e. struct setbranch,
>                     SETBRANCH_CB_INIT, as well as frontend function module_setbranch(). Other helper functions(such as remote_submodule_branch() &
>                     get_default_remote() which are already implemented may prove helpful later) may be needed in the process as well. Compare with shell
>                     script and try to “translate” it into C. This subcommand may take about 200 lines of C code to implement(including helper functions).

As it looks like it requires less lines of code, do you think it might
be better to do this one before the 'add' sub-command?

>         set-url: pending conversion, full code needs to be written for the same. Need to implement macros and structures, i.e. struct seturl,
>                  SETURL_CB_INIT, as well as frontend function module_seturl(). Other helper functions(such as remote_url() & resolve_resolve_url() which
>                  are already implemented may prove helpful later) may be needed in the process as well. Compare with shell script and try to “translate” it
>                  into C. It will have a similar implementation to set-branch because they are “setter” functions. This subcommand may take about 200 lines
>                  of C code to implement(including helper functions).
>
>         summary: pending conversion, work in progress; callback structures, functions and macros have been created, also, basic scaffolding of the command
>                  is done, i.e., functions module_summary(), summary_submodule(), summary_submodule_cb(). As this is a prototype, some functions may be scrapped
>                  or added later. Other functions to complement the subcommand have already been created; learn from Prathamesh's mistakes and implement a better code.
>                  After discussions with Junio C Hamano[https://lore.kernel.org/git/20200318163234.21628-1-shouryashukla.oo@gmail.com/T/#ma3912b761b6deda937691a19c1a070e5e9b34bd7],
>                  I intend to add a “--recursive” option as well for summary so as to obtain summaries of nested submodules as well.
>                  I estimate about 400 lines of code for this subcommand(excluding the  “--recursive” option, yet including the helper functions)

Nice!

> I aim to follow the same approach as Stefan and Prathamesh as mentioned above.

I am not sure that you talked much about their approach above.

> Though, there is about a 3 year gap between their work and mine, the model for porting seems to be consistent even if coding style may vary and might even give out improvements over previous implementations.



> #### Contribution process and interaction with the mentors
>
> I will keep committing changes on my GitHub fork[https://github.com/periperidip/git] and finally post a bundled patch on the Mailing List.

By "bundled patch" do you mean a patch series?

> I will make sure to keep interacting with the community as well as the mentors regularly.    I aim to write weekly “progress report” blogs, which I will post on my website as well as the List. Apart from that, I will document anything new I learn as well as my journey in the GSoC program on my blogs and maybe as self-answered questions on StackOverflow with the aim that they will help me as well as others in case of reference.
>
>
> #### Project Timeline
>
> I have been studying the code of 'submodule.c', 'submodule--helper.c' and 'git-submodule.sh'
> since the submission of my microproject. After studying the codes, I tried to devise an effective
> conversion strategy for 'submodule'. I noticed that 'submodule.c' contains various helper functions
> for 'submodule--helper.c' whereas the latter houses the main "converted" command as of now.
>
> The subcommands ‘set-branch’ and ‘set-url’ will provide easy conversion due to the vast array of helper functions already available for them.

Nice that you found this!

> Hence, I have coupled them with other commands and tasks such as the conversion of ‘add’ and improving CLI parsing.

Hmm.

> In spite of the easiness of the aforementioned conversions, I have decided to convert ‘summary’ first because of the large variety of resources available for it

It is not very clear which resources you are talking about.

> as well as a direction of conversion available(as done by Prathamesh)

Do you mean that he already sent patches or wrote commits in his repo
about that?

> which will aid me in learning from the mistakes committed before and thus help me offer an even more improved version of the subcommand.

Thanks,
Christian.

^ permalink raw reply	[relevance 2%]

* Re: [GSoC][RFC][Proposal v3] Convert submodule to builtin
  2020-03-18 19:10  4% [GSoC][RFC][Proposal v3] " Shourya Shukla
@ 2020-03-24  8:21  4% ` Christian Couder
  0 siblings, 0 replies; 200+ results
From: Christian Couder @ 2020-03-24  8:21 UTC (permalink / raw)
  To: Shourya Shukla
  Cc: git, Johannes Schindelin, Jeff King, Heba Waly, Elijah Newren

Hi,

On Wed, Mar 18, 2020 at 8:10 PM Shourya Shukla
<shouryashukla.oo@gmail.com> wrote:
>
> Hello everyone,
>
> Thank you so much once again for reviewing my proposal v2 Christian! :)
> Apologies for the late reply, I had been working on the conversion since and needed some concrete study for my proposal. This is the third draft of my GSoC Proposal. I have acted upon Christian's advice and reviews of my proposal.
>
> Changes made:
>         1. Corrected some of the links provided
>         2. Renamed 'Relevant Work' to 'Workflow'
>         3. Corrected grammatical errors and spelling mistakes
>         4. Added more information about the conversion process as well as the current
>            state of the subcommands left to convert, along with a potential process and
>            direction of the conversion.

Great!

> I think the proposal needs to be even more descriptive conversion process and direction, I will keep exploring the code even more and try to formulate an even better direction in the coming couple of days.
>
> One thing I wanted to ask was that how do I foresee a good strategy and required helper functions
> for the subcommands add, set-branch and set-url, as I am not working on them currently, hence I am
> not able to exactly predict a path as of now. I can foresee a skeleton for these subcommands but
> not a precise track for the same. :/

I was not asking that you work on them with the goal of converting
them right away, but rather that you take a look at each of them to
see if they call a lot of other shell functions that might themselves
call a lot of other shell functions and so on.

If you don't look at that, you may for example, at the beginning of
your project, start converting a sub-command which requires many shell
functions to be converted first, which means that it might take a long
time before your first patches can be merged.

It's better if you start converting a sub-command that doesn't require
a lot of work. So that you can send patches early and then work on the
rest while your early patches are reviewed.

> Also, a small report on my progress: I have created a scaffolding of the 'summary' subcommand as stated in this commit:
> https://github.com/periperidip/git/commit/d33948dfc5d4c8faede9d3213adc3964557f33e1

We don't ask that you start your project before the GSoC starts. We'd
rather have you do other things that regular contributors do, like
reviewers other's patches on the mailing list or implementing small
things to scratch your itches (though not things that would interfere
with your project).

> I have progressed further than this commit and I will update the GitHub fork shortly. Currently, I am
> studying other subcommands and trying to find a better direction for the code. I am also studying
> Prathamesh Chavan's 2017 GSoC project and patches thoroughly.

Yeah, it's a good idea to study the different sub-commands and
previous GSoC students' work.

> PS: A prettier version of this proposal is on Docs, it is more readable than the plain-text version :)
> Google Docs: https://docs.google.com/document/d/1vqu84h0E83BnNyuj19HkgoWsGYHsGgY2Jkc5kTB4fSs/edit?usp=sharing
>
> PPS: I noticed that there are new subcommands in the 'submodule--helper.c' but they are not defined
> in submodule's documentation. Will they be added after the full completion of the conversion?

I am not sure. They might just be temporary helper sub-commands that
should be removed when conversion to C is finished.

By the way it might be a good strategy if there are big shell
functions that need to be converted to convert them first into
temporary helper sub-commands. That's one reason why it's interesting
for you to study a bit each sub-command left to be converted.

> ## Contributions to Git
>
> Contributing to Git helped me understand a lot about how modern & robust software
> work as well as how real world development takes place. I plan on contributing even
> more to Git and make my contributions count. As of now, my contributions at Git are:
>
> ---------------
> status: merged
> git/git:
> [Microproject]: Modernise tests and use helper functions in test script.
> GitHub: https://github.com/git/git/commit/c513a958b69090c02ad422b0cd4622009bb4b9f5
> List: https://lore.kernel.org/git/20200116203622.4694-1-shouryashukla.oo@gmail.com/

Participating in discussions and reviewing other's patches can also be
valuable contributions, so please list them too.

> ## The Project: Convert submodule to builtin
>
> #### Outline
>
> Git commands were initially implemented directly in shell script with some instances of Perl as well.

Not all the Git commands were implemented in shell scripts.

> As times progressed, various platforms to run Git on emerged, _enter_, problems in production code. There were multiple problems with shell scripts, such as: compatibility of code across platforms(e.g.: POSIX-to-Windows path conversion issues).

What do previous students who worked on porting some commands to C
have written about that?

> To fix this issue, it was decided to convert these scripts into portable C code(the original intention C was developed with, to have portable code and software).
>
> Various commands have been converted as of now, such as add, blame, bisect(work in progress), etc. In my project, I intend to convert submodule into C fully, hence making it a ‘builtin’.
>
>
> #### Previous Work
>
> There has been an ongoing work in the conversion of various Git commands such as 'add', 'commit', 'blame', etc. from their shell form into their C form. 'git submodule' is one of the commands left to fully convert into its C form. Stefan Beller <stefanbeller@gmail.com> converted a large part of this command up until 2019. Prathamesh Chavan <pc44800@gmail.com> also aided in the conversion of the command during his GSoC project in the year 2017. In its current state, four subcommands are due for conversion, namely: 'add', 'set-branch', 'set-url' and 'summary'.

It might be clearer if you say "four 'git submodule' subcommands".

> Also, the Command Line parsing Interface needs improvements, such as better error messages and support for more subcommands.
>
> Prathamesh Chavan implemented and improved the subcommands summary, status, sync, deinit and some more. The relevancy of this to my project is that some helper functions(located in sbmodule.c) such as print_submodule_summary(),prepare_submodule_summary(), etc. have been implemented beforehand.

"submodule.c" instead of "sbmodule.c".

> In the case of subcommand summary, the work left is to stitch these functions together and implement the main module_summary() function. The current status of The conversion is:
>
>         add: pending conversion, full code needs to be written for the same. Need to implement
>              callback macros and structures, i.e. struct add_cb(), ADD_CB_INIT, as well as frontend                  function module_add(). Other helper functions may be needed in the process as well.                     Compare with shell script and try to “translate” it into C.

The above is not easy to understand. Could you find a way so that it
appears nice when converted to plain text?

>         set-branch: pending conversion, full code needs to be written for the same. Need to implement                       macros and structures, i.e. struct _setbranch(), SETBRANCH_CB_INIT, as well as                          frontend function module_setbranch(). Other helper functions may be needed in the                       process as well. Compare with shell script and try to “translate” it into C.        set-url: pending conversion, full code needs to be written for the same. Need to implement                      macros and structures, i.e. struct _seturl(), SETURL_CB_INIT, as well as frontend                       function module_seturl(). Other helper functions may be needed in the process as                        well. Compare with shell script and try to “translate” it into C.Compare with shell                     script and try to “translate” it into C. It will have a similar implementation to                       set-branch because they are “setter” functions

Also not easy to understand the above.

>         summary: pending conversion, work in progress; callback structures, functions and macros have
>                  been created, also, basic scaffolding of the command is done, i.e., functions
>                  module_summary(), summary_submodule(), summary_submodule_cb(). As this is a
>                  prototype, some functions may be scrapped or added later. Other functions to
>                  complement the subcommand have already been created; learn from Prathamesh's
>                  mistakes and implement a better code.

What I'd like to see is an estimation of the effort required for each
of the module_summary(), summary_submodule() and
summary_submodule_cb() functions. For example it would be especially
interesting if there is one function that needs 5 times more work than
the others as maybe an helper command in 'submodule--helper.c' could
be created for this function.

>         status: conversion complete, currently in a functional state.
>         init: conversion complete, currently in a functional state.
>         deinit: conversion complete, currently in a functional state.
>         update: conversion complete, currently in a functional state.
>         foreach: conversion complete, currently in a functional state.
>         sync: conversion complete, currently in a functional state.
>         absorbgitdirs: conversion complete, currently in a functional state.
>
>
>
> I plan on working in a similar fashion by contributing changes to my GitHub handle as well as the refined versions to the List, so that my mentors are able to keep a track of my progress regularly. I plan to create a weekly blog for the same, but in case it is not possible, I will post weekly updates on the List.

Ok.

> #### Project Timeline
>
> I have been studying the code of 'submodule.c', 'submodule--helper.c' and 'git-submodule.sh'
> since the submission of my microproject. After studying the codes, I tried to devise an effective
> conversion strategy for 'submodule'. I noticed that 'submodule.c' contains various helper functions
> for 'submodule--helper.c' whereas the latter houses the main "converted" command as of now.
>
> Therefore, the timeline looks like:
>
>   - Empty Period (Present - April 26)
>     --> I am writing a paper(of the project I have been working upon) for a conference which I have to finalise and submit by first week of April.

Is it the UAV project?

>     --> My end-semester exams begin on April 23 hence I might be a bit busy before a week or so before the start date.

Could you also give the end date of your exams?

>     --> I plan on starting the conversion of ‘summary’ in this period. Although, I am busy, I will try my best to implement a basic scaffolding and maybe
>         even complete some good portion of the subcommand for the command and will keep my mentors posted regarding the same.
>
>   - Community Bonding Period (April 27 - May 18)
>     --> Get familiar with the community
>     --> Improve the project workflow: make some timeline changes if necessary.
>     --> Finish implementation of `summary` subcommand
>
>   - Phase 1 (May 19 - June 6)
>     --> Convert 'set-url' subcommand
>     --> Improve CLI parsing(give out better error messages)
>
>   - Phase 2 (June 7- August 8)
>     --> Convert 'add' subcommand
>     --> Convert 'set-branch' subcommand
>
>   - Final Phase (August 9 - August 17)
>     --> Improve and add Documentation(if there is any still left)
>     --> Apply final touch-ups to code
>
> If there is some extra time left, I will try to implement some BONUS features.
>
> **BONUS features:** Consist of command touch ups and improving some bugs such as code
>                     sections with 'NEEDSWORK' tags.
>
>
> ## Workflow
>
> I have divided the project into 3 subprojects(SP).
>
>     1. **SP 1:** Convert 'summary'
>     2. **SP 2:** Convert 'set-url' and and improve CLI(Command Line Interface) parsing
>     3. **SP 3:** Convert 'add' and 'set-branch'
>
> After discussions with Christian Couder, I plan to start SP1 before GSoC itself. Currently,
> I am studying the code in detail and constructing a scaffolding for this implementation.
> I aim to complete the leftover bits of SP1 during Phase 1 and SP2 & SP3 during Phase 2 of
> GSoC.
>
> As Derrick Stolee advised[https://lore.kernel.org/git/nycvar.QRO 7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m232941f6cdcf92b97b3531f6fc582935c06734cf],
> the conversion may not be possible in one whole summer, hence, I think an early start might be needed to finish things in time if possible.
>
>
> ## Availability
>
> The official GSoC period starts from April 27 and ends on August 17. My vacations start
> from May 10 and will be over by July 13.

So your exams are from April 23 to May 9?

> I can easily devote 45-50 hours per week until
> the commencement of my Semester. Other than this project, I have no commitments planned
> for my vacations. I shall keep the community posted in case of any change in plans.
>
>
> ## Post GSoC
>
> Even after the completion of Google Summer of Code, I plan on continuing my contributions
> to Git, on the technical front(in terms of code and documentation contributions) as well
> as on the social front(solving people's doubts/problems on the List as well as on StackOverflow).
> I vision to convert the remaining of the commands as pointed out by Dscho[https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m637c5c97d42dc68aab85420b5ffcaeb34c270ad3]
> as well as improve the test files.
>
> I aim to develop mentorship skills as well as the ability to guide others and try to give back to
> the community by mentoring and guiding others as well(by reviewing their code, helping them out, etc.)

Ok.

Thanks,
Christian.

^ permalink raw reply	[relevance 4%]

* [GSoC][RFC][Proposal v4] Convert submodule to builtin
@ 2020-03-23 17:15  4% Shourya Shukla
  2020-03-24  9:08  2% ` Christian Couder
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-03-23 17:15 UTC (permalink / raw)
  To: git
  Cc: christian.couder, peff, heba.waly, newren, Johannes.Schindelin,
	Shourya Shukla

Hello everyone,

Thank you so much once again for reviewing my proposal v2 Christian! :)
Apologies for the late reply, I had been working on the conversion since and needed some concrete study for my proposal. This is the fourth draft of my GSoC Proposal. Though my v3 did not get reviewed, I decided to deploy an even more improved version of my proposal, so here it goes. I have acted upon Christian's advice and reviews of my proposal.

Link to v3:
https://lore.kernel.org/git/20200318191033.443-1-shouryashukla.oo@gmail.com/

Changes made:
	1. Corrected some of the links provided[v3]
	2. Renamed 'Relevant Work' to 'Workflow'[v3]
	3. Corrected grammatical errors and spelling mistakes[v3+v4]
	4. Added more information about the conversion process as well as the current
	   state of the subcommands left to convert, along with a potential process and
	   direction of the conversion[v3]
	5. Improved the Timeline[v4]
	6. Added more description and strenghtened the information in change 4[v4]
	7. Added more relevant information in the 'Previous Work' section[v4]
	8. Added website link in the 'Contact Information' section[v4]
	9. Added the 'Current Status of the subcommand and future vision' section[v4]
	10. Added the 'Contribution process and interaction with the mentors' section[v4]
	11. Added the 'Final Remarks' section[v4]

One thing I wanted to ask was that how do I foresee a good strategy and required helper functions
for the subcommands add, set-branch and set-url, as I am not working on them currently, hence I am
not able to exactly predict a path as of now. I can foresee a skeleton for these subcommands but
not a precise track for the same. :/

I have almost completed the frontend 'module_summary()' function. This commit describes the following:
https://github.com/periperidip/git/commit/db3604f653e02a90145abb56cffb2d4860ececa2
Note: Travis CI failed due to some errors there are in the change which I will address in the next commit.

Currently, I am studying other subcommands and trying to find a better direction for the code. I am also studying
Prathamesh Chavan's 2017 GSoC project and patches thoroughly.

PS: A prettier version of this proposal is on Docs, it is more readable than the plain-text version :)
Google Docs: https://docs.google.com/document/d/1vqu84h0E83BnNyuj19HkgoWsGYHsGgY2Jkc5kTB4fSs/edit?usp=sharing

PPS: I noticed that there are new subcommands in the 'submodule--helper.c' but they are not defined
in submodule's documentation. Will they be added after the full completion of the conversion?

Thanks,
Shourya

-x-x-x-x-x-x-x-x-x-x-x-x-x--x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x


# Convert submodule to builtin

## Contact Information
--------------------

Name          : Shourya Shukla
Major         : Computer Science and Engineering
E-mail        : shouryashukla.oo@gmail.com
IRC           : rasengan_chidori on #git & #git-devel
Mobile no     : <<mobile no>>
GitHub        : periperidip
Linkedin      : shuklashourya
StackOverflow : rasengan__
Website	      : https://sites.google.com/view/periperidip
Address       : <<address>>
Time Zone     : IST (UTC +0530)


## Background

I am Shourya Shukla, a sophomore in Computer Science and Engineering at the Indian Institute of Technology Roorkee[https://www.iitr.ac.in/].
I was introduced to programming at a young age and I have been trying to learn new concepts everyday since. My
interests include modern mobile networks, Internet of Things, system software development and Cryptography. I have been working
on a research project[https://github.com/periperidip/UAV-based-wireless-networks-2] which involves providing cellular network
access to users in a disaster-struck area via drones. I love low-level coding and FLOSS as well. I have been an active part of
the Git community since January of this year, contributing to Git.


## Work Environment

I am fluent in C/C++, Java and Shell script, and have an understanding of Python
as well. I use Git as my VCS and Visual Studio Code with integrated GDB as my
primary code editor and Ubuntu 19.10 as my primary Operating System unless the
work specifically needs Windows.


## Contributions to Git

Contributing to Git helped me understand a lot about how modern & robust software
work as well as how real world development takes place. I plan on contributing even
more to Git and make my contributions count. As of now, my contributions at Git are:

---------------
status: merged
git/git:
[Microproject]: Modernise tests and use helper functions in test script.
GitHub: https://github.com/git/git/commit/c513a958b69090c02ad422b0cd4622009bb4b9f5
List: https://lore.kernel.org/git/20200116203622.4694-1-shouryashukla.oo@gmail.com/


## The Project: Convert submodule to builtin

#### Outline

Git commands were initially implemented directly in shell script with some instances of Perl as well. As times progressed, various platforms to run Git emerged, _enter_, problems in production code. There were multiple problems with shell scripts, such as: large function call overhead for large projects and compatibility of code across platforms(e.g.: POSIX-to-Windows path conversion issues). To fix this issue, it was decided to convert these scripts into portable C code(the original intention C was developed with, to have portable code and software).

Various commands have been converted as of now, such as add, blame, bisect(work in progress), etc. In my project, I intend to convert submodule into C fully, hence making it a ‘builtin’. 


#### Previous Work

There has been an ongoing work in the conversion of various Git commands such as 'add', 'commit', 'blame', etc. from their shell form into their C form. 'git submodule' is one of the commands left to fully convert into its C form. Stefan Beller <stefanbeller@gmail.com> converted a large part of this command up until 2019. Prathamesh Chavan <pc44800@gmail.com> also aided in the conversion of the command during his GSoC project in the year 2017. In its current state, four subcommands are due for conversion, namely: 'add', 'set-branch', 'set-url' and 'summary'. Also, the Command Line parsing Interface needs improvements, such as better error messages and support for more subcommands.

Prathamesh implemented and improved the subcommands status[https://lore.kernel.org/git/20170713200538.25806-4-pc44800@gmail.com/], sync[https://lore.kernel.org/git/20180114211529.6391-2-pc44800@gmail.com/], deinit[https://lore.kernel.org/git/20180114211529.6391-3-pc44800@gmail.com/] and some more. The relevancy of this to my project is that some helper functions(located in submodule.c) such as print_submodule_summary(),prepare_submodule_summary(), etc. have been implemented beforehand. In the case of subcommand summary, use these functions, integrate them with the basic scaffolding(mentioned in the table below) and implement the module_summary() frontend function. He also ported various helper functions such as set_name_rev()[https://lore.kernel.org/git/20170619215025.10086-3-pc44800@gmail.com/]. He kept offering improvements to his conversions till around January of 2018.

Stefan Beller finished the implementation of the subcommand init[https://lore.kernel.org/git/1453418323-29587-1-git-send-email-sbeller@google.com/] as well as laid its foundation[https://lore.kernel.org/git/1453255396-31942-3-git-send-email-sbeller@google.com/]. He implemented foreach[https://lore.kernel.org/git/20180509002952.172347-5-sbeller@google.com/] and improved deinit[https://lore.kernel.org/git/20180327232824.112539-1-sbeller@google.com/] & update[https://lore.kernel.org/git/1444960333-16003-6-git-send-email-sbeller@google.com/] as well. He also ported various helper functions such as resolve_relative_url()[https://lore.kernel.org/git/1460767813-25916-2-git-send-email-sbeller@google.com/].


#### Current Status of the subcommand and future vision

The current status of the conversion as well as the direction I will take for the conversion of the subcommands are as follows:

	add: pending conversion, full code needs to be written for the same. Need to implement callback macros and structures, i.e. struct add_cb,
	     ADD_CB_INIT, as well as frontend function module_add(). Other helper functions may be needed in the process as well. Compare with shell 
	     script and try to “translate” it into C. I guesstimate around 400-500 lines of code for this(including helper functions).
	
	set-branch: pending conversion, full code needs to be written for the same. Need to implement macros and structures, i.e. struct setbranch,
		    SETBRANCH_CB_INIT, as well as frontend function module_setbranch(). Other helper functions(such as remote_submodule_branch() &
		    get_default_remote() which are already implemented may prove helpful later) may be needed in the process as well. Compare with shell
		    script and try to “translate” it into C. This subcommand may take about 200 lines of C code to implement(including helper functions).

 	set-url: pending conversion, full code needs to be written for the same. Need to implement macros and structures, i.e. struct seturl,
		 SETURL_CB_INIT, as well as frontend function module_seturl(). Other helper functions(such as remote_url() & resolve_resolve_url() which
		 are already implemented may prove helpful later) may be needed in the process as well. Compare with shell script and try to “translate” it
		 into C. It will have a similar implementation to set-branch because they are “setter” functions. This subcommand may take about 200 lines
		 of C code to implement(including helper functions).

	summary: pending conversion, work in progress; callback structures, functions and macros have been created, also, basic scaffolding of the command
		 is done, i.e., functions module_summary(), summary_submodule(), summary_submodule_cb(). As this is a prototype, some functions may be scrapped
		 or added later. Other functions to complement the subcommand have already been created; learn from Prathamesh's mistakes and implement a better code.
		 After discussions with Junio C Hamano[https://lore.kernel.org/git/20200318163234.21628-1-shouryashukla.oo@gmail.com/T/#ma3912b761b6deda937691a19c1a070e5e9b34bd7],
		 I intend to add a “--recursive” option as well for summary so as to obtain summaries of nested submodules as well.
		 I estimate about 400 lines of code for this subcommand(excluding the  “--recursive” option, yet including the helper functions)
	
	status: conversion complete, currently in a functional state.
	
	init: conversion complete, currently in a functional state.
	
	deinit: conversion complete, currently in a functional state.
	
	update: conversion complete, currently in a functional state.
	
	foreach: conversion complete, currently in a functional state.
	
	sync: conversion complete, currently in a functional state.
	
	absorbgitdirs: conversion complete, currently in a functional state.

I aim to follow the same approach as Stefan and Prathamesh as mentioned above. Though, there is about a 3 year gap between their work and mine, the model for porting seems to be consistent even if coding style may vary and might even give out improvements over previous implementations.


#### Contribution process and interaction with the mentors

I will keep committing changes on my GitHub fork[https://github.com/periperidip/git] and finally post a bundled patch on the Mailing List. I will make sure to keep interacting with the community as well as the mentors regularly. 	I aim to write weekly “progress report” blogs, which I will post on my website as well as the List. Apart from that, I will document anything new I learn as well as my journey in the GSoC program on my blogs and maybe as self-answered questions on StackOverflow with the aim that they will help me as well as others in case of reference.


#### Project Timeline

I have been studying the code of 'submodule.c', 'submodule--helper.c' and 'git-submodule.sh'
since the submission of my microproject. After studying the codes, I tried to devise an effective
conversion strategy for 'submodule'. I noticed that 'submodule.c' contains various helper functions
for 'submodule--helper.c' whereas the latter houses the main "converted" command as of now.
      
The subcommands ‘set-branch’ and ‘set-url’ will provide easy conversion due to the vast array of helper functions already available for them. Hence, I have coupled them with other commands and tasks such as the conversion of ‘add’ and improving CLI parsing.
In spite of the easiness of the aforementioned conversions, I have decided to convert ‘summary’ first because of the large variety of resources available for it as well as a direction of conversion available(as done by Prathamesh) which will aid me in learning from the mistakes committed before and thus help me offer an even more improved version of the subcommand.
Therefore, after all these considerations, the timeline looks like:	
  
  - Empty Period (Present - April 26)
    --> I am writing a paper(on the project[https://github.com/periperidip/UAV-based-wireless-networks-2] I have been working upon) for a conference which I have to finalise and submit by first week of April.
    --> My end-semester exams begin on April 23 hence I might be a bit busy before a week or so before the start date.
    --> I plan on starting the conversion of ‘summary’ in this period. Although, I am busy, I will try my best to implement a basic scaffolding and maybe
	even complete some good portion of the subcommand for the command and will keep my mentors posted regarding the same.
 
  - Community Bonding Period (April 27 - May 18)
    --> Get familiar with the community
    --> Improve the project workflow: make some timeline changes if necessary.
    --> Finish implementation of `summary` subcommand
    --> Update the Documentation

   
  - Phase 1 (May 19 - June 6)
    --> Convert 'set-url' subcommand
    --> Improve CLI parsing(give out better error messages)
    --> Update the Documentation
    --> Add appropriate tests for integration testing of ‘set-url’ and ‘summary’

    
  - Phase 2 (June 7- August 8)
    --> Convert 'add' subcommand
    --> Convert 'set-branch' subcommand
    --> Update the Documentation
    --> Add appropriate tests for integration testing of ‘add’ and ‘set-branch’ with the whole system

    
  - Final Phase (August 9 - August 17)
    --> Improve and add Documentation(if there is any still left)
    --> Apply final touch-ups to code

If there is some extra time left, I will try to implement some BONUS features.

**BONUS features:** Consist of command touch ups and improving some bugs such as code sections with 'NEEDSWORK' tags, improving the test files and maybe improve some previous implementations of helper functions.


## Workflow

I have divided the project into 3 subprojects(SP).

    1. **SP 1:** Convert 'summary'
    2. **SP 2:** Convert 'set-url' and and improve CLI(Command Line Interface) parsing   
    3. **SP 3:** Convert 'add' and 'set-branch'
    
After discussions with Christian Couder, I plan to start SP1 before GSoC itself. Currently,
I am studying the code in detail and constructing a scaffolding for this implementation.
I aim to complete the leftover bits of SP1 during Phase 1 and SP2 & SP3 during Phase 2 of
GSoC.

As Derrick Stolee advised[https://lore.kernel.org/git/nycvar.QRO 7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m232941f6cdcf92b97b3531f6fc582935c06734cf],
the conversion may not be possible in one whole summer, hence, I think an early start might be needed to finish things in time if possible.

As of now(March 21(UTC)), my progress is described by the following commit[https://github.com/periperidip/git/commit/db3604f653e02a90145abb56cffb2d4860ececa2].
I have implemented the frontend function(almost) module_summary(). I hope to increase my work speed once I get a hang of the inner working and coding style
of the command.


## Availability

The official GSoC period starts from April 27 and ends on August 17. My vacations start
from May 10 and will be over by July 13. I can easily devote 45-50 hours per week until
the commencement of my Semester. Other than this project, I have no commitments planned
for my vacations. I shall keep the community posted in case of any change in plans.


## Post GSoC

Even after the completion of Google Summer of Code, I plan on continuing my contributions
to Git, on the technical front(in terms of code and documentation contributions) as well
as on the social front(solving people's doubts/problems on the List as well as on StackOverflow).
I vision to convert the remaining of the commands as pointed out by Dscho[https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m637c5c97d42dc68aab85420b5ffcaeb34c270ad3]
as well as improve the test files.

I aim to develop mentorship skills as well as the ability to guide others and try to give back to
the community by mentoring and guiding others as well(by reviewing their code, helping them out, etc.)


## Final Remarks

I have a habit of not giving up. I will keep trying things until I succeed at them. Same was my case with learning to use Git in my freshman year. I was so scared of it for some reason that I refrained from using ‘git bash’. But I knew that I had to master this tool(or at least learn it to a satisfactory extent) because of the utility it has in a programmer’s life. I kept going, watching tons of tutorials, reading the documentation and articles and lo, here I am writing code for Git.

I hope that you give me the chance to showcase my abilities by considering my proposal for working with you during the summer of 2020. Really looking forward to learning from you :)


^ permalink raw reply	[relevance 4%]

* [GSoC][RFC][Proposal v3] Convert submodule to builtin
@ 2020-03-18 19:10  4% Shourya Shukla
  2020-03-24  8:21  4% ` Christian Couder
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-03-18 19:10 UTC (permalink / raw)
  To: git
  Cc: Johannes.Schindelin, christian.couder, peff, heba.waly, newren,
	Shourya Shukla

Hello everyone,

Thank you so much once again for reviewing my proposal v2 Christian! :)
Apologies for the late reply, I had been working on the conversion since and needed some concrete study for my proposal. This is the third draft of my GSoC Proposal. I have acted upon Christian's advice and reviews of my proposal.

Changes made:
	1. Corrected some of the links provided
	2. Renamed 'Relevant Work' to 'Workflow'
	3. Corrected grammatical errors and spelling mistakes
	4. Added more information about the conversion process as well as the current
	   state of the subcommands left to convert, along with a potential process and
	   direction of the conversion.

I think the proposal needs to be even more descriptive conversion process and direction, I will keep exploring the code even more and try to formulate an even better direction in the coming couple of days.

One thing I wanted to ask was that how do I foresee a good strategy and required helper functions
for the subcommands add, set-branch and set-url, as I am not working on them currently, hence I am
not able to exactly predict a path as of now. I can foresee a skeleton for these subcommands but
not a precise track for the same. :/

Also, a small report on my progress: I have created a scaffolding of the 'summary' subcommand as stated in this commit:
https://github.com/periperidip/git/commit/d33948dfc5d4c8faede9d3213adc3964557f33e1

I have progressed further than this commit and I will update the GitHub fork shortly. Currently, I am
studying other subcommands and trying to find a better direction for the code. I am also studying
Prathamesh Chavan's 2017 GSoC project and patches thoroughly.

PS: A prettier version of this proposal is on Docs, it is more readable than the plain-text version :)
Google Docs: https://docs.google.com/document/d/1vqu84h0E83BnNyuj19HkgoWsGYHsGgY2Jkc5kTB4fSs/edit?usp=sharing

PPS: I noticed that there are new subcommands in the 'submodule--helper.c' but they are not defined
in submodule's documentation. Will they be added after the full completion of the conversion?

Thanks,
Shourya

-x-x-x-x-x-x-x-x-x-x-x-x-x--x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x


# Convert submodule to builtin

## Contact Information
--------------------

Name          : Shourya Shukla
Major         : Computer Science and Engineering
E-mail        : shouryashukla.oo@gmail.com
IRC           : rasengan_chidori on #git & #git-devel
Mobile no     : <<mobile no>>
GitHub        : periperidip
Linkedin      : shuklashourya
StackOverflow : rasengan__
Address       : <<address>>
Time Zone     : IST (UTC +0530)


## Background

I am Shourya Shukla, a sophomore in Computer Science and Engineering at the Indian Institute of Technology Roorkee[https://www.iitr.ac.in/].
I was introduced to programming at a young age and I have been trying to learn new concepts everyday since. My
interests include modern mobile networks, Internet of Things and system software development. I have been working
on a research project[https://github.com/periperidip/UAV-based-wireless-networks-2] which involves providing cellular network
access to users in a disaster-struck area via drones. I love low-level coding and FLOSS as well. I have been an active part of
the Git community since January of this year, contributing to Git.


## Work Environment

I am fluent in C/C++, Java and Shell script, and have an understanding of Python
as well. I use Git as my VCS and Visual Studio Code with integrated GDB as my
primary code editor and Ubuntu 19.10 as my primary Operating System unless the
work specifically needs Windows.


## Contributions to Git

Contributing to Git helped me understand a lot about how modern & robust software
work as well as how real world development takes place. I plan on contributing even
more to Git and make my contributions count. As of now, my contributions at Git are:

---------------
status: merged
git/git:
[Microproject]: Modernise tests and use helper functions in test script.
GitHub: https://github.com/git/git/commit/c513a958b69090c02ad422b0cd4622009bb4b9f5
List: https://lore.kernel.org/git/20200116203622.4694-1-shouryashukla.oo@gmail.com/


## The Project: Convert submodule to builtin

#### Outline

Git commands were initially implemented directly in shell script with some instances of Perl as well. As times progressed, various platforms to run Git on emerged, _enter_, problems in production code. There were multiple problems with shell scripts, such as: compatibility of code across platforms(e.g.: POSIX-to-Windows path conversion issues). To fix this issue, it was decided to convert these scripts into portable C code(the original intention C was developed with, to have portable code and software).

Various commands have been converted as of now, such as add, blame, bisect(work in progress), etc. In my project, I intend to convert submodule into C fully, hence making it a ‘builtin’. 


#### Previous Work

There has been an ongoing work in the conversion of various Git commands such as 'add', 'commit', 'blame', etc. from their shell form into their C form. 'git submodule' is one of the commands left to fully convert into its C form. Stefan Beller <stefanbeller@gmail.com> converted a large part of this command up until 2019. Prathamesh Chavan <pc44800@gmail.com> also aided in the conversion of the command during his GSoC project in the year 2017. In its current state, four subcommands are due for conversion, namely: 'add', 'set-branch', 'set-url' and 'summary'. Also, the Command Line parsing Interface needs improvements, such as better error messages and support for more subcommands.

Prathamesh Chavan implemented and improved the subcommands summary, status, sync, deinit and some more. The relevancy of this to my project is that some helper functions(located in sbmodule.c) such as print_submodule_summary(),prepare_submodule_summary(), etc. have been implemented beforehand. In the case of subcommand summary, the work left is to stitch these functions together and implement the main module_summary() function. The current status of The conversion is:

	add: pending conversion, full code needs to be written for the same. Need to implement
	     callback macros and structures, i.e. struct add_cb(), ADD_CB_INIT, as well as frontend 		     function module_add(). Other helper functions may be needed in the process as well. 		     Compare with shell script and try to “translate” it into C.
	set-branch: pending conversion, full code needs to be written for the same. Need to implement 			    macros and structures, i.e. struct _setbranch(), SETBRANCH_CB_INIT, as well as 			    frontend function module_setbranch(). Other helper functions may be needed in the 			    process as well. Compare with shell script and try to “translate” it into C. 	set-url: pending conversion, full code needs to be written for the same. Need to implement 			macros and structures, i.e. struct _seturl(), SETURL_CB_INIT, as well as frontend 			function module_seturl(). Other helper functions may be needed in the process as 			well. Compare with shell script and try to “translate” it into C.Compare with shell 			script and try to “translate” it into C. It will have a similar implementation to 			set-branch because they are “setter” functions
	summary: pending conversion, work in progress; callback structures, functions and macros have
		 been created, also, basic scaffolding of the command is done, i.e., functions
		 module_summary(), summary_submodule(), summary_submodule_cb(). As this is a
		 prototype, some functions may be scrapped or added later. Other functions to
		 complement the subcommand have already been created; learn from Prathamesh's
		 mistakes and implement a better code.
	status: conversion complete, currently in a functional state.
	init: conversion complete, currently in a functional state.
	deinit: conversion complete, currently in a functional state.
	update: conversion complete, currently in a functional state.
	foreach: conversion complete, currently in a functional state.
	sync: conversion complete, currently in a functional state.
	absorbgitdirs: conversion complete, currently in a functional state.



I plan on working in a similar fashion by contributing changes to my GitHub handle as well as the refined versions to the List, so that my mentors are able to keep a track of my progress regularly. I plan to create a weekly blog for the same, but in case it is not possible, I will post weekly updates on the List.


#### Project Timeline

I have been studying the code of 'submodule.c', 'submodule--helper.c' and 'git-submodule.sh'
since the submission of my microproject. After studying the codes, I tried to devise an effective
conversion strategy for 'submodule'. I noticed that 'submodule.c' contains various helper functions
for 'submodule--helper.c' whereas the latter houses the main "converted" command as of now.
      
Therefore, the timeline looks like:	
  
  - Empty Period (Present - April 26)
    --> I am writing a paper(of the project I have been working upon) for a conference which I have to finalise and submit by first week of April.
    --> My end-semester exams begin on April 23 hence I might be a bit busy before a week or so before the start date.
    --> I plan on starting the conversion of ‘summary’ in this period. Although, I am busy, I will try my best to implement a basic scaffolding and maybe
	even complete some good portion of the subcommand for the command and will keep my mentors posted regarding the same.
 
  - Community Bonding Period (April 27 - May 18)
    --> Get familiar with the community
    --> Improve the project workflow: make some timeline changes if necessary.
    --> Finish implementation of `summary` subcommand
   
  - Phase 1 (May 19 - June 6)
    --> Convert 'set-url' subcommand
    --> Improve CLI parsing(give out better error messages)
    
  - Phase 2 (June 7- August 8)
    --> Convert 'add' subcommand
    --> Convert 'set-branch' subcommand
    
  - Final Phase (August 9 - August 17)
    --> Improve and add Documentation(if there is any still left)
    --> Apply final touch-ups to code

If there is some extra time left, I will try to implement some BONUS features.

**BONUS features:** Consist of command touch ups and improving some bugs such as code
                    sections with 'NEEDSWORK' tags.


## Workflow

I have divided the project into 3 subprojects(SP).

    1. **SP 1:** Convert 'summary'
    2. **SP 2:** Convert 'set-url' and and improve CLI(Command Line Interface) parsing   
    3. **SP 3:** Convert 'add' and 'set-branch'
    
After discussions with Christian Couder, I plan to start SP1 before GSoC itself. Currently,
I am studying the code in detail and constructing a scaffolding for this implementation.
I aim to complete the leftover bits of SP1 during Phase 1 and SP2 & SP3 during Phase 2 of
GSoC.

As Derrick Stolee advised[https://lore.kernel.org/git/nycvar.QRO 7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m232941f6cdcf92b97b3531f6fc582935c06734cf],
the conversion may not be possible in one whole summer, hence, I think an early start might be needed to finish things in time if possible.


## Availability

The official GSoC period starts from April 27 and ends on August 17. My vacations start
from May 10 and will be over by July 13. I can easily devote 45-50 hours per week until
the commencement of my Semester. Other than this project, I have no commitments planned
for my vacations. I shall keep the community posted in case of any change in plans.


## Post GSoC

Even after the completion of Google Summer of Code, I plan on continuing my contributions
to Git, on the technical front(in terms of code and documentation contributions) as well
as on the social front(solving people's doubts/problems on the List as well as on StackOverflow).
I vision to convert the remaining of the commands as pointed out by Dscho[https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m637c5c97d42dc68aab85420b5ffcaeb34c270ad3]
as well as improve the test files.

I aim to develop mentorship skills as well as the ability to guide others and try to give back to
the community by mentoring and guiding others as well(by reviewing their code, helping them out, etc.)


^ permalink raw reply	[relevance 4%]

* Re: [GSoC][RFC][Proposal v2] Convert submodule to builtin
  2020-03-09 13:10  5% [GSoC][RFC][Proposal v2] Convert submodule to builtin Shourya Shukla
@ 2020-03-11 21:27  3% ` Christian Couder
  0 siblings, 0 replies; 200+ results
From: Christian Couder @ 2020-03-11 21:27 UTC (permalink / raw)
  To: Shourya Shukla
  Cc: git, Johannes Schindelin, Jeff King, Heba Waly, Elijah Newren

Hi Shourya,

On Mon, Mar 9, 2020 at 2:10 PM Shourya Shukla
<shouryashukla.oo@gmail.com> wrote:

> Changes made:
>         1. Improve project timeline
>         2. Separate 'Overview' into 'Outline' and 'Previous work'
>         3. Corrected grammatical errors and spelling mistakes
>         4. Provided some links to relevant things asked for.

Thanks for the improvements!

> # Convert submodule to builtin
>
> ## Contact Information
> --------------------
>
> Name          : Shourya Shukla
> Major         : Computer Science and Engineering
> E-mail        : shouryashukla.oo@gmail.com
> IRC           : rasengan_chidori on #git & #git-devel
> Mobile no     : <<mobile no>>
> GitHub        : periperidip
> Linkedin      : shuklashourya
> StackOverflow : rasengan__
> Address       : <<address>>
> Time Zone     : IST (UTC +0530)
>
>
> ## Background
>
> I am Shourya Shukla, a sophomore in Computer Science and Engineering at the Indian Institute of Technology Roorkee[https://www.iitr.ac.in/].
> I was introduced to programming at a young age and I have been trying to learn new concepts everyday since. My
> interests include modern mobile networks, Internet of Things and system software development. I have been working
> on a research project[https://github.com/periperidip/UAV-based-wireless-networks-2] which involves providing cellular network
> access to users in a disaster-struck area via drones. I love low-level coding and FLOSS as well. I have been an active part of
> the Git community since January of this year, contributing to Git.

Ok.

> ## Work Envinronment

Maybe "Environment".

> I am fluent in C/C++, Java and Shell script, and have an understanding of Python
> as well. I use Git as my VCS and Visual Studio Code with integrated GDB as my
> primary code editor and Ubuntu 19.10 as my primary Operating System unless the
> work specifically needs Windows.
>
>
> ## Contributions to Git
>
> Contributing to Git helped me understand a lot about how modern & robust software
> work as well as how real world development takes place. I plan on contributing even
> more to Git and make my contributions count. As of now, my contributions at Git are:
>
> ---------------
> status: merged
> git/git:
> [Microproject]: Modernise tests and use helper functions in test script.
> GitHub: https://github.com/git/git/commit/c513a958b69090c02ad422b0cd4622009bb4b9f5
> List: https://github.com/git/git/commit/c513a958b69090c02ad422b0cd4622009bb4b9f5

Both links are the same.

> ## The Project: Convert submodule to builtin
>
> #### Outline
>
> Git was initially implemented directly in shell script with some instances of Perl as well.

Do you talk about the `git submodule` command here? In Git there has
been a lot of C code since the beginning.

> As times progressed,
> various platforms to run Git on emerged, _enter_, problems in production code. There were multiple problems with
> compatibility of code across platforms(e.g.: POSIX-to-Windows path conversion issues). To fix this issue, it was
> decided to convert these scripts into portable C code(the original intention C was developed with, to have portable
> code and software).

Platform portability is only one of the reasons why some commands have
been ported.

> Various commands have been converted as of now, such as add, blame, bisect(work in progress), etc. In my project,
> I intend to convert submodule into C fully, hence making it a ‘builtin’.
>
>
> #### Previous Work
>
> There has been an ongoing work in the conversion of various Git commands such as 'add', 'commit', 'blame', etc. from
> their shell form into their C form. 'git submodule' is one of the commands left to fully convert into its C form.
> Stefan Beller <stefanbeller@gmail.com> converted a large part of this command up until 2019. Prathamesh Chavan <pc44800@gmail.com>
> also aided in the conversion of the command during his GSoC project in the year 2017. In its current state, four subcommands are
> due for conversion, namely: 'add', 'set-branch', 'set-url' and 'summary'. Also, the Command Line parsing Interface needs improvements,
> such as better error messages and support for more subcommands.
>
> Prathamesh Chavan implemented and improved the subcommands summary, status, sync, deinit and some more. The relevancy of this to my project
> is that some helper functions(located in submodule.c) such as print_submodule_summary(),prepare_submodule_summary(), etc. have been implemented
> beforehand. In the case of subcommand summary, the work left is to stitch these functions together and implement the main module_summary()
> function.

It is not very clear which subcommands have been fully converted into
C. Could you list all the subcommands and tell for each one what work
is left to do if any.

> I plan on working in a similar fashion by contributing changes to my GitHub handle as well as the refined versions to the List,
> so that my mentors are able to keep a track of my progress regularly.

Ok, do you plan to have a weekly updated blog or to just send weekly
email updates to the mailing list?

> #### Project Timeline
>
> I have been studying the code of 'submodule.c', 'submodule--helper.c' and 'git-submodule.sh'
> since the submission of my microproject. After studying the codes, I tried to devise an effective
> conversion strategy for 'submodule'. I noticed that 'submodule.c' contains various helper functions
> for 'submodule--helper.c' whereas the latter houses the main "converted" command as of now.
>
> Therefore, the timeline looks like:
>
>   - Empty Period (Present - April 26)
>     --> I am writing a paper(of the project I have been working upon) for a conference which I have to finalise and submit by first week of April.

You mean the UAV project, right?

>     --> My end-semester exams begin on April 23 hence I might be a bit busy before a week or so before the start date.
>     --> I plan on starting the conversion of ‘summary’ in this period. Although, I am busy, I will try my best to implement
>         a basic scaffolding  and maybe even complete some good portion of the subcommand for the command and will keep my
>         mentors posted regarding the same.

You wrote above that Prathamesh Chavan already worked on the ‘summary’
subcommand, so this would be about starting to finish it, right? Which
good portion you think you could complete?

>   - Community Bonding Period (April 27 - May 18)
>     --> Get familiar with the community
>     --> Improve the project workflow: make some timeline changes if necessary.
>     --> Finish implementation of `summary` subcommand
>
>   - Phase 1 (May 19 - June 6)
>     --> Convert 'set-url' subcommand
>     --> Improve CLI parsing

Do you mean implementing better error messages in CLI parsing?

>   - Phase 2 (June 7- August 8)
>     --> Convert 'add' subcommand
>     --> Convert 'set-branch' subcommand
>
>   - Final Phase (August 9 - August 17)
>     --> Improve and add Documentation(if there is any still left)
>     --> Apply final touch-ups to code
>
> If there is some extra time left, I will try to implement some BONUS features.
>
> **BONUS features:** Consist of command touch ups and improving some bugs such as code
>                     sections with 'NEEDSWORK' tags.
>
>
> ## Relevant Work
>
> I have divided the project into 3 subprojects(SP).
>
>     1. **SP 1:** Convert 'summary'
>     2. **SP 2:** Convert 'set-url' and and improve CLI(Command Line Interface) parsing
>     3. **SP 3:** Convert 'add' and 'set-branch'

I am not sure that the above adds much information to what is in the
previous section (Project Timeline). At least I think you might want
to rename "Relevant Work" to something like "Subprojects".

> After discussions with Christian Couder, I plan to start SP1 before GSoC itself. Currently,
> I am studying the code in detail and constructing a scaffolding for this implementation.
> I aim to complete the leftover bits of SP1 during Phase 1 and SP2 & SP3 during Phase 2 of
> GSoC.
>
> As Derrick Stolee advised[https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m232941f6cdcf92b97b3531f6fc582935c06734cf],
> the conversion may not be possible in one whole summer, hence, I think an early start might be needed to finish things in time if possible.
>
>
> ## Availability
>
> The official GSoC period starts from April 27 and ends on August 17. My vacations start
> from May 10 and will be over by July 13. I can easily devote 45-50 hours per week until
> the commencement of my Semester. Other than this project, I have no commitments planned
> for my vacations. I shall keep the community posted in case of any change in plans.
>
>
> ## Post GSoC
>
> Even after the completion of Google Summer of Code, I plan on continuing my contributions
> to Git, on the technical front(in terms of code and documentation contributions) as well
> as on the social front(solving people's doubts/problems on the List as well as on StackOverflow).
> I vision to convert the remaining of the commands as pointed out by Dscho[https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m637c5c97d42dc68aab85420b5ffcaeb34c270ad3]
> as well as improve the test files.
>
> I aim to develop mentorship skills as well as the ability to guide others and try to give back to
> the community by mentoring and guiding others as well(by reviewing their code, helping them out, etc.)

Ok.

I think it might be interesting to add a bit more information about
what should be done to implement the 'set-url', 'add' and 'set-branch'
subcommands.

Thanks,
Christian.

^ permalink raw reply	[relevance 3%]

* [GSoC][RFC][Proposal v2] Convert submodule to builtin
@ 2020-03-09 13:10  5% Shourya Shukla
  2020-03-11 21:27  3% ` Christian Couder
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-03-09 13:10 UTC (permalink / raw)
  To: git
  Cc: Johannes.Schindelin, christian.couder, peff, heba.waly, newren,
	Shourya Shukla

Hello everyone,

Thank you so much for reviewing my proposal Christian! :)
Apologies for the late reply, I was busty with exams for the past 10 days. This is the second
draft of my GSoC Proposal. I have acted upon Christian's advice and reviews of my proposal.

Changes made:
	1. Improve project timeline
	2. Separate 'Overview' into 'Outline' and 'Previous work'
	3. Corrected grammatical errors and spelling mistakes
	4. Provided some links to relevant things asked for.

Google Docs: https://docs.google.com/document/d/1vqu84h0E83BnNyuj19HkgoWsGYHsGgY2Jkc5kTB4fSs/edit?usp=sharing

Thanks,
Shourya

-x-x-x-x-x-x-x-x-x-x-x-x-x--x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x


# Convert submodule to builtin

## Contact Information
--------------------

Name          : Shourya Shukla
Major         : Computer Science and Engineering
E-mail        : shouryashukla.oo@gmail.com
IRC           : rasengan_chidori on #git & #git-devel
Mobile no     : <<mobile no>>
GitHub        : periperidip
Linkedin      : shuklashourya
StackOverflow : rasengan__
Address       : <<address>>
Time Zone     : IST (UTC +0530)


## Background

I am Shourya Shukla, a sophomore in Computer Science and Engineering at the Indian Institute of Technology Roorkee[https://www.iitr.ac.in/].
I was introduced to programming at a young age and I have been trying to learn new concepts everyday since. My
interests include modern mobile networks, Internet of Things and system software development. I have been working
on a research project[https://github.com/periperidip/UAV-based-wireless-networks-2] which involves providing cellular network
access to users in a disaster-struck area via drones. I love low-level coding and FLOSS as well. I have been an active part of
the Git community since January of this year, contributing to Git.


## Work Envinronment

I am fluent in C/C++, Java and Shell script, and have an understanding of Python
as well. I use Git as my VCS and Visual Studio Code with integrated GDB as my
primary code editor and Ubuntu 19.10 as my primary Operating System unless the
work specifically needs Windows.


## Contributions to Git

Contributing to Git helped me understand a lot about how modern & robust software
work as well as how real world development takes place. I plan on contributing even
more to Git and make my contributions count. As of now, my contributions at Git are:

---------------
status: merged
git/git:
[Microproject]: Modernise tests and use helper functions in test script.
GitHub: https://github.com/git/git/commit/c513a958b69090c02ad422b0cd4622009bb4b9f5
List: https://github.com/git/git/commit/c513a958b69090c02ad422b0cd4622009bb4b9f5


## The Project: Convert submodule to builtin

#### Outline

Git was initially implemented directly in shell script with some instances of Perl as well. As times progressed,
various platforms to run Git on emerged, _enter_, problems in production code. There were multiple problems with
compatibility of code across platforms(e.g.: POSIX-to-Windows path conversion issues). To fix this issue, it was
decided to convert these scripts into portable C code(the original intention C was developed with, to have portable
code and software).

Various commands have been converted as of now, such as add, blame, bisect(work in progress), etc. In my project,
I intend to convert submodule into C fully, hence making it a ‘builtin’. 


#### Previous Work

There has been an ongoing work in the conversion of various Git commands such as 'add', 'commit', 'blame', etc. from
their shell form into their C form. 'git submodule' is one of the commands left to fully convert into its C form.
Stefan Beller <stefanbeller@gmail.com> converted a large part of this command up until 2019. Prathamesh Chavan <pc44800@gmail.com>
also aided in the conversion of the command during his GSoC project in the year 2017. In its current state, four subcommands are
due for conversion, namely: 'add', 'set-branch', 'set-url' and 'summary'. Also, the Command Line parsing Interface needs improvements,
such as better error messages and support for more subcommands.

Prathamesh Chavan implemented and improved the subcommands summary, status, sync, deinit and some more. The relevancy of this to my project
is that some helper functions(located in submodule.c) such as print_submodule_summary(),prepare_submodule_summary(), etc. have been implemented
beforehand. In the case of subcommand summary, the work left is to stitch these functions together and implement the main module_summary()
function. I plan on working in a similar fashion by contributing changes to my GitHub handle as well as the refined versions to the List,
so that my mentors are able to keep a track of my progress regularly.

#### Project Timeline

I have been studying the code of 'submodule.c', 'submodule--helper.c' and 'git-submodule.sh'
since the submission of my microproject. After studying the codes, I tried to devise an effective
conversion strategy for 'submodule'. I noticed that 'submodule.c' contains various helper functions
for 'submodule--helper.c' whereas the latter houses the main "converted" command as of now.
      
Therefore, the timeline looks like:	
  
  - Empty Period (Present - April 26)
    --> I am writing a paper(of the project I have been working upon) for a conference which I have to finalise and submit by first week of April.
    --> My end-semester exams begin on April 23 hence I might be a bit busy before a week or so before the start date.
    --> I plan on starting the conversion of ‘summary’ in this period. Although, I am busy, I will try my best to implement
        a basic scaffolding  and maybe even complete some good portion of the subcommand for the command and will keep my
        mentors posted regarding the same.
 
  - Community Bonding Period (April 27 - May 18)
    --> Get familiar with the community
    --> Improve the project workflow: make some timeline changes if necessary.
    --> Finish implementation of `summary` subcommand
   
  - Phase 1 (May 19 - June 6)
    --> Convert 'set-url' subcommand
    --> Improve CLI parsing
    
  - Phase 2 (June 7- August 8)
    --> Convert 'add' subcommand
    --> Convert 'set-branch' subcommand
    
  - Final Phase (August 9 - August 17)
    --> Improve and add Documentation(if there is any still left)
    --> Apply final touch-ups to code

If there is some extra time left, I will try to implement some BONUS features.

**BONUS features:** Consist of command touch ups and improving some bugs such as code
                    sections with 'NEEDSWORK' tags.


## Relevant Work

I have divided the project into 3 subprojects(SP).

    1. **SP 1:** Convert 'summary'
    2. **SP 2:** Convert 'set-url' and and improve CLI(Command Line Interface) parsing   
    3. **SP 3:** Convert 'add' and 'set-branch'
    
After discussions with Christian Couder, I plan to start SP1 before GSoC itself. Currently,
I am studying the code in detail and constructing a scaffolding for this implementation.
I aim to complete the leftover bits of SP1 during Phase 1 and SP2 & SP3 during Phase 2 of
GSoC.

As Derrick Stolee advised[https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m232941f6cdcf92b97b3531f6fc582935c06734cf],
the conversion may not be possible in one whole summer, hence, I think an early start might be needed to finish things in time if possible.


## Availability

The official GSoC period starts from April 27 and ends on August 17. My vacations start
from May 10 and will be over by July 13. I can easily devote 45-50 hours per week until
the commencement of my Semester. Other than this project, I have no commitments planned
for my vacations. I shall keep the community posted in case of any change in plans.


## Post GSoC

Even after the completion of Google Summer of Code, I plan on continuing my contributions
to Git, on the technical front(in terms of code and documentation contributions) as well
as on the social front(solving people's doubts/problems on the List as well as on StackOverflow).
I vision to convert the remaining of the commands as pointed out by Dscho[https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m637c5c97d42dc68aab85420b5ffcaeb34c270ad3]
as well as improve the test files.

I aim to develop mentorship skills as well as the ability to guide others and try to give back to
the community by mentoring and guiding others as well(by reviewing their code, helping them out, etc.)


^ permalink raw reply	[relevance 5%]

* Re: [GSoC][RFC] Proposal: Convert scripts to builtins
  2020-02-25 19:45  4% [GSoC][RFC] Proposal: Convert scripts to builtins Shourya Shukla
@ 2020-03-02 13:32  0% ` Christian Couder
  0 siblings, 0 replies; 200+ results
From: Christian Couder @ 2020-03-02 13:32 UTC (permalink / raw)
  To: Shourya Shukla
  Cc: git, Johannes Schindelin, Jeff King, Elijah Newren,
	Derrick Stolee, Heba Waly

Hi Shourya,

On Tue, Feb 25, 2020 at 8:45 PM Shourya Shukla
<shouryashukla.oo@gmail.com> wrote:
>
> I am Shourya, and this is the first draft of my proposal for the project titled:
> 'Convert scripts to builtins'. I need your feedback and more than that I need help
> to improve my project timeline.
> Specifically, I'd like your thoughts on the early commencement of the project and
> how should I adjust the timeline accordingly. Any guidance the Community can provide
> is greatly appreciated :)

Thank you or your proposal and sorry for the late answer!

> # Convert scripts to builtins
>
> ## Contact Information
> --------------------

[...]

> ## Background
>
> I am Shourya Shukla, a sophomore in Computer Science and Engineering at the
> Indian Institute of Technology Roorkee[1]. I was introduced to programming at
> a young age and I have been trying to learn new concepts everyday since. My
> interests include modern mobile networks, Internet of Things and system software
> development. I have been working on a project which involves providing cellular
> network access to users in a disaster-struck are via drones. I love low-level

I think you mean "disaster-struck area".

Do you have a link to the project you have been contributing to?

> coding and FLOSS as well. I have been an active part of the Git community since
> January of this year, contributing to Git.

Ok.

> ## Work Envinronment
>
> I am fluent in C/C++, Java and Shell script, and have an understanding of Python
> as well. I use Git as my VCS and Visual Studio Code with integrated GDB as my
> primary code editor and Ubuntu 19.10 as my primary Operating System unless the
> work specifically needs Windows.

Ok.

> ## Contributions to Git
>
> Contributing to Git helped me understand a lot about how modern & robust softwares

Maybe "software".

> work as well as how real world development takes place. I plan on contrubuting even

Maybe "contributing".

> more to Git and make my contributions count. As of now, my contributions at Git are:
>
> ---------------
> status: merged
> git/git:
> [Microproject][2]: Modernise tests and use helper functions in test script.

I think it would be better if you also provided a link to the commits
that were merged, or the tip of the branch that was merged, on GitHub
or GitLab. Also I prefer when the links are not at then end of the
document but rather part of the text.

> ## The Project: 'Convert scripts to builtins'

I think the project name should specify the script(s) that you want to
convert. Mentors might be more interested in one script being
converted than another and it's better if they don't have to look
inside your proposal.

> #### Overview
>
> There has been an ongoing work in the conversion of various Git commands
> such as `add`, `commit`, `blame`, etc. from their shell form into their C form.
> `git submodule` is one of the commands left to fully convert into its C form.
> Stefan Beller <stefanbeller@gmail.com> converted a large part of this command
> up until 2019. Prathamesh Chavan <pc44800@gmail.com> also aided in the conversion
> of the command during his GSoC project in the year 2017. In its current state, four
> subcommands are due for conversion, namely: 'add`, `set-branch`, `set-url` and `summary`.
> Also, the Command Line parsing Interface needs improvements, such as better error messages
> and support for more subcommands.

I hoped that what you mention here was detailed below, but it looks
like it isn't. It's important to show that you studied what happened
before. And that you can take advantage of it. For example maybe they
started working at porting other commands but didn't finish and you
could take advantage of their work.

You could perhaps add links to their repos and the patch series they
sent that were merged and possibly those that weren't merged too.

I would use "Previous work" rather than "Overview" as the title for
this section.

> #### Project Timeline
>
> I have been studying the code of `submodule.c`, `submodule--helper.c` and `git-submodule.sh`
> since the submission of my microproject. After studying the codes, I tried to devise an effective
> conversion strategy for `submodule`. I noticed that `submodule.c` contains various helper functions
> for `submodule--helper.c` whereas the latter houses the main "converted" command as of now.
>
> Therefore, the timeline looks like:
>
>   - Community Bonding Period (April 27 - May 18)
>     --> Get familiar with the community
>     --> Improve the project workflow

I'd like more details about this.

>   - Phase 1 (May 19 - June 6)
>     --> Convert `summary` subcommand
>     --> Improve CLI parsing
>
>   - Phase 2 (June 7- August 8)
>     --> Convert `add` subcommand
>     --> Convert `set-url` subcommand
>     --> Convert `set-branch` subcommand

You could add a bit more information, like an estimate of the number
of line of shell you will convert at each step.

>   - Final Phase (August 9 - August 17)
>     --> Documentation
>     --> Final touch-ups to code

Documentation should be part of the previous phases. Also we like to
be updated (either via a blog or emails to the mailing list) during
the course of the project, not just at the end.

> If there is some extra time left, I will try to implement some BONUS features.
>
> **BONUS features:** Consist of command touch ups and improcing some bugs such as code

Maybe "improving on".

>                     sections with 'NEEDSWORK' tags.
>
>
> ## Relevant Work
>
> I have divided the project into 3 subprojects(SP).
>
>     1. **SP 1:** Convert `summary`
>     2. **SP 2:** Convert `add` and improve CLI(Command Line Interface) parsing
>     3. **SP 3:** Convert `set-url` and `set-branch`
>
> After discussions with Christian Couder, I plan to start SP1 before GSoC itself. Currently,
> I am studying the code in detail and constructing a scaffolding for this implementation.
> I aim to complete the leftover bits of SP1 during Phase 1 and SP2 & SP3 during Phase 2 of
> GSoC.

Ok.

> As Derrick Stolee advised[3], the conversion may not be possible in one whole summer, hence,
> I think an early start might be needed to finish things in time if possible.

Yeah, probably.

> ## Availability
>
> The official GSoC period starts from April 27 and ends on August 17. My vacations start
> from May 10 and will be over by July 13. I can easily devote 45-50 hours per week until
> the commencement of my Semester. Other than this project, I have no commitments planned
> for my vacations. I shall keep the community posted in case of any change in plans.

Ok.

> ## Post GSoC
>
> Even after the completion of Google Summer of Code, I plan on continuing my contributions
> to Git, on the technical front(in terms of code and documentation contributions) as well
> as on the social front(solving people's doubts/problems on the List as well as on StackOverflow).
> I vision to convert the remaining of the commands as pointed out by Dscho[3] as well as improve
> the test files.
>
> I aim to develop mentorship skills as well as the ability to guide others and try to give back to
> the community by mentoring and guiding others as well(by reviewing their code, helping them out, etc.)

Great!

Thanks,
Christian.

^ permalink raw reply	[relevance 0%]

* [GSoC][RFC] Proposal: Convert scripts to builtins
@ 2020-02-25 19:45  4% Shourya Shukla
  2020-03-02 13:32  0% ` Christian Couder
  0 siblings, 1 reply; 200+ results
From: Shourya Shukla @ 2020-02-25 19:45 UTC (permalink / raw)
  To: git
  Cc: Johannes.Schindelin, christian.couder, peff, newren, stolee,
	Shourya Shukla

Hello everyone,

I am Shourya, and this is the first draft of my proposal for the project titled:
'Convert scripts to builtins'. I need your feedback and more than that I need help
to improve my project timeline.
Specifically, I'd like your thoughts on the early commencement of the project and
how should I adjust the timeline accordingly. Any guidance the Community can provide
is greatly appreciated :)

Thanks,
Shourya

-x-x-x-x-x-x-x-x-x-x-x-x-x--x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x


# Convert scripts to builtins

## Contact Information
--------------------

Name          : Shourya Shukla
Major         : Computer Science and Engineering
E-mail        : shouryashukla.oo@gmail.com
IRC           : rasengan_chidori on #git & #git-devel
Mobile no     : <<mobile no>>
GitHub        : periperidip
Linkedin      : shuklashourya
StackOverflow : rasengan__
Address       : <<address>>
Time Zone     : IST (UTC +0530)


## Background

I am Shourya Shukla, a sophomore in Computer Science and Engineering at the
Indian Institute of Technology Roorkee[1]. I was introduced to programming at
a young age and I have been trying to learn new concepts everyday since. My
interests include modern mobile networks, Internet of Things and system software
development. I have been working on a project which involves providing cellular
network access to users in a disaster-struck are via drones. I love low-level
coding and FLOSS as well. I have been an active part of the Git community since
January of this year, contributing to Git.


## Work Envinronment

I am fluent in C/C++, Java and Shell script, and have an understanding of Python
as well. I use Git as my VCS and Visual Studio Code with integrated GDB as my
primary code editor and Ubuntu 19.10 as my primary Operating System unless the
work specifically needs Windows.


## Contributions to Git

Contributing to Git helped me understand a lot about how modern & robust softwares
work as well as how real world development takes place. I plan on contrubuting even
more to Git and make my contributions count. As of now, my contributions at Git are:

---------------
status: merged
git/git:
[Microproject][2]: Modernise tests and use helper functions in test script.


## The Project: 'Convert scripts to builtins'

#### Overview

There has been an ongoing work in the conversion of various Git commands
such as `add`, `commit`, `blame`, etc. from their shell form into their C form.
`git submodule` is one of the commands left to fully convert into its C form.
Stefan Beller <stefanbeller@gmail.com> converted a large part of this command
up until 2019. Prathamesh Chavan <pc44800@gmail.com> also aided in the conversion
of the command during his GSoC project in the year 2017. In its current state, four
subcommands are due for conversion, namely: 'add`, `set-branch`, `set-url` and `summary`.
Also, the Command Line parsing Interface needs improvements, such as better error messages
and support for more subcommands.


#### Project Timeline

I have been studying the code of `submodule.c`, `submodule--helper.c` and `git-submodule.sh`
since the submission of my microproject. After studying the codes, I tried to devise an effective
conversion strategy for `submodule`. I noticed that `submodule.c` contains various helper functions
for `submodule--helper.c` whereas the latter houses the main "converted" command as of now.
      
Therefore, the timeline looks like:
  
  - Community Bonding Period (April 27 - May 18)
    --> Get familiar with the community
    --> Improve the project workflow
   
  - Phase 1 (May 19 - June 6)
    --> Convert `summary` subcommand
    --> Improve CLI parsing
    
  - Phase 2 (June 7- August 8)
    --> Convert `add` subcommand
    --> Convert `set-url` subcommand
    --> Convert `set-branch` subcommand
    
  - Final Phase (August 9 - August 17)
    --> Documentation
    --> Final touch-ups to code

If there is some extra time left, I will try to implement some BONUS features.

**BONUS features:** Consist of command touch ups and improcing some bugs such as code
                    sections with 'NEEDSWORK' tags.


## Relevant Work

I have divided the project into 3 subprojects(SP).

    1. **SP 1:** Convert `summary`
    2. **SP 2:** Convert `add` and improve CLI(Command Line Interface) parsing        
    3. **SP 3:** Convert `set-url` and `set-branch`
    
After discussions with Christian Couder, I plan to start SP1 before GSoC itself. Currently,
I am studying the code in detail and constructing a scaffolding for this implementation.
I aim to complete the leftover bits of SP1 during Phase 1 and SP2 & SP3 during Phase 2 of
GSoC.

As Derrick Stolee advised[3], the conversion may not be possible in one whole summer, hence,
I think an early start might be needed to finish things in time if possible.


## Availability

The official GSoC period starts from April 27 and ends on August 17. My vacations start
from May 10 and will be over by July 13. I can easily devote 45-50 hours per week until
the commencement of my Semester. Other than this project, I have no commitments planned
for my vacations. I shall keep the community posted in case of any change in plans.


## Post GSoC

Even after the completion of Google Summer of Code, I plan on continuing my contributions
to Git, on the technical front(in terms of code and documentation contributions) as well
as on the social front(solving people's doubts/problems on the List as well as on StackOverflow).
I vision to convert the remaining of the commands as pointed out by Dscho[3] as well as improve
the test files.

I aim to develop mentorship skills as well as the ability to guide others and try to give back to
the community by mentoring and guiding others as well(by reviewing their code, helping them out, etc.)

------------------------------------------------------------------------------------------------
[1]: https://www.iitr.ac.in/
[2]: https://lore.kernel.org/git/20200116203622.4694-1-shouryashukla.oo@gmail.com/
[3]: https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m232941f6cdcf92b97b3531f6fc582935c06734cf
[4]: https://lore.kernel.org/git/nycvar.QRO.7.76.6.2001301154170.46@tvgsbejvaqbjf.bet/T/#m637c5c97d42dc68aab85420b5ffcaeb34c270ad3

^ permalink raw reply	[relevance 4%]

* Re: Converting scripted commands to built-ins, was Re: [GSoC] Exploring Previous year Projects
  2020-01-31  9:32  2%       ` Johannes Schindelin
@ 2020-01-31  9:57  0%         ` Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2020-01-31  9:57 UTC (permalink / raw)
  To: Derrick Stolee
  Cc: Jakub Narebski, Shourya Shukla, christian.couder, t.gummerer, git,
	gitster

Hi again,

On Fri, 31 Jan 2020, Johannes Schindelin wrote:

> On Thu, 30 Jan 2020, Derrick Stolee wrote:
>
> > On 1/30/2020 6:10 AM, Johannes Schindelin wrote:
> > > Large parts of `git submodule` are already implemented in `git
> > > submodule--helper`, so that's a head start (thanks Stephan Beller!).
> > >
> > > [...]
> > >
> > > Realistically, I think that it would be possible for a GSoC student
> > > who is already very familiar with the code base and with submodules to
> > > finish the conversion of `git submodule` in one season.
> >
> > Even assuming the most generous definition of "very familiar" I'm not sure
> > this is the case. But I also don't meet the bar of "very familiar" when it
> > comes to the submodule code.
>
> Hmm. I guess you're right, and it actually matches my earlier assessment:
> https://lore.kernel.org/git/nycvar.QRO.7.76.6.1904031957480.41@tvgsbejvaqbjf.bet/

I vaguely remembered that I had described this project in a lot more
detail in a Git for Windows ticket, and I just spent a couple of minutes
to coagulate it into a more concrete proposal here:
https://github.com/gitgitgadget/git/issues/541

Ciao,
Dscho

^ permalink raw reply	[relevance 0%]

* Re: Converting scripted commands to built-ins, was Re: [GSoC] Exploring Previous year Projects
  2020-01-30 15:14  2%     ` Derrick Stolee
@ 2020-01-31  9:32  2%       ` Johannes Schindelin
  2020-01-31  9:57  0%         ` Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Johannes Schindelin @ 2020-01-31  9:32 UTC (permalink / raw)
  To: Derrick Stolee
  Cc: Jakub Narebski, Shourya Shukla, christian.couder, t.gummerer, git,
	gitster

Hi Stolee,

On Thu, 30 Jan 2020, Derrick Stolee wrote:

> On 1/30/2020 6:10 AM, Johannes Schindelin wrote:
> > Large parts of `git submodule` are already implemented in `git
> > submodule--helper`, so that's a head start (thanks Stephan Beller!).
>
> As I recall, a bit part of what prevented more going into submodule--helper
> was isolating the_repository and allowing multiple repositories in-memory
> at once. That effort has stalled since Stephan has moved to other things.
> (I will also admit that perhaps I am wrong: is it complete, rather than
> stalled?)

There was definitely a push toward using `the_repository` in more places,
essentially making the entire code base a bit more object-oriented. My
impression is that this effort has largely stalled since Stephan and Duy
moved to other things.

However, this push is not exactly necessary to make `git submodule` a
built-in, much like `git push` can be a built-in even if it has to work on
two different repositories when run locally: it simply spawns a `git
receive-pack` in the repository to push to, rather than handling two
repositories in the same memory space.

The same is true for `git submodule`, of course: it can very easily spawn
processes for all the submodules. And that's what the `submodule--helper`
already does ;-)

> I would be happy to see more progress in this area, and it could be a
> good way to get familiar with the codebase and submitting patches.

I am of two minds here. On the one hand, I am eager to get rid of issues
such as https://github.com/git-for-windows/git/issues/1661, i.e. issues
that are solely due to Git requiring a Unix shell interpreter to run some
subcommands.

On the other hand... it is well known, I believe, what I think of
the design of Git's submodules feature. Putting an effort into making them
easier to use will not change this design.

In my mind, it would make more sense to focus on making partial clone and
sparse checkout a thing, and then combine it with a built-in version of
`git subtree` to include dependencies' commit history. Yes, I do suspect
that git-subtrac is going the wrong direction from git-subtree.

> > Realistically, I think that it would be possible for a GSoC student
> > who is already very familiar with the code base and with submodules to
> > finish the conversion of `git submodule` in one season.
>
> Even assuming the most generous definition of "very familiar" I'm not sure
> this is the case. But I also don't meet the bar of "very familiar" when it
> comes to the submodule code.

Hmm. I guess you're right, and it actually matches my earlier assessment:
https://lore.kernel.org/git/nycvar.QRO.7.76.6.1904031957480.41@tvgsbejvaqbjf.bet/

While it would be more satisfying for a prolific student to "complete" the
conversion in 3 months, it does not _have_ to be rushed that way. There
are tons of things to learn along the way, which is also part of GSoC's
mission.

The good news is that it is not an all-or-nothing project. Just like the
conversion of `git rebase` to C, which took several years, and the effort
of several contributors (implementing merge-recursive in C, then the
sequencer, then letting most of `rebase -i` be performed by the sequencer,
then the built-in `git am`, then the two GSoC projects to convert `git
rebase` and `git rebase -i`, extracting and deprecating `rebase -p` and of
course implementing the replacement for it: `rebase -r`), `git submodule`
_can_ and should be converted incrementally.

> So, I'm sending this message just to say "DRAGONS BE HERE" and recommend
> taking on a smaller project.

I can get behind that pretty good advice ;-)

Thanks for weighing in,
Dscho

^ permalink raw reply	[relevance 2%]

* Re: Converting scripted commands to built-ins, was Re: [GSoC] Exploring Previous year Projects
  2020-01-30 11:10  5%   ` Converting scripted commands to built-ins, was " Johannes Schindelin
@ 2020-01-30 15:14  2%     ` Derrick Stolee
  2020-01-31  9:32  2%       ` Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Derrick Stolee @ 2020-01-30 15:14 UTC (permalink / raw)
  To: Johannes Schindelin, Jakub Narebski
  Cc: Shourya Shukla, christian.couder, t.gummerer, git, gitster

On 1/30/2020 6:10 AM, Johannes Schindelin wrote:
> Large parts of `git submodule` are already implemented in `git
> submodule--helper`, so that's a head start (thanks Stephan Beller!).

As I recall, a bit part of what prevented more going into submodule--helper
was isolating the_repository and allowing multiple repositories in-memory
at once. That effort has stalled since Stephan has moved to other things.
(I will also admit that perhaps I am wrong: is it complete, rather than
stalled?)

I would be happy to see more progress in this area, and it could be a good
way to get familiar with the codebase and submitting patches.

> Realistically, I think that it would be possible for a GSoC student who is
> already very familiar with the code base and with submodules to finish the
> conversion of `git submodule` in one season.

Even assuming the most generous definition of "very familiar" I'm not sure
this is the case. But I also don't meet the bar of "very familiar" when it
comes to the submodule code.
 
So, I'm sending this message just to say "DRAGONS BE HERE" and recommend
taking on a smaller project.

Thanks,
-Stolee

^ permalink raw reply	[relevance 2%]

* Converting scripted commands to built-ins, was Re: [GSoC] Exploring Previous year Projects
  @ 2020-01-30 11:10  5%   ` Johannes Schindelin
  2020-01-30 15:14  2%     ` Derrick Stolee
  0 siblings, 1 reply; 200+ results
From: Johannes Schindelin @ 2020-01-30 11:10 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Shourya Shukla, christian.couder, t.gummerer, git, gitster

[-- Attachment #1: Type: text/plain, Size: 3586 bytes --]

Hi Kuba,

On Wed, 29 Jan 2020, Jakub Narebski wrote:

> Shourya Shukla <shouryashukla.oo@gmail.com> writes:
>
> > Hello,
> >
> > I was looking at the previous year projects[1] and a project intrigued me, namely:
> > "Convert scripts to builtins".
> >
> > Following from Christian's advice[2], I have decided to focus on my project proposal.
> > I noticed that various commands such as "git bisect", "git web--browse"(it particularly
> > interests me) are still in their "shell" form and will be needed to be converted into
> > their "C" form as per the project description.
> [...]
> > [1]: https://git.github.io/SoC-2019-Ideas/
> > [2]: https://lore.kernel.org/git/CAP8UFD2Fo=2suQDLwzLM-Wg3ZzXpqHw-x0brPtPV0d4dRsgs9A@mail.gmail.com/
>
> As far as I know, "git bisect" is currently being converted from shell
> to C by Miriam Rubio for Outreachy project [3], so I am not sure if it
> would be feasible as GSoC 2020 project.

Indeed. That one "is already taken".

> I'm not sure if it would be possible and if it would make sense to
> convert "git instaweb" and/or it's helper script "git web--browse" from
> shell to C.

I agree, both of those scripts seem not to benefit all that much from
being converted, while some people would still consider them to be
developed easier as shell scripts.

> I think trying to convert either "git stash" or "git submodule" to C
> would make more sense.

Oh, but `git stash` is already converted. The only two remainining shell
scripts for which I would consider a conversion to C to make sense are
`git submodule` and `git mergetool`.

Large parts of `git submodule` are already implemented in `git
submodule--helper`, so that's a head start (thanks Stephan Beller!).

The `git mergetool` command is a bit trickier, as it consists of three
scripts, really, with the `difftool--helper` depending on
`mergetool--lib`.

Realistically, I think that it would be possible for a GSoC student who is
already very familiar with the code base and with submodules to finish the
conversion of `git submodule` in one season.

The same is probably not true for `git mergetool`: it would require a
couple of seasons to convert, and a good chunk of the first month would be
taken by planning a conversion strategy.

As of the current `master`, the `git-*.sh` scripts are:

# In the process of being converted

git-bisect.sh

# Candidates for being converted

git-difftool--helper.sh
git-mergetool--lib.sh
git-mergetool.sh
git-submodule.sh

# Trivial conversions

git-merge-octopus.sh
git-merge-one-file.sh
git-merge-resolve.sh

# Already deprecated

git-filter-branch.sh
git-legacy-stash.sh
git-rebase--preserve-merges.sh

# Is this even needed anymore?

git-quiltimport.sh

# Probably better to leave them as shell scripts

git-instaweb.sh
git-request-pull.sh
git-web--browse.sh

# Not even Git commands

git-parse-remote.sh
git-sh-i18n.sh
git-sh-setup.sh

The situation of the Perl scripts to be converted is much nicer:

# Already in code review

git-add--interactive.perl

# Too complex/too dependent on the Perl packages

git-send-email.perl
git-svn.perl

# Support for legacy SCMs that are less and less used

git-archimport.perl
git-cvsexportcommit.perl
git-cvsimport.perl
git-cvsserver.perl

So: after `git add -i`, I think we're done with the conversion of the Perl
scripts. Took long enough ;-)

Ciao,
Dscho

>
> [3]: https://public-inbox.org/git/20200128144026.53128-1-mirucam@gmail.com/t/#u
>
> Best,
> --
> Jakub Narębski
>

^ permalink raw reply	[relevance 5%]

* Re: [PATCH v2 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree
  2020-01-24 23:00  2%       ` Philippe Blain
@ 2020-01-24 23:47  2%         ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2020-01-24 23:47 UTC (permalink / raw)
  To: Philippe Blain; +Cc: Git List

Philippe Blain <levraiphilippeblain@gmail.com> writes:

>>>> Cc:Max Kirillov max@max630.net [max@max630.net] Brandon Williams 
>>>> bwilliams.eng@gmail.com [bwilliams.eng@gmail.com] Jonathan Tan 
>>>> jonathantanmy@google.com [jonathantanmy@google.com] Stefan Beller 
>>>> stefanbeller@gmail.com [stefanbeller@gmail.com] Nguyễn Thái Ngọc Duy 
>>>> pclouds@gmail.com [pclouds@gmail.com] Eric Sunshine sunshine@sunshineco.com
>>>> [sunshine@sunshineco.com] Derrick Stolee stolee@gmail.com [stolee@gmail.com]
>>> 
>>> This is somewhat unreadable wall of names X-< Is it a funny
>>> rendering of what is originally in some mark-up format (perhaps
>>> HTML???)
>> 
>> Yes, Gitgitgadget unfortunately failed to convert this wall of text into a proper CC: list because there was no space between the "Cc:" and "Max". 
>> I’ll try to submit a PR for that in GGG. 
> For the record, https://github.com/gitgitgadget/gitgitgadget/pull/198 has been merged so this should not happen again.

That's good to know.  As long as the resulting e-mail addresses are
sensible (e.g. if Markdown markups are not cleansed enough and the
duplicated addresses inside [] seep through, the result would still
not be good), it is OK.

Thanks.

^ permalink raw reply	[relevance 2%]

* Re: [PATCH v2 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree
  2020-01-22 22:25  2%     ` Philippe Blain
@ 2020-01-24 23:00  2%       ` Philippe Blain
  2020-01-24 23:47  2%         ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Philippe Blain @ 2020-01-24 23:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git List


> Le 22 janv. 2020 à 17:25, Philippe Blain <levraiphilippeblain@gmail.com> a écrit :
> 
> Hi Junio, 
> 
>> Le 22 janv. 2020 à 17:10, Junio C Hamano <gitster@pobox.com> a écrit :
>> 
>> "Philippe Blain via GitGitGadget" <gitgitgadget@gmail.com> writes:
> 
>>> Cc:Max Kirillov max@max630.net [max@max630.net] Brandon Williams 
>>> bwilliams.eng@gmail.com [bwilliams.eng@gmail.com] Jonathan Tan 
>>> jonathantanmy@google.com [jonathantanmy@google.com] Stefan Beller 
>>> stefanbeller@gmail.com [stefanbeller@gmail.com] Nguyễn Thái Ngọc Duy 
>>> pclouds@gmail.com [pclouds@gmail.com] Eric Sunshine sunshine@sunshineco.com
>>> [sunshine@sunshineco.com] Derrick Stolee stolee@gmail.com [stolee@gmail.com]
>> 
>> This is somewhat unreadable wall of names X-< Is it a funny
>> rendering of what is originally in some mark-up format (perhaps
>> HTML???)
> 
> Yes, Gitgitgadget unfortunately failed to convert this wall of text into a proper CC: list because there was no space between the "Cc:" and "Max". 
> I’ll try to submit a PR for that in GGG. 
For the record, https://github.com/gitgitgadget/gitgitgadget/pull/198 has been merged so this should not happen again.


^ permalink raw reply	[relevance 2%]

* Re: [PATCH v2 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree
  2020-01-22 22:10  4%   ` Junio C Hamano
@ 2020-01-22 22:25  2%     ` Philippe Blain
  2020-01-24 23:00  2%       ` Philippe Blain
  0 siblings, 1 reply; 200+ results
From: Philippe Blain @ 2020-01-22 22:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Philippe Blain via GitGitGadget, git

Hi Junio, 

> Le 22 janv. 2020 à 17:10, Junio C Hamano <gitster@pobox.com> a écrit :
> 
> "Philippe Blain via GitGitGadget" <gitgitgadget@gmail.com> writes:

>> Cc:Max Kirillov max@max630.net [max@max630.net] Brandon Williams 
>> bwilliams.eng@gmail.com [bwilliams.eng@gmail.com] Jonathan Tan 
>> jonathantanmy@google.com [jonathantanmy@google.com] Stefan Beller 
>> stefanbeller@gmail.com [stefanbeller@gmail.com] Nguyễn Thái Ngọc Duy 
>> pclouds@gmail.com [pclouds@gmail.com] Eric Sunshine sunshine@sunshineco.com
>> [sunshine@sunshineco.com] Derrick Stolee stolee@gmail.com [stolee@gmail.com]
> 
> This is somewhat unreadable wall of names X-< Is it a funny
> rendering of what is originally in some mark-up format (perhaps
> HTML???)

Yes, Gitgitgadget unfortunately failed to convert this wall of text into a proper CC: list because there was no space between the "Cc:" and "Max". 
I’ll try to submit a PR for that in GGG. 

Cheers,
Philippe. 

^ permalink raw reply	[relevance 2%]

* Re: [PATCH v2 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree
  2020-01-21 15:01  5% ` [PATCH v2 " Philippe Blain via GitGitGadget
  2020-01-22 12:55  2%   ` Philippe Blain
@ 2020-01-22 22:10  4%   ` Junio C Hamano
  2020-01-22 22:25  2%     ` Philippe Blain
  1 sibling, 1 reply; 200+ results
From: Junio C Hamano @ 2020-01-22 22:10 UTC (permalink / raw)
  To: Philippe Blain via GitGitGadget; +Cc: git, Philippe Blain

"Philippe Blain via GitGitGadget" <gitgitgadget@gmail.com> writes:

> Changes since v1:
>
>  * revert the addition of a dash in "file1 updated" by correctly using the
>    'tag' argument of test_commit
>  * improve the commit message for the 3rd patch, as suggested by Eric
>  * fix spacing when redirecting into 'expect' and 'actual'
>  * harden the tests by echoing expected values into expect, as suggested by
>    Stolee (I did that in both tests)
>  * remove test_might_fail and use test_expect_code
>  * add the 'git log' test suggested by Stolee
>
> v1: This series fixes the behaviour of git checkout/reset/read-tree
> --recurse-submodules when they are called in a linked worktree (created by 
> git worktree add). 
>
> Although submodules are cloned in $GIT_COMMON_DIR/worktrees/<name>/modules 
> upon issuing git submodule update in the linked worktree, any invocation of 
> git checkout/reset/read-tree --recurse-submodules that changes the state of
> the submodule(s) will incorrectly operate on the repositories of the
> submodules in the main worktree, i.e. the ones at $GIT_COMMON_DIR/modules/. 
>
> The fourth patch fixes this behaviour by using get_git_dir() instead of 
> git_common_dir() in submodule.c::submodule_move_head and 
> submodule.c::submodule_unset_core_worktree to construct the path to the
> submodule repository.
>
> The first 3 patches are clean-up patches on t7410-submodule-checkout-to.sh
> (renamed to t2405-worktree-submodule.sh) to bring it up to date.

I've read these four patches a few times and did not spot any
remaining issues.  I however is hardly an expert on (nor a big fan
of) the "--recurse-submodule" feature, so a proper review by those
who are more familiar with it is surely appreciated.

Thanks.

> Cc:Max Kirillov max@max630.net [max@max630.net] Brandon Williams 
> bwilliams.eng@gmail.com [bwilliams.eng@gmail.com] Jonathan Tan 
> jonathantanmy@google.com [jonathantanmy@google.com] Stefan Beller 
> stefanbeller@gmail.com [stefanbeller@gmail.com] Nguyễn Thái Ngọc Duy 
> pclouds@gmail.com [pclouds@gmail.com] Eric Sunshine sunshine@sunshineco.com
> [sunshine@sunshineco.com] Derrick Stolee stolee@gmail.com [stolee@gmail.com]

This is somewhat unreadable wall of names X-< Is it a funny
rendering of what is originally in some mark-up format (perhaps
HTML???)


^ permalink raw reply	[relevance 4%]

* Re: [PATCH v2 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree
  2020-01-21 15:01  5% ` [PATCH v2 " Philippe Blain via GitGitGadget
@ 2020-01-22 12:55  2%   ` Philippe Blain
  2020-01-22 22:10  4%   ` Junio C Hamano
  1 sibling, 0 replies; 200+ results
From: Philippe Blain @ 2020-01-22 12:55 UTC (permalink / raw)
  To: Git List
  Cc: Brandon Williams, Max Kirillov, Stefan Beller,
	Nguyễn Thái Ngọc Duy, Jonathan Tan,
	Eric Sunshine, Derrick Stolee

Hello,

Here is v2 of my series. I realized that Gitgitgadget failed to parse the Cc: footer in my PR description and thus both v1 and v2 got sent to the list without any Cc:s.

Cheers,

Philippe.

> Le 21 janv. 2020 à 10:01, Philippe Blain via GitGitGadget <gitgitgadget@gmail.com> a écrit :
> 
> Changes since v1:
> 
> * revert the addition of a dash in "file1 updated" by correctly using the
>   'tag' argument of test_commit
> * improve the commit message for the 3rd patch, as suggested by Eric
> * fix spacing when redirecting into 'expect' and 'actual'
> * harden the tests by echoing expected values into expect, as suggested by
>   Stolee (I did that in both tests)
> * remove test_might_fail and use test_expect_code
> * add the 'git log' test suggested by Stolee
> 
> v1: This series fixes the behaviour of git checkout/reset/read-tree
> --recurse-submodules when they are called in a linked worktree (created by 
> git worktree add). 
> 
> Although submodules are cloned in $GIT_COMMON_DIR/worktrees/<name>/modules 
> upon issuing git submodule update in the linked worktree, any invocation of 
> git checkout/reset/read-tree --recurse-submodules that changes the state of
> the submodule(s) will incorrectly operate on the repositories of the
> submodules in the main worktree, i.e. the ones at $GIT_COMMON_DIR/modules/. 
> 
> The fourth patch fixes this behaviour by using get_git_dir() instead of 
> git_common_dir() in submodule.c::submodule_move_head and 
> submodule.c::submodule_unset_core_worktree to construct the path to the
> submodule repository.
> 
> The first 3 patches are clean-up patches on t7410-submodule-checkout-to.sh
> (renamed to t2405-worktree-submodule.sh) to bring it up to date.
> 
> Cc:Max Kirillov max@max630.net [max@max630.net] Brandon Williams 
> bwilliams.eng@gmail.com [bwilliams.eng@gmail.com] Jonathan Tan 
> jonathantanmy@google.com [jonathantanmy@google.com] Stefan Beller 
> stefanbeller@gmail.com [stefanbeller@gmail.com] Nguyễn Thái Ngọc Duy 
> pclouds@gmail.com [pclouds@gmail.com] Eric Sunshine sunshine@sunshineco.com
> [sunshine@sunshineco.com] Derrick Stolee stolee@gmail.com [stolee@gmail.com]
> 
> Philippe Blain (4):
>  t7410: rename to t2405-worktree-submodule.sh
>  t2405: use git -C and test_commit -C instead of subshells
>  t2405: clarify test descriptions and simplify test
>  submodule.c: use get_git_dir() instead of get_git_common_dir()
> 
> submodule.c                      |  6 +--
> t/t2405-worktree-submodule.sh    | 90 ++++++++++++++++++++++++++++++++
> t/t7410-submodule-checkout-to.sh | 77 ---------------------------
> 3 files changed, 93 insertions(+), 80 deletions(-)
> create mode 100755 t/t2405-worktree-submodule.sh
> delete mode 100755 t/t7410-submodule-checkout-to.sh
> 
> 
> base-commit: b4615e40a8125477e18490d868f7b65954372b43
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-523%2Fphil-blain%2Fcheckout-recurse-in-linked-worktree-v2
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-523/phil-blain/checkout-recurse-in-linked-worktree-v2
> Pull-Request: https://github.com/gitgitgadget/git/pull/523
> 
> Range-diff vs v1:
> 
> 1:  ff33339690 = 1:  1a4eae1ef5 t7410: rename to t2405-worktree-submodule.sh
> 2:  5060ce3d64 ! 2:  f06d2c4aa5 t2405: use git -C and test_commit -C instead of subshells
>     @@ -41,7 +41,7 @@
>      +	git init origin/main &&
>      +	git -C origin/main submodule add ../sub &&
>      +	git -C origin/main commit -m "add sub" &&
>     -+	test_commit -C origin/sub "file1-updated" file1 file1updated &&
>     ++	test_commit -C origin/sub "file1 updated" file1 file1updated file1updated &&
>       	git -C origin/main/sub pull &&
>      -	(
>      -		cd origin/main &&
>     @@ -53,30 +53,3 @@
>       '
> 
>       test_expect_success 'setup: clone' '
>     -@@
>     - 
>     - test_expect_failure 'can see submodule diffs just after checkout' '
>     - 	git -C default_checkout/main diff --submodule master"^!" >out &&
>     --	grep "file1 updated" out
>     -+	grep "file1-updated" out
>     - '
>     - 
>     - test_expect_success 'checkout main and initialize independent clones' '
>     -@@
>     - 
>     - test_expect_success 'can see submodule diffs after independent cloning' '
>     - 	git -C fully_cloned_submodule/main diff --submodule master"^!" >out &&
>     --	grep "file1 updated" out
>     -+	grep "file1-updated" out
>     - '
>     - 
>     - test_expect_success 'checkout sub manually' '
>     -@@
>     - 
>     - test_expect_success 'can see submodule diffs after manual checkout of linked submodule' '
>     - 	git -C linked_submodule/main diff --submodule master"^!" >out &&
>     --	grep "file1 updated" out
>     -+	grep "file1-updated" out
>     - '
>     - 
>     - test_done
> 3:  6e0e664026 ! 3:  10727275a2 t2405: clarify test descriptions and simplify test
>     @@ -10,7 +10,13 @@
>          descriptions were not updated, keeping 'checkout' instead of using the new
>          terminology (linked worktrees).
> 
>     -    Clarify the tests by using the right terminology. While at it, remove some unnecessary
>     +    Also, in the test each worktree is created in
>     +    $TRASH_DIRECTORY/<leading-directory>/main, where the name of <leading-directory>
>     +    carries some information about what behavior each test verifies. This directory
>     +    structure is not mandatory for the tests; the worktrees can live next to one
>     +    another in the trash directory.
>     +
>     +    Clarify the tests by using the right terminology, and remove the unnecessary
>          leading directories such that all superproject worktrees are directly next to one
>          another in the trash directory.
> 
>     @@ -44,7 +50,7 @@
>      -	git -C default_checkout/main diff --submodule master"^!" >out &&
>      +test_expect_failure 'submodule is checked out just after worktree add' '
>      +	git -C worktree diff --submodule master"^!" >out &&
>     - 	grep "file1-updated" out
>     + 	grep "file1 updated" out
>       '
> 
>      -test_expect_success 'checkout main and initialize independent clones' '
>     @@ -60,7 +66,7 @@
>      -	git -C fully_cloned_submodule/main diff --submodule master"^!" >out &&
>      +test_expect_success 'submodule is checked out just after submodule update in linked worktree' '
>      +	git -C worktree-submodule-update diff --submodule master"^!" >out &&
>     - 	grep "file1-updated" out
>     + 	grep "file1 updated" out
>       '
> 
>      -test_expect_success 'checkout sub manually' '
>     @@ -76,6 +82,6 @@
>      -	git -C linked_submodule/main diff --submodule master"^!" >out &&
>      +test_expect_success 'submodule is checked out after manually adding submodule worktree' '
>      +	git -C linked_submodule diff --submodule master"^!" >out &&
>     - 	grep "file1-updated" out
>     + 	grep "file1 updated" out
>       '
> 
> 4:  72cdb2f95d ! 4:  614bccd31b submodule.c: use get_git_dir() instead of get_git_common_dir()
>     @@ -24,7 +24,7 @@
>          This leads to an incorrect (and confusing!) state in the submodule working tree
>          of the main superproject worktree.
> 
>     -    Additionnally, if switching to a commit where the submodule is not present,
>     +    Additionally, if switching to a commit where the submodule is not present,
>          submodule_unset_core_worktree will be called and will incorrectly remove
>          'core.wortree' from the config file of the submodule in the main superproject worktree,
>          $GIT_COMMON_DIR/modules/<name>/config.
>     @@ -75,30 +75,41 @@
>      +	test_commit -C origin/main first &&
>       	git -C origin/main submodule add ../sub &&
>       	git -C origin/main commit -m "add sub" &&
>     - 	test_commit -C origin/sub "file1-updated" file1 file1updated &&
>     + 	test_commit -C origin/sub "file1 updated" file1 file1updated file1updated &&
>      @@
>     - 	grep "file1-updated" out
>     + 	grep "file1 updated" out
>       '
> 
>      +test_expect_success 'checkout --recurse-submodules uses $GIT_DIR for submodules in a linked worktree' '
>      +	git -C main worktree add "$base_path/checkout-recurse" --detach  &&
>      +	git -C checkout-recurse submodule update --init &&
>     -+	cat checkout-recurse/sub/.git > expect-gitfile &&
>     -+	git -C main/sub rev-parse HEAD > expect-head-main &&
>     ++	echo "gitdir: ../../main/.git/worktrees/checkout-recurse/modules/sub" >expect-gitfile &&
>     ++	cat checkout-recurse/sub/.git >actual-gitfile &&
>     ++	test_cmp expect-gitfile actual-gitfile &&
>     ++	git -C main/sub rev-parse HEAD >expect-head-main &&
>      +	git -C checkout-recurse checkout --recurse-submodules HEAD~1 &&
>     -+	cat checkout-recurse/sub/.git > actual-gitfile &&
>     -+	git -C main/sub rev-parse HEAD > actual-head-main &&
>     ++	cat checkout-recurse/sub/.git >actual-gitfile &&
>     ++	git -C main/sub rev-parse HEAD >actual-head-main &&
>      +	test_cmp expect-gitfile actual-gitfile &&
>      +	test_cmp expect-head-main actual-head-main
>      +'
>      +
>      +test_expect_success 'core.worktree is removed in $GIT_DIR/modules/<name>/config, not in $GIT_COMMON_DIR/modules/<name>/config' '
>     -+	git -C main/sub config --get core.worktree > expect &&
>     ++	echo "../../../sub" >expect-main &&
>     ++	git -C main/sub config --get core.worktree >actual-main &&
>     ++	test_cmp expect-main actual-main &&
>     ++	echo "../../../../../../checkout-recurse/sub" >expect-linked &&
>     ++	git -C checkout-recurse/sub config --get core.worktree >actual-linked &&
>     ++	test_cmp expect-linked actual-linked &&
>      +	git -C checkout-recurse checkout --recurse-submodules first &&
>     -+	test_might_fail git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree > linked-config &&
>     ++	test_expect_code 1 git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree >linked-config &&
>      +	test_must_be_empty linked-config &&
>     -+	test_might_fail git -C main/sub config --get core.worktree > actual &&
>     -+	test_cmp expect actual
>     ++	git -C main/sub config --get core.worktree >actual-main &&
>     ++	test_cmp expect-main actual-main
>     ++'
>     ++
>     ++test_expect_success 'unsetting core.worktree does not prevent running commands directly against the submodule repository' '
>     ++	git -C main/.git/worktrees/checkout-recurse/modules/sub log
>      +'
>      +
>       test_done
> 
> -- 
> gitgitgadget


^ permalink raw reply	[relevance 2%]

* [PATCH v2 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree
  2020-01-17 12:23 14% [PATCH 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree Philippe Blain via GitGitGadget
@ 2020-01-21 15:01  5% ` Philippe Blain via GitGitGadget
  2020-01-22 12:55  2%   ` Philippe Blain
  2020-01-22 22:10  4%   ` Junio C Hamano
  0 siblings, 2 replies; 200+ results
From: Philippe Blain via GitGitGadget @ 2020-01-21 15:01 UTC (permalink / raw)
  To: git; +Cc: Philippe Blain

Changes since v1:

 * revert the addition of a dash in "file1 updated" by correctly using the
   'tag' argument of test_commit
 * improve the commit message for the 3rd patch, as suggested by Eric
 * fix spacing when redirecting into 'expect' and 'actual'
 * harden the tests by echoing expected values into expect, as suggested by
   Stolee (I did that in both tests)
 * remove test_might_fail and use test_expect_code
 * add the 'git log' test suggested by Stolee

v1: This series fixes the behaviour of git checkout/reset/read-tree
--recurse-submodules when they are called in a linked worktree (created by 
git worktree add). 

Although submodules are cloned in $GIT_COMMON_DIR/worktrees/<name>/modules 
upon issuing git submodule update in the linked worktree, any invocation of 
git checkout/reset/read-tree --recurse-submodules that changes the state of
the submodule(s) will incorrectly operate on the repositories of the
submodules in the main worktree, i.e. the ones at $GIT_COMMON_DIR/modules/. 

The fourth patch fixes this behaviour by using get_git_dir() instead of 
git_common_dir() in submodule.c::submodule_move_head and 
submodule.c::submodule_unset_core_worktree to construct the path to the
submodule repository.

The first 3 patches are clean-up patches on t7410-submodule-checkout-to.sh
(renamed to t2405-worktree-submodule.sh) to bring it up to date.

Cc:Max Kirillov max@max630.net [max@max630.net] Brandon Williams 
bwilliams.eng@gmail.com [bwilliams.eng@gmail.com] Jonathan Tan 
jonathantanmy@google.com [jonathantanmy@google.com] Stefan Beller 
stefanbeller@gmail.com [stefanbeller@gmail.com] Nguyễn Thái Ngọc Duy 
pclouds@gmail.com [pclouds@gmail.com] Eric Sunshine sunshine@sunshineco.com
[sunshine@sunshineco.com] Derrick Stolee stolee@gmail.com [stolee@gmail.com]

Philippe Blain (4):
  t7410: rename to t2405-worktree-submodule.sh
  t2405: use git -C and test_commit -C instead of subshells
  t2405: clarify test descriptions and simplify test
  submodule.c: use get_git_dir() instead of get_git_common_dir()

 submodule.c                      |  6 +--
 t/t2405-worktree-submodule.sh    | 90 ++++++++++++++++++++++++++++++++
 t/t7410-submodule-checkout-to.sh | 77 ---------------------------
 3 files changed, 93 insertions(+), 80 deletions(-)
 create mode 100755 t/t2405-worktree-submodule.sh
 delete mode 100755 t/t7410-submodule-checkout-to.sh


base-commit: b4615e40a8125477e18490d868f7b65954372b43
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-523%2Fphil-blain%2Fcheckout-recurse-in-linked-worktree-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-523/phil-blain/checkout-recurse-in-linked-worktree-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/523

Range-diff vs v1:

 1:  ff33339690 = 1:  1a4eae1ef5 t7410: rename to t2405-worktree-submodule.sh
 2:  5060ce3d64 ! 2:  f06d2c4aa5 t2405: use git -C and test_commit -C instead of subshells
     @@ -41,7 +41,7 @@
      +	git init origin/main &&
      +	git -C origin/main submodule add ../sub &&
      +	git -C origin/main commit -m "add sub" &&
     -+	test_commit -C origin/sub "file1-updated" file1 file1updated &&
     ++	test_commit -C origin/sub "file1 updated" file1 file1updated file1updated &&
       	git -C origin/main/sub pull &&
      -	(
      -		cd origin/main &&
     @@ -53,30 +53,3 @@
       '
       
       test_expect_success 'setup: clone' '
     -@@
     - 
     - test_expect_failure 'can see submodule diffs just after checkout' '
     - 	git -C default_checkout/main diff --submodule master"^!" >out &&
     --	grep "file1 updated" out
     -+	grep "file1-updated" out
     - '
     - 
     - test_expect_success 'checkout main and initialize independent clones' '
     -@@
     - 
     - test_expect_success 'can see submodule diffs after independent cloning' '
     - 	git -C fully_cloned_submodule/main diff --submodule master"^!" >out &&
     --	grep "file1 updated" out
     -+	grep "file1-updated" out
     - '
     - 
     - test_expect_success 'checkout sub manually' '
     -@@
     - 
     - test_expect_success 'can see submodule diffs after manual checkout of linked submodule' '
     - 	git -C linked_submodule/main diff --submodule master"^!" >out &&
     --	grep "file1 updated" out
     -+	grep "file1-updated" out
     - '
     - 
     - test_done
 3:  6e0e664026 ! 3:  10727275a2 t2405: clarify test descriptions and simplify test
     @@ -10,7 +10,13 @@
          descriptions were not updated, keeping 'checkout' instead of using the new
          terminology (linked worktrees).
      
     -    Clarify the tests by using the right terminology. While at it, remove some unnecessary
     +    Also, in the test each worktree is created in
     +    $TRASH_DIRECTORY/<leading-directory>/main, where the name of <leading-directory>
     +    carries some information about what behavior each test verifies. This directory
     +    structure is not mandatory for the tests; the worktrees can live next to one
     +    another in the trash directory.
     +
     +    Clarify the tests by using the right terminology, and remove the unnecessary
          leading directories such that all superproject worktrees are directly next to one
          another in the trash directory.
      
     @@ -44,7 +50,7 @@
      -	git -C default_checkout/main diff --submodule master"^!" >out &&
      +test_expect_failure 'submodule is checked out just after worktree add' '
      +	git -C worktree diff --submodule master"^!" >out &&
     - 	grep "file1-updated" out
     + 	grep "file1 updated" out
       '
       
      -test_expect_success 'checkout main and initialize independent clones' '
     @@ -60,7 +66,7 @@
      -	git -C fully_cloned_submodule/main diff --submodule master"^!" >out &&
      +test_expect_success 'submodule is checked out just after submodule update in linked worktree' '
      +	git -C worktree-submodule-update diff --submodule master"^!" >out &&
     - 	grep "file1-updated" out
     + 	grep "file1 updated" out
       '
       
      -test_expect_success 'checkout sub manually' '
     @@ -76,6 +82,6 @@
      -	git -C linked_submodule/main diff --submodule master"^!" >out &&
      +test_expect_success 'submodule is checked out after manually adding submodule worktree' '
      +	git -C linked_submodule diff --submodule master"^!" >out &&
     - 	grep "file1-updated" out
     + 	grep "file1 updated" out
       '
       
 4:  72cdb2f95d ! 4:  614bccd31b submodule.c: use get_git_dir() instead of get_git_common_dir()
     @@ -24,7 +24,7 @@
          This leads to an incorrect (and confusing!) state in the submodule working tree
          of the main superproject worktree.
      
     -    Additionnally, if switching to a commit where the submodule is not present,
     +    Additionally, if switching to a commit where the submodule is not present,
          submodule_unset_core_worktree will be called and will incorrectly remove
          'core.wortree' from the config file of the submodule in the main superproject worktree,
          $GIT_COMMON_DIR/modules/<name>/config.
     @@ -75,30 +75,41 @@
      +	test_commit -C origin/main first &&
       	git -C origin/main submodule add ../sub &&
       	git -C origin/main commit -m "add sub" &&
     - 	test_commit -C origin/sub "file1-updated" file1 file1updated &&
     + 	test_commit -C origin/sub "file1 updated" file1 file1updated file1updated &&
      @@
     - 	grep "file1-updated" out
     + 	grep "file1 updated" out
       '
       
      +test_expect_success 'checkout --recurse-submodules uses $GIT_DIR for submodules in a linked worktree' '
      +	git -C main worktree add "$base_path/checkout-recurse" --detach  &&
      +	git -C checkout-recurse submodule update --init &&
     -+	cat checkout-recurse/sub/.git > expect-gitfile &&
     -+	git -C main/sub rev-parse HEAD > expect-head-main &&
     ++	echo "gitdir: ../../main/.git/worktrees/checkout-recurse/modules/sub" >expect-gitfile &&
     ++	cat checkout-recurse/sub/.git >actual-gitfile &&
     ++	test_cmp expect-gitfile actual-gitfile &&
     ++	git -C main/sub rev-parse HEAD >expect-head-main &&
      +	git -C checkout-recurse checkout --recurse-submodules HEAD~1 &&
     -+	cat checkout-recurse/sub/.git > actual-gitfile &&
     -+	git -C main/sub rev-parse HEAD > actual-head-main &&
     ++	cat checkout-recurse/sub/.git >actual-gitfile &&
     ++	git -C main/sub rev-parse HEAD >actual-head-main &&
      +	test_cmp expect-gitfile actual-gitfile &&
      +	test_cmp expect-head-main actual-head-main
      +'
      +
      +test_expect_success 'core.worktree is removed in $GIT_DIR/modules/<name>/config, not in $GIT_COMMON_DIR/modules/<name>/config' '
     -+	git -C main/sub config --get core.worktree > expect &&
     ++	echo "../../../sub" >expect-main &&
     ++	git -C main/sub config --get core.worktree >actual-main &&
     ++	test_cmp expect-main actual-main &&
     ++	echo "../../../../../../checkout-recurse/sub" >expect-linked &&
     ++	git -C checkout-recurse/sub config --get core.worktree >actual-linked &&
     ++	test_cmp expect-linked actual-linked &&
      +	git -C checkout-recurse checkout --recurse-submodules first &&
     -+	test_might_fail git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree > linked-config &&
     ++	test_expect_code 1 git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree >linked-config &&
      +	test_must_be_empty linked-config &&
     -+	test_might_fail git -C main/sub config --get core.worktree > actual &&
     -+	test_cmp expect actual
     ++	git -C main/sub config --get core.worktree >actual-main &&
     ++	test_cmp expect-main actual-main
     ++'
     ++
     ++test_expect_success 'unsetting core.worktree does not prevent running commands directly against the submodule repository' '
     ++	git -C main/.git/worktrees/checkout-recurse/modules/sub log
      +'
      +
       test_done

-- 
gitgitgadget

^ permalink raw reply	[relevance 5%]

* [PATCH 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree
@ 2020-01-17 12:23 14% Philippe Blain via GitGitGadget
  2020-01-21 15:01  5% ` [PATCH v2 " Philippe Blain via GitGitGadget
  0 siblings, 1 reply; 200+ results
From: Philippe Blain via GitGitGadget @ 2020-01-17 12:23 UTC (permalink / raw)
  To: git; +Cc: Philippe Blain

This series fixes the behaviour of git checkout/reset/read-tree
--recurse-submodules when they are called in a linked worktree (created by 
git worktree add). 

Although submodules are cloned in $GIT_COMMON_DIR/worktrees/<name>/modules 
upon issuing git submodule update in the linked worktree, any invocation of 
git checkout/reset/read-tree --recurse-submodules that changes the state of
the submodule(s) will incorrectly operate on the repositories of the
submodules in the main worktree, i.e. the ones at $GIT_COMMON_DIR/modules/. 

The fourth patch fixes this behaviour by using get_git_dir() instead of 
git_common_dir() in submodule.c::submodule_move_head and 
submodule.c::submodule_unset_core_worktree to construct the path to the
submodule repository.

The first 3 patches are clean-up patches on t7410-submodule-checkout-to.sh
(renamed to t2405-worktree-submodule.sh) to bring it up to date.

Note: in the second test added in the fourth patch I used test_might_fail 
such that when the test is run on the current master, only the last test_cmp 
makes the test fail. If we want to be more strict I'll change that to :

diff --git a/t/t2405-worktree-submodule.sh b/t/t2405-worktree-submodule.sh
index eba17d9e35..31d156cce7 100755
--- a/t/t2405-worktree-submodule.sh
+++ b/t/t2405-worktree-submodule.sh
@@ -70,9 +70,9 @@ test_expect_success 'checkout --recurse-submodules uses $GIT_DIR for submodules
 test_expect_success 'core.worktree is removed in $GIT_DIR/modules/<name>/config, not in $GIT_COMMON_DIR/modules/<name>/config' '
     git -C main/sub config --get core.worktree > expect &&
     git -C checkout-recurse checkout --recurse-submodules first &&
-    test_might_fail git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree > linked-config &&
+    test_expect_code 1 git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree > linked-config &&
     test_must_be_empty linked-config &&
-    test_might_fail git -C main/sub config --get core.worktree > actual &&
+    git -C main/sub config --get core.worktree > actual &&
     test_cmp expect actual
 '

Cc:Max Kirillov max@max630.net [max@max630.net] Brandon Williams 
bwilliams.eng@gmail.com [bwilliams.eng@gmail.com] Jonathan Tan 
jonathantanmy@google.com [jonathantanmy@google.com] Stefan Beller 
stefanbeller@gmail.com [stefanbeller@gmail.com] Nguyễn Thái Ngọc Duy 
pclouds@gmail.com [pclouds@gmail.com]

Philippe Blain (4):
  t7410: rename to t2405-worktree-submodule.sh
  t2405: use git -C and test_commit -C instead of subshells
  t2405: clarify test descriptions and simplify test
  submodule.c: use get_git_dir() instead of get_git_common_dir()

 submodule.c                      |  6 +--
 t/t2405-worktree-submodule.sh    | 79 ++++++++++++++++++++++++++++++++
 t/t7410-submodule-checkout-to.sh | 77 -------------------------------
 3 files changed, 82 insertions(+), 80 deletions(-)
 create mode 100755 t/t2405-worktree-submodule.sh
 delete mode 100755 t/t7410-submodule-checkout-to.sh


base-commit: b4615e40a8125477e18490d868f7b65954372b43
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-523%2Fphil-blain%2Fcheckout-recurse-in-linked-worktree-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-523/phil-blain/checkout-recurse-in-linked-worktree-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/523
-- 
gitgitgadget

^ permalink raw reply related	[relevance 14%]

* Re: Issue: "Could not access submodule" error when pulling recursively with Git 2.22.0
  2019-10-23 10:04  8% ` SZEDER Gábor
@ 2019-10-25 12:41  9%   ` Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2019-10-25 12:41 UTC (permalink / raw)
  To: SZEDER Gábor; +Cc: Aleksey Mikhaylov, git@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 9313 bytes --]

Hi Gábor,

On Wed, 23 Oct 2019, SZEDER Gábor wrote:

> On Wed, Oct 23, 2019 at 07:22:12AM +0000, Aleksey Mikhaylov wrote:
> > "Could not access submodule" error when pulling recursively with Git 2.22.0.
> > This issue causes if there is submodule in submodule.
>
> > Please use my simple test repository to reproduce the problem:
> > https://github.com/agmikhailov/example2361.git
> >
> > It is just an empty repository with one submodule (https://github.com/agmikhailov/example2361M1.git)
> > and one submodule of submodule (https://github.com/agmikhailov/example2361M2.git):
> >
> > git clone https://github.com/agmikhailov/example2361.git
> > cd example2361/
> > git submodule init
>
> According to the docs of 'git submodule init', it "initializes the
> submodules recorded in the index".  Therefore, it can only initialize
> the submodule in 'example2361M1', because at this point we have no
> idea that there is a nested submodule in there.
>
>   $ git submodule init
>   Submodule 'example2361M1' (https://github.com/agmikhailov/example2361M1.git) registered for path 'example2361M1'

Indeed, `git submodule init` is not recursive.

> > git submodule update
>
> This command clones 'example2361M1':
>
>   $ git submodule update --recursive
>   Cloning into '/tmp/example2361/example2361M1'...
>   Submodule path 'example2361M1': checked out '6a9be24a1c0ebd44d91ae4dcf1fd62580b936540'
>
> Only at this point can we finally see that there is a nested
> submodule, and can initialize and clone it with:
>
>   $ cd example2361M1
>   $ git submodule init
>   Submodule 'example2361M2' (https://github.com/agmikhailov/example2361M2.git) registered for path 'example2361M2'
>   $ git submodule update
>   Cloning into '/tmp/example2361/example2361M1/example2361M2'...
>   Submodule path 'example2361M2': checked out '9ed39cf1fe0a8cf34e72d2e7ebff1ea9d4a63ac1'

I concur.

> > git pull --recurse-submodules=true
>
> And after that:
>
>   $ cd ../..
>   $ git pull --recurse-submodules=true
>   Fetching submodule example2361M1
>   Fetching submodule example2361M1/example2361M2
>   Already up to date.

Yes, I agree that _probably_ what the user wanted is to initialize the
submodules recursively.

Having said that, I vaguely remember that e.g. Boost has this insane
forest of submodules, and I am almost certain that no sane person wants
to clone them all. _I_ wouldn't.

> > ACTUAL RESULT
> >
> > "git --recurse-submodules=true" command fails with message "Could not access submodule":
> >
> > $ git --recurse-submodules=true
> > Fetching submodule example2361M1
> > Could not access submodule 'example2361M2'
> >
> > EXPECTED RESULT
> >
> > All submodules are successfully updated by "git --recurse-submodules=true" command.
> >
> > ADDITIONAL INFORMATION
> >
> > Git version 2.20.1 does not have this problem.
> > So we had to downgrade Git to work with submodules.
>
> The behavior was indeed different with v2.20.1, but that version
> didn't show the behavior you expected.  When running your commands
> with v2.20.1 I get:
>
>   $ ~/src/git/bin-wrappers/git pull --recurse-submodules=true
>   Fetching submodule example2361M1
>   Already up to date.
>   $ find example2361M1/example2361M2/
>   example2361M1/example2361M2/
>
> So while that 'git pull' didn't error out, it didn't even look at the
> nested submodule, which is still uninitialized and empty.

I would actually argue that this is what is expected: the entire _point_
of submodules is that they can be inactive.

Coming back to the Boost example, what I would want Git to do when only
a fraction of the submodules is active is to skip the inactive ones
during a `git pull --recurse-submodules=true`.

Which v2.20.1 apparently did, and I would call the current behavior a
regression.

> FWIW, bisecting shows that the behavior changed with commit
> a62387b3fc,

Thanks for digging this out!

> but, unfortunately, the commit message doesn't seem to be very helpful
> to me, but perhaps others with more experience with submodules can
> make something out of it.
>
> commit a62387b3fc9f5aeeb04a2db278121d33a9caafa7
> Author: Stefan Beller <sbeller@google.com>
> Date:   Wed Nov 28 16:27:55 2018 -0800
>
>     submodule.c: fetch in submodules git directory instead of in worktree
>
>     Keep the properties introduced in 10f5c52656 (submodule: avoid
>     auto-discovery in prepare_submodule_repo_env(), 2016-09-01), by fixating
>     the git directory of the submodule.
>
>     Signed-off-by: Stefan Beller <sbeller@google.com>
>     Signed-off-by: Junio C Hamano <gitster@pobox.com>
>
>  submodule.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)

To me, this commit message suggests that the bahvior should not have
changed in the reported manner.

Let's look at the diff:

-- snip --
diff --git a/submodule.c b/submodule.c
index 77ace5e784a..d1b6646f42d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -494,6 +494,12 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }

+static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out)
+{
+	prepare_submodule_repo_env_no_git_dir(out);
+	argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT);
+}
+
 /* Helper function to display the submodule header line prior to the full
  * summary output. If it can locate the submodule objects directory it will
  * attempt to lookup both the left and right commits and put them into the
@@ -1327,8 +1333,8 @@ static int get_next_submodule(struct child_process *cp,
 		repo = get_submodule_repo_for(spf->r, submodule);
 		if (repo) {
 			child_process_init(cp);
-			cp->dir = xstrdup(repo->worktree);
-			prepare_submodule_repo_env(&cp->env_array);
+			cp->dir = xstrdup(repo->gitdir);
+			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
-- snap --

The obvious difference in behavior is that we no longer let Git
discover the `.git` file/directory, but we define it (because we can).

But actually, we cannot, not if the submodule is not checked out!
Because in this case, there is no `.git` file and Git then tries to
initialize the repository and the worktree, and fails rather miserably
in the reported manner.

Side note: I think there is something spooky going on where we try to
fetch submodules twice when the first time failed, and somehow slip into
the `else` arm of this code:

-- snip --
		task->repo = get_submodule_repo_for(spf->r, task->sub);
		if (task->repo) {
			struct strbuf submodule_prefix = STRBUF_INIT;
			child_process_init(cp);
			cp->dir = task->repo->gitdir;
			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
			cp->git_cmd = 1;
			if (!spf->quiet)
				strbuf_addf(err, "Fetching submodule %s%s\n",
					    spf->prefix, ce->name);
			argv_array_init(&cp->args);
			argv_array_pushv(&cp->args, spf->args.argv);
			argv_array_push(&cp->args, default_argv);
			argv_array_push(&cp->args, "--submodule-prefix");

			strbuf_addf(&submodule_prefix, "%s%s/",
						       spf->prefix,
						       task->sub->path);
			argv_array_push(&cp->args, submodule_prefix.buf);

			spf->count++;
			*task_cb = task;

			strbuf_release(&submodule_prefix);
			return 1;
		} else {

			fetch_task_release(task);
			free(task);

			/*
			 * An empty directory is normal,
			 * the submodule is not initialized
			 */
			if (S_ISGITLINK(ce->ce_mode) &&
			    !is_empty_dir(ce->name)) {
				spf->result = 1;
				strbuf_addf(err,
					    _("Could not access submodule '%s'"),
					    ce->name);
			}
		}
-- snap --

As you can see, at that point, `is_empty_dir()` indicates that it is _no
longer empty_, which means that the recursive pull actually tried to
initialize it, and left things in a half-consistent state.

BTW I also think that Stefan's commit just made a bug very obvious that
had not mattered all that much before: it would seem that before that
commit, when the code tried to fetch a submodule, it would actually
fetch the super project (because it would discover the .git
file/directory, and as the inactive submodule does not have any, it
would have found the super project's).

In essence, I think that the report points out a very real bug, and this
bug should be fixed.

I _could_ imagine that it would be as easy as applying this patch (and
turning the provided reproducer into a regression test), then polishing
this with a nice commit message:

-- snip --
diff --git a/submodule.c b/submodule.c
index 0f199c51378..5694905610a 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1443,6 +1443,12 @@ static int get_next_submodule(struct child_process *cp,
 		task->repo = get_submodule_repo_for(spf->r, task->sub);
 		if (task->repo) {
 			struct strbuf submodule_prefix = STRBUF_INIT;
+
+			/* skip uninitialized submodule */
+			if (!file_exists(task->repo->gitdir) ||
+			    is_empty_dir(task->repo->gitdir))
+				continue;
+
 			child_process_init(cp);
 			cp->dir = task->repo->gitdir;
 			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
-- snap --

Any takers?

Ciao,
Johannes

^ permalink raw reply related	[relevance 9%]

* Re: Issue: "Could not access submodule" error when pulling recursively with Git 2.22.0
  @ 2019-10-23 10:04  8% ` SZEDER Gábor
  2019-10-25 12:41  9%   ` Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: SZEDER Gábor @ 2019-10-23 10:04 UTC (permalink / raw)
  To: Aleksey Mikhaylov; +Cc: git@vger.kernel.org

On Wed, Oct 23, 2019 at 07:22:12AM +0000, Aleksey Mikhaylov wrote:
> "Could not access submodule" error when pulling recursively with Git 2.22.0.
> This issue causes if there is submodule in submodule.

> Please use my simple test repository to reproduce the problem:
> https://github.com/agmikhailov/example2361.git
> 
> It is just an empty repository with one submodule (https://github.com/agmikhailov/example2361M1.git) 
> and one submodule of submodule (https://github.com/agmikhailov/example2361M2.git):
> 
> git clone https://github.com/agmikhailov/example2361.git
> cd example2361/
> git submodule init

According to the docs of 'git submodule init', it "initializes the
submodules recorded in the index".  Therefore, it can only initialize
the submodule in 'example2361M1', because at this point we have no
idea that there is a nested submodule in there.

  $ git submodule init
  Submodule 'example2361M1' (https://github.com/agmikhailov/example2361M1.git) registered for path 'example2361M1'

> git submodule update

This command clones 'example2361M1':

  $ git submodule update --recursive
  Cloning into '/tmp/example2361/example2361M1'...
  Submodule path 'example2361M1': checked out '6a9be24a1c0ebd44d91ae4dcf1fd62580b936540'

Only at this point can we finally see that there is a nested
submodule, and can initialize and clone it with:

  $ cd example2361M1
  $ git submodule init
  Submodule 'example2361M2' (https://github.com/agmikhailov/example2361M2.git) registered for path 'example2361M2'
  $ git submodule update
  Cloning into '/tmp/example2361/example2361M1/example2361M2'...
  Submodule path 'example2361M2': checked out '9ed39cf1fe0a8cf34e72d2e7ebff1ea9d4a63ac1'

> git pull --recurse-submodules=true

And after that:

  $ cd ../..
  $ git pull --recurse-submodules=true
  Fetching submodule example2361M1
  Fetching submodule example2361M1/example2361M2
  Already up to date.


> ACTUAL RESULT
> 
> "git --recurse-submodules=true" command fails with message "Could not access submodule":
> 
> $ git --recurse-submodules=true
> Fetching submodule example2361M1
> Could not access submodule 'example2361M2'
> 
> EXPECTED RESULT
> 
> All submodules are successfully updated by "git --recurse-submodules=true" command.
> 
> ADDITIONAL INFORMATION
> 
> Git version 2.20.1 does not have this problem. 
> So we had to downgrade Git to work with submodules.

The behavior was indeed different with v2.20.1, but that version
didn't show the behavior you expected.  When running your commands
with v2.20.1 I get:

  $ ~/src/git/bin-wrappers/git pull --recurse-submodules=true
  Fetching submodule example2361M1
  Already up to date.
  $ find example2361M1/example2361M2/
  example2361M1/example2361M2/

So while that 'git pull' didn't error out, it didn't even look at the
nested submodule, which is still uninitialized and empty.

FWIW, bisecting shows that the behavior changed with commit
a62387b3fc, but, unfortunately, the commit message doesn't seem to be
very helpful to me, but perhaps others with more experience with
submodules can make something out of it.

commit a62387b3fc9f5aeeb04a2db278121d33a9caafa7
Author: Stefan Beller <sbeller@google.com>
Date:   Wed Nov 28 16:27:55 2018 -0800

    submodule.c: fetch in submodules git directory instead of in worktree
    
    Keep the properties introduced in 10f5c52656 (submodule: avoid
    auto-discovery in prepare_submodule_repo_env(), 2016-09-01), by fixating
    the git directory of the submodule.
    
    Signed-off-by: Stefan Beller <sbeller@google.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

 submodule.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)



^ permalink raw reply	[relevance 8%]

* Re: Performance regression on git fetch in 2.21
  2019-05-24  9:14  6% Performance regression on git fetch in 2.21 Orgad Shaneh
@ 2019-06-10 13:55  0% ` Orgad Shaneh
  0 siblings, 0 replies; 200+ results
From: Orgad Shaneh @ 2019-06-10 13:55 UTC (permalink / raw)
  To: git

On Fri, May 24, 2019 at 12:14 PM Orgad Shaneh <orgads@gmail.com> wrote:
>
> Hi,
>
> git fetch in my repository *when nothing new is received* takes 2.5x
> the time when comparing 2.20 against 2.21 (on Windows it's 4x).
>
> I have 5 initialized submodules in this working directory.
>
> I reported this issue on git-for-windows github:
> https://github.com/git-for-windows/git/issues/2199 but there is also
> an upstream change related.
>
> I bisected and found this commit to blame:
>
> Building... Fetching... Failed [10.7949124]
> Bisecting: 0 revisions left to test after this (roughly 0 steps)
> [a62387b3fc9f5aeeb04a2db278121d33a9caafa7] submodule.c: fetch in
> submodules git directory instead of in worktree
> running git-bisect.rb
> Building... Fetching... Success [4.303592]
> be76c2128234d94b47f7087152ee55d08bb65d88 is the first bad commit
> commit be76c2128234d94b47f7087152ee55d08bb65d88
> Author: Stefan Beller <sbeller@google.com>
> Date:   Thu Dec 6 13:26:55 2018 -0800
>
>     fetch: ensure submodule objects fetched
>
>     Currently when git-fetch is asked to recurse into submodules, it dispatches
>     a plain "git-fetch -C <submodule-dir>" (with some submodule related options
>     such as prefix and recusing strategy, but) without any information of the
>     remote or the tip that should be fetched.
>
>     But this default fetch is not sufficient, as a newly fetched commit in
>     the superproject could point to a commit in the submodule that is not
>     in the default refspec. This is common in workflows like Gerrit's.
>     When fetching a Gerrit change under review (from refs/changes/??), the
>     commits in that change likely point to submodule commits that have not
>     been merged to a branch yet.
>
>     Fetch a submodule object by id if the object that the superproject
>     points to, cannot be found. For now this object is fetched from the
>     'origin' remote as we defer getting the default remote to a later patch.
>
>     A list of new submodule commits are already generated in certain
>     conditions (by check_for_new_submodule_commits()); this new feature
>     invokes that function in more situations.
>
>     The submodule checks were done only when a ref in the superproject
>     changed, these checks were extended to also be performed when fetching
>     into FETCH_HEAD for completeness, and add a test for that too.
>
>     Signed-off-by: Stefan Beller <sbeller@google.com>
>     Signed-off-by: Junio C Hamano <gitster@pobox.com>
>
> :040000 040000 2bad86c248b79ef1e36ea5edaa423cd73445c9a2
> ad989a8f3e6f80d4f5a84ec3db0ff1ab00a7e210 M      builtin
> :100644 100644 d1b6646f42d5d12740a94f50a7d25aad4aa356bf
> b88343d977d78364b417e2015eaa352dec1501b9 M      submodule.c
> :040000 040000 a3c58919de0796b6467709a0f21fa21e28d4d13b
> cdf9514c9085efcbfcdba8efc765174f6455ce5d M      t
>
> Can you please suggest a fix? Is this the expected behavior?
>
> Thanks,
> - Orgad

ping

- Orgad

^ permalink raw reply	[relevance 0%]

* Performance regression on git fetch in 2.21
@ 2019-05-24  9:14  6% Orgad Shaneh
  2019-06-10 13:55  0% ` Orgad Shaneh
  0 siblings, 1 reply; 200+ results
From: Orgad Shaneh @ 2019-05-24  9:14 UTC (permalink / raw)
  To: git, Stefan Beller

Hi,

git fetch in my repository *when nothing new is received* takes 2.5x
the time when comparing 2.20 against 2.21 (on Windows it's 4x).

I have 5 initialized submodules in this working directory.

I reported this issue on git-for-windows github:
https://github.com/git-for-windows/git/issues/2199 but there is also
an upstream change related.

I bisected and found this commit to blame:

Building... Fetching... Failed [10.7949124]
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[a62387b3fc9f5aeeb04a2db278121d33a9caafa7] submodule.c: fetch in
submodules git directory instead of in worktree
running git-bisect.rb
Building... Fetching... Success [4.303592]
be76c2128234d94b47f7087152ee55d08bb65d88 is the first bad commit
commit be76c2128234d94b47f7087152ee55d08bb65d88
Author: Stefan Beller <sbeller@google.com>
Date:   Thu Dec 6 13:26:55 2018 -0800

    fetch: ensure submodule objects fetched

    Currently when git-fetch is asked to recurse into submodules, it dispatches
    a plain "git-fetch -C <submodule-dir>" (with some submodule related options
    such as prefix and recusing strategy, but) without any information of the
    remote or the tip that should be fetched.

    But this default fetch is not sufficient, as a newly fetched commit in
    the superproject could point to a commit in the submodule that is not
    in the default refspec. This is common in workflows like Gerrit's.
    When fetching a Gerrit change under review (from refs/changes/??), the
    commits in that change likely point to submodule commits that have not
    been merged to a branch yet.

    Fetch a submodule object by id if the object that the superproject
    points to, cannot be found. For now this object is fetched from the
    'origin' remote as we defer getting the default remote to a later patch.

    A list of new submodule commits are already generated in certain
    conditions (by check_for_new_submodule_commits()); this new feature
    invokes that function in more situations.

    The submodule checks were done only when a ref in the superproject
    changed, these checks were extended to also be performed when fetching
    into FETCH_HEAD for completeness, and add a test for that too.

    Signed-off-by: Stefan Beller <sbeller@google.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

:040000 040000 2bad86c248b79ef1e36ea5edaa423cd73445c9a2
ad989a8f3e6f80d4f5a84ec3db0ff1ab00a7e210 M      builtin
:100644 100644 d1b6646f42d5d12740a94f50a7d25aad4aa356bf
b88343d977d78364b417e2015eaa352dec1501b9 M      submodule.c
:040000 040000 a3c58919de0796b6467709a0f21fa21e28d4d13b
cdf9514c9085efcbfcdba8efc765174f6455ce5d M      t

Can you please suggest a fix? Is this the expected behavior?

Thanks,
- Orgad

^ permalink raw reply	[relevance 6%]

* Git for Windows v2.21.0 due Tuesday, was Re: [ANNOUNCE] Git v2.21.0
  2019-02-24 18:17  3% [ANNOUNCE] Git v2.21.0 Junio C Hamano
@ 2019-02-24 22:32  0% ` Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2019-02-24 22:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, git-packagers, git-for-windows

[-- Attachment #1: Type: text/plain, Size: 24222 bytes --]

Team,

the corresponding Git for Windows v2.21.0 will probably be published on
Tuesday, as we are waiting for a Git LFS version that fixes a known
regression that is considered critical.

In the meantime, feel free to grab the current snapshot (which differs
from the final v2.21.0 probably only in the bundled Git LFS version and in
the output of `git version`):

	https://wingit.blob.core.windows.net/files/index.html

Oh, and if you can find any bug in that snapshot so that we can fix it in
time for Git for Windows v2.21.0: extra kudos to you!

Thanks,
Johannes


On Sun, 24 Feb 2019, Junio C Hamano wrote:

> The latest feature release Git v2.21.0 is now available at the
> usual places.  It is comprised of 500 non-merge commits since
> v2.20.0, contributed by 74 people, 20 of which are new faces.
> 
> The tarballs are found at:
> 
>     https://www.kernel.org/pub/software/scm/git/
> 
> The following public repositories all have a copy of the 'v2.21.0'
> tag and the 'master' branch that the tag points at:
> 
>   url = https://kernel.googlesource.com/pub/scm/git/git
>   url = git://repo.or.cz/alt-git.git
>   url = https://github.com/gitster/git
> 
> New contributors whose contributions weren't in v2.20.0 are as follows.
> Welcome to the Git development community!
> 
>   Alessandro Menti, Arti Zirk, Brandon Richardson, Chayoung
>   You, Denis Ovsienko, Emilio Cobos Álvarez, Erin Dahlgren,
>   Fabien Villepinte, Force Charlie, Frank Dana, Issac Trotts,
>   Katrin Leinweber, Laura Abbott, Patrick Hogg, Peter Osterlund,
>   Shahzad Lone, Slavica Djukic, Yoichi Nakayama, Zhilei Han, and
>   Tanushree Tumane.
> 
> Returning contributors who helped this release are as follows.
> Thanks for your continued support.
> 
>   Ævar Arnfjörð Bjarmason, Alexander Shopov, Ben Peart,
>   Brandon Williams, brian m. carlson, Carlo Marcelo Arenas Belón,
>   Christian Couder, Christopher Díaz Riveros, David Turner,
>   Derrick Stolee, Elijah Newren, Eric Sunshine, Eric Wong, Fangyi
>   Zhou, Jean-Noël Avila, Jeff King, Jiang Xin, Jimmy Angelakos,
>   Johannes Schindelin, Jonathan Nieder, Jonathan Tan, Jordi
>   Mas, Josh Steadmon, Junio C Hamano, Kevin Daudt, Kim Gybels,
>   Kyle Meyer, Linus Torvalds, Luke Diamand, Martin Ågren,
>   Masaya Suzuki, Matthew DeVore, Matthieu Moy, Max Kirillov,
>   Nguyễn Thái Ngọc Duy, Olga Telezhnaya, Orgad Shaneh, Peter
>   Krefting, Phillip Wood, Pranit Bauva, Ralf Thielow, Ramsay Jones,
>   Randall S. Becker, René Scharfe, Sebastian Staudt, Sergey
>   Organov, Stefan Beller, Stephen P. Smith, Sven van Haastregt,
>   SZEDER Gábor, Thomas Braun, Thomas Gummerer, Todd Zullinger,
>   and Torsten Bögershausen.
> 
> ----------------------------------------------------------------
> 
> Git 2.21 Release Notes
> ======================
> 
> Backward Compatibility Notes
> ----------------------------
> 
>  * Historically, the "-m" (mainline) option can only be used for "git
>    cherry-pick" and "git revert" when working with a merge commit.
>    This version of Git no longer warns or errors out when working with
>    a single-parent commit, as long as the argument to the "-m" option
>    is 1 (i.e. it has only one parent, and the request is to pick or
>    revert relative to that first parent).  Scripts that relied on the
>    behaviour may get broken with this change.
> 
> 
> Updates since v2.20
> -------------------
> 
> UI, Workflows & Features
> 
>  * The "http.version" configuration variable can be used with recent
>    enough versions of cURL library to force the version of HTTP used
>    to talk when fetching and pushing.
> 
>  * Small fixes and features for fast-export and fast-import, mostly on
>    the fast-export side has been made.
> 
>  * "git push $there $src:$dst" rejects when $dst is not a fully
>    qualified refname and it is not clear what the end user meant.  The
>    codepath has been taught to give a clearer error message, and also
>    guess where the push should go by taking the type of the pushed
>    object into account (e.g. a tag object would want to go under
>    refs/tags/).
> 
>  * "git checkout [<tree-ish>] path..." learned to report the number of
>    paths that have been checked out of the index or the tree-ish,
>    which gives it the same degree of noisy-ness as the case in which
>    the command checks out a branch.  "git checkout -m <pathspec>" to
>    undo conflict resolution gives a similar message.
> 
>  * "git quiltimport" learned "--keep-non-patch" option.
> 
>  * "git worktree remove" and "git worktree move" refused to work when
>    there is a submodule involved.  This has been loosened to ignore
>    uninitialized submodules.
> 
>  * "git cherry-pick -m1" was forbidden when picking a non-merge
>    commit, even though there _is_ parent number 1 for such a commit.
>    This was done to avoid mistakes back when "cherry-pick" was about
>    picking a single commit, but is no longer useful with "cherry-pick"
>    that can pick a range of commits.  Now the "-m$num" option is
>    allowed when picking any commit, as long as $num names an existing
>    parent of the commit.
> 
>  * Update "git multimail" from the upstream.
> 
>  * "git p4" update.
> 
>  * The "--format=<placeholder>" option of for-each-ref, branch and tag
>    learned to show a few more traits of objects that can be learned by
>    the object_info API.
> 
>  * "git rebase -i" learned to re-execute a command given with 'exec'
>    to run after it failed the last time.
> 
>  * "git diff --color-moved-ws" updates.
> 
>  * Custom userformat "log --format" learned %S atom that stands for
>    the tip the traversal reached the commit from, i.e. --source.
> 
>  * "git instaweb" learned to drive http.server that comes with
>    "batteries included" Python installation (both Python2 & 3).
> 
>  * A new encoding UTF-16LE-BOM has been invented to force encoding to
>    UTF-16 with BOM in little endian byte order, which cannot be directly
>    generated by using iconv.
> 
>  * A new date format "--date=human" that morphs its output depending
>    on how far the time is from the current time has been introduced.
>    "--date=auto:human" can be used to use this new format (or any
>    existing format) when the output is going to the pager or to the
>    terminal, and otherwise the default format.
> 
> 
> Performance, Internal Implementation, Development Support etc.
> 
>  * Code clean-up with optimization for the codepath that checks
>    (non-)existence of loose objects.
> 
>  * More codepaths have become aware of working with in-core repository
>    instances other than the default "the_repository".
> 
>  * The "strncat()" function is now among the banned functions.
> 
>  * Portability updates for the HPE NonStop platform.
> 
>  * Earlier we added "-Wformat-security" to developer builds, assuming
>    that "-Wall" (which includes "-Wformat" which in turn is required
>    to use "-Wformat-security") is always in effect.  This is not true
>    when config.mak.autogen is in use, unfortunately.  This has been
>    fixed by unconditionally adding "-Wall" to developer builds.
> 
>  * The loose object cache used to optimize existence look-up has been
>    updated.
> 
>  * Flaky tests can now be repeatedly run under load with the
>    "--stress" option.
> 
>  * Documentation/Makefile is getting prepared for manpage
>    localization.
> 
>  * "git fetch-pack" now can talk the version 2 protocol.
> 
>  * sha-256 hash has been added and plumbed through the code to allow
>    building Git with the "NewHash".
> 
>  * Debugging help for http transport.
> 
>  * "git fetch --deepen=<more>" has been corrected to work over v2
>    protocol.
> 
>  * The code to walk tree objects has been taught that we may be
>    working with object names that are not computed with SHA-1.
> 
>  * The in-core repository instances are passed through more codepaths.
> 
>  * Update the protocol message specification to allow only the limited
>    use of scaled quantities.  This is to ensure potential compatibility
>    issues will not get out of hand.
> 
>  * Micro-optimize the code that prepares commit objects to be walked
>    by "git rev-list" when the commit-graph is available.
> 
>  * "git fetch" and "git upload-pack" learned to send all exchanges over
>    the sideband channel while talking the v2 protocol.
> 
>  * The codepath to write out commit-graph has been optimized by
>    following the usual pattern of visiting objects in in-pack order.
> 
>  * The codepath to show progress meter while writing out commit-graph
>    file has been improved.
> 
>  * Cocci rules have been updated to encourage use of strbuf_addbuf().
> 
>  * "git rebase --merge" has been reimplemented by reusing the internal
>    machinery used for "git rebase -i".
> 
>  * More code in "git bisect" has been rewritten in C.
> 
>  * Instead of going through "git-rebase--am" scriptlet to use the "am"
>    backend, the built-in version of "git rebase" learned to drive the
>    "am" backend directly.
> 
>  * The assumption to work on the single "in-core index" instance has
>    been reduced from the library-ish part of the codebase.
> 
>  * The test lint learned to catch non-portable "sed" options.
> 
>  * "git pack-objects" learned another algorithm to compute the set of
>    objects to send, that trades the resulting packfile off to save
>    traversal cost to favor small pushes.
> 
>  * The travis CI scripts have been corrected to build Git with the
>    compiler(s) of our choice.
> 
>  * "git submodule update" learned to abort early when core.worktree
>    for the submodule is not set correctly to prevent spreading damage.
> 
>  * Test suite has been adjusted to run on Azure Pipeline.
> 
>  * Running "Documentation/doc-diff x" from anywhere other than the
>    top-level of the working tree did not show the usage string
>    correctly, which has been fixed.
> 
>  * Use of the sparse tool got easier to customize from the command
>    line to help developers.
> 
>  * A new target "coverage-prove" to run the coverage test under
>    "prove" has been added.
> 
>  * A flakey "p4" test has been removed.
> 
>  * The code and tests assume that the system supplied iconv() would
>    always use BOM in its output when asked to encode to UTF-16 (or
>    UTF-32), but apparently some implementations output big-endian
>    without BOM.  A compile-time knob has been added to help such
>    systems (e.g. NonStop) to add BOM to the output to increase
>    portability.
> 
> 
> Fixes since v2.20
> -----------------
> 
>  * Updates for corner cases in merge-recursive.
>    (merge cc4cb0902c en/merge-path-collision later to maint).
> 
>  * "git checkout frotz" (without any double-dash) avoids ambiguity by
>    making sure 'frotz' cannot be interpreted as a revision and as a
>    path at the same time.  This safety has been updated to check also
>    a unique remote-tracking branch 'frotz' in a remote, when dwimming
>    to create a local branch 'frotz' out of a remote-tracking branch
>    'frotz' from a remote.
>    (merge be4908f103 nd/checkout-dwim-fix later to maint).
> 
>  * Refspecs configured with "git -c var=val clone" did not propagate
>    to the resulting repository, which has been corrected.
>    (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).
> 
>  * A properly configured username/email is required under
>    user.useConfigOnly in order to create commits; now "git stash"
>    (even though it creates commit objects to represent stash entries)
>    command is exempt from the requirement.
>    (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).
> 
>  * The http-backend CGI process did not correctly clean up the child
>    processes it spawns to run upload-pack etc. when it dies itself,
>    which has been corrected.
>    (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).
> 
>  * "git rev-list --exclude-promisor-objects" had to take an object
>    that does not exist locally (and is lazily available) from the
>    command line without barfing, but the code dereferenced NULL.
>    (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).
> 
>  * The traversal over tree objects has learned to honor
>    ":(attr:label)" pathspec match, which has been implemented only for
>    enumerating paths on the filesystem.
>    (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).
> 
>  * BSD port updates.
>    (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
>    (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
>    (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).
> 
>  * Lines that begin with a certain keyword that come over the wire, as
>    well as lines that consist only of one of these keywords, ought to
>    be painted in color for easier eyeballing, but the latter was
>    broken ever since the feature was introduced in 2.19, which has
>    been corrected.
>    (merge 1f67290450 hn/highlight-sideband-keywords later to maint).
> 
>  * "git log -G<regex>" looked for a hunk in the "git log -p" patch
>    output that contained a string that matches the given pattern.
>    Optimize this code to ignore binary files, which by default will
>    not show any hunk that would match any pattern (unless textconv or
>    the --text option is in effect, that is).
>    (merge e0e7cb8080 tb/log-G-binary later to maint).
> 
>  * "git submodule update" ought to use a single job unless asked, but
>    by mistake used multiple jobs, which has been fixed.
>    (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).
> 
>  * "git stripspace" should be usable outside a git repository, but
>    under the "-s" or "-c" mode, it didn't.
>    (merge 957da75802 jn/stripspace-wo-repository later to maint).
> 
>  * Some of the documentation pages formatted incorrectly with
>    Asciidoctor, which have been fixed.
>    (merge b62eb1d2f4 ma/asciidoctor later to maint).
> 
>  * The core.worktree setting in a submodule repository should not be
>    pointing at a directory when the submodule loses its working tree
>    (e.g. getting deinit'ed), but the code did not properly maintain
>    this invariant.
> 
>  * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
>    when the completed path has a special character like SP in it,
>    without any attempt to keep "path name" a single filename.  This
>    has been fixed to complete it to "git cmd path\ name" just like
>    Bash completion does.
> 
>  * The test suite tried to see if it is run under bash, but the check
>    itself failed under some other implementations of shell (notably
>    under NetBSD).  This has been corrected.
>    (merge 54ea72f09c sg/test-bash-version-fix later to maint).
> 
>  * "git gc" and "git repack" did not close the open packfiles that
>    they found unneeded before removing them, which didn't work on a
>    platform incapable of removing an open file.  This has been
>    corrected.
>    (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).
> 
>  * The code to drive GIT_EXTERNAL_DIFF command relied on the string
>    returned from getenv() to be non-volatile, which is not true, that
>    has been corrected.
>    (merge 6776a84dae kg/external-diff-save-env later to maint).
> 
>  * There were many places the code relied on the string returned from
>    getenv() to be non-volatile, which is not true, that have been
>    corrected.
>    (merge 0da0e9268b jk/save-getenv-result later to maint).
> 
>  * The v2 upload-pack protocol implementation failed to honor
>    hidden-ref configuration, which has been corrected.
>    (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).
> 
>  * "git fetch --recurse-submodules" may not fetch the necessary commit
>    that is bound to the superproject, which is getting corrected.
>    (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).
> 
>  * "git rebase" internally runs "checkout" to switch between branches,
>    and the command used to call the post-checkout hook, but the
>    reimplementation stopped doing so, which is getting fixed.
> 
>  * "git add -e" got confused when the change it wants to let the user
>    edit is smaller than the previous change that was left over in a
>    temporary file.
>    (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).
> 
>  * "git p4" failed to update a shelved change when there were moved
>    files, which has been corrected.
>    (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).
> 
>  * The codepath to read from the commit-graph file attempted to read
>    past the end of it when the file's table-of-contents was corrupt.
> 
>  * The compat/obstack code had casts that -Wcast-function-type
>    compilation option found questionable.
>    (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).
> 
>  * An obvious typo in an assertion error message has been fixed.
>    (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).
> 
>  * In Git for Windows, "git clone \\server\share\path" etc. that uses
>    UNC paths from command line had bad interaction with its shell
>    emulation.
> 
>  * "git add --ignore-errors" did not work as advertised and instead
>    worked as an unintended synonym for "git add --renormalize", which
>    has been fixed.
>    (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).
> 
>  * On a case-insensitive filesystem, we failed to compare the part of
>    the path that is above the worktree directory in an absolute
>    pathname, which has been corrected.
> 
>  * Asking "git check-attr" about a macro (e.g. "binary") on a specific
>    path did not work correctly, even though "git check-attr -a" listed
>    such a macro correctly.  This has been corrected.
>    (merge 7b95849be4 jk/attr-macro-fix later to maint).
> 
>  * "git pack-objects" incorrectly used uninitialized mutex, which has
>    been corrected.
>    (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).
> 
>  * "git checkout -b <new> [HEAD]" to create a new branch from the
>    current commit and check it out ought to be a no-op in the index
>    and the working tree in normal cases, but there are corner cases
>    that do require updates to the index and the working tree.  Running
>    it immediately after "git clone --no-checkout" is one of these
>    cases that an earlier optimization kicked in incorrectly, which has
>    been fixed.
>    (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).
> 
>  * "git diff --color-moved --cc --stat -p" did not work well due to
>    funny interaction between a bug in color-moved and the rest, which
>    has been fixed.
>    (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).
> 
>  * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
>    started when modes of "git rebase" that implicitly uses the
>    machinery for the interactive rebase are run, which has been
>    corrected.
>    (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).
> 
>  * The commit-graph facility did not work when in-core objects that
>    are promoted from unknown type to commit (e.g. a commit that is
>    accessed via a tag that refers to it) were involved, which has been
>    corrected.
>    (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).
> 
>  * "git fetch" output cleanup.
>    (merge dc40b24df4 nd/fetch-compact-update later to maint).
> 
>  * "git cat-file --batch" reported a dangling symbolic link by
>    mistake, when it wanted to report that a given name is ambiguous.
> 
>  * Documentation around core.crlf has been updated.
>    (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).
> 
>  * The documentation of "git commit-tree" said that the command
>    understands "--gpg-sign" in addition to "-S", but the command line
>    parser did not know about the longhand, which has been corrected.
> 
>  * "git rebase -x $cmd" did not reject multi-line command, even though
>    the command is incapable of handling such a command.  It now is
>    rejected upfront.
>    (merge c762aada1a pw/rebase-x-sanity-check later to maint).
> 
>  * Output from "git help" was not correctly aligned, which has been
>    fixed.
>    (merge 6195a76da4 nd/help-align-command-desc later to maint).
> 
>  * The "git submodule summary" subcommand showed shortened commit
>    object names by mechanically truncating them at 7-hexdigit, which
>    has been improved to let "rev-parse --short" scale the length of
>    the abbreviation with the size of the repository.
>    (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).
> 
>  * The way the OSX build jobs updates its build environment used the
>    "--quiet" option to "brew update" command, but it wasn't all that
>    quiet to be useful.  The use of the option has been replaced with
>    an explicit redirection to the /dev/null (which incidentally would
>    have worked around a breakage by recent updates to homebrew, which
>    has fixed itself already).
>    (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).
> 
>  * "git --work-tree=$there --git-dir=$here describe --dirty" did not
>    work correctly as it did not pay attention to the location of the
>    worktree specified by the user by mistake, which has been
>    corrected.
>    (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).
> 
>  * "git fetch" over protocol v2 that needs to make a second connection
>    to backfill tags did not clear a variable that holds shallow
>    repository information correctly, leading to an access of freed
>    piece of memory.
> 
>  * Some errors from the other side coming over smart HTTP transport
>    were not noticed, which has been corrected.
> 
>  * Code cleanup, docfix, build fix, etc.
>    (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
>    (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
>    (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
>    (merge ec36c42a63 nd/indentation-fix later to maint).
>    (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
>    (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
>    (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
>    (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
>    (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
>    (merge 3b3357626e nd/style-opening-brace later to maint).
>    (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
>    (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
>    (merge 0650614982 cy/completion-typofix later to maint).
>    (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
>    (merge bd8d6f0def en/show-ref-doc-fix later to maint).
>    (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
>    (merge e01378753d cc/fetch-error-message-fix later to maint).
>    (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
>    (merge d609615f48 js/test-git-installed later to maint).
>    (merge ba170517be ja/doc-style-fix later to maint).
>    (merge 86fb1c4e77 km/init-doc-typofix later to maint).
>    (merge 5cfd4a9d10 nd/commit-doc later to maint).
>    (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).
>    (merge 2e285e7803 tz/gpg-test-fix later to maint).
>    (merge 5427de960b kl/pretty-doc-markup-fix later to maint).
>    (merge 3815f64b0d js/mingw-host-cpu later to maint).
>    (merge 5fe81438b5 rj/sequencer-sign-off-header-static later to maint).
>    (merge 18a4f6be6b nd/fileno-may-be-macro later to maint).
>    (merge 99e9ab54ab kd/t0028-octal-del-is-377-not-777 later to maint).
> 
> -- 
> You received this message because you are subscribed to the Google Groups "git-packagers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to git-packagers+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/git-packagers/xmqqtvgtkq46.fsf%40gitster-ct.c.googlers.com.
> For more options, visit https://groups.google.com/d/optout.
> 

^ permalink raw reply	[relevance 0%]

* [ANNOUNCE] Git v2.21.0
@ 2019-02-24 18:17  3% Junio C Hamano
  2019-02-24 22:32  0% ` Git for Windows v2.21.0 due Tuesday, was " Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2019-02-24 18:17 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

The latest feature release Git v2.21.0 is now available at the
usual places.  It is comprised of 500 non-merge commits since
v2.20.0, contributed by 74 people, 20 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/

The following public repositories all have a copy of the 'v2.21.0'
tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.20.0 are as follows.
Welcome to the Git development community!

  Alessandro Menti, Arti Zirk, Brandon Richardson, Chayoung
  You, Denis Ovsienko, Emilio Cobos Álvarez, Erin Dahlgren,
  Fabien Villepinte, Force Charlie, Frank Dana, Issac Trotts,
  Katrin Leinweber, Laura Abbott, Patrick Hogg, Peter Osterlund,
  Shahzad Lone, Slavica Djukic, Yoichi Nakayama, Zhilei Han, and
  Tanushree Tumane.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Alexander Shopov, Ben Peart,
  Brandon Williams, brian m. carlson, Carlo Marcelo Arenas Belón,
  Christian Couder, Christopher Díaz Riveros, David Turner,
  Derrick Stolee, Elijah Newren, Eric Sunshine, Eric Wong, Fangyi
  Zhou, Jean-Noël Avila, Jeff King, Jiang Xin, Jimmy Angelakos,
  Johannes Schindelin, Jonathan Nieder, Jonathan Tan, Jordi
  Mas, Josh Steadmon, Junio C Hamano, Kevin Daudt, Kim Gybels,
  Kyle Meyer, Linus Torvalds, Luke Diamand, Martin Ågren,
  Masaya Suzuki, Matthew DeVore, Matthieu Moy, Max Kirillov,
  Nguyễn Thái Ngọc Duy, Olga Telezhnaya, Orgad Shaneh, Peter
  Krefting, Phillip Wood, Pranit Bauva, Ralf Thielow, Ramsay Jones,
  Randall S. Becker, René Scharfe, Sebastian Staudt, Sergey
  Organov, Stefan Beller, Stephen P. Smith, Sven van Haastregt,
  SZEDER Gábor, Thomas Braun, Thomas Gummerer, Todd Zullinger,
  and Torsten Bögershausen.

----------------------------------------------------------------

Git 2.21 Release Notes
======================

Backward Compatibility Notes
----------------------------

 * Historically, the "-m" (mainline) option can only be used for "git
   cherry-pick" and "git revert" when working with a merge commit.
   This version of Git no longer warns or errors out when working with
   a single-parent commit, as long as the argument to the "-m" option
   is 1 (i.e. it has only one parent, and the request is to pick or
   revert relative to that first parent).  Scripts that relied on the
   behaviour may get broken with this change.


Updates since v2.20
-------------------

UI, Workflows & Features

 * The "http.version" configuration variable can be used with recent
   enough versions of cURL library to force the version of HTTP used
   to talk when fetching and pushing.

 * Small fixes and features for fast-export and fast-import, mostly on
   the fast-export side has been made.

 * "git push $there $src:$dst" rejects when $dst is not a fully
   qualified refname and it is not clear what the end user meant.  The
   codepath has been taught to give a clearer error message, and also
   guess where the push should go by taking the type of the pushed
   object into account (e.g. a tag object would want to go under
   refs/tags/).

 * "git checkout [<tree-ish>] path..." learned to report the number of
   paths that have been checked out of the index or the tree-ish,
   which gives it the same degree of noisy-ness as the case in which
   the command checks out a branch.  "git checkout -m <pathspec>" to
   undo conflict resolution gives a similar message.

 * "git quiltimport" learned "--keep-non-patch" option.

 * "git worktree remove" and "git worktree move" refused to work when
   there is a submodule involved.  This has been loosened to ignore
   uninitialized submodules.

 * "git cherry-pick -m1" was forbidden when picking a non-merge
   commit, even though there _is_ parent number 1 for such a commit.
   This was done to avoid mistakes back when "cherry-pick" was about
   picking a single commit, but is no longer useful with "cherry-pick"
   that can pick a range of commits.  Now the "-m$num" option is
   allowed when picking any commit, as long as $num names an existing
   parent of the commit.

 * Update "git multimail" from the upstream.

 * "git p4" update.

 * The "--format=<placeholder>" option of for-each-ref, branch and tag
   learned to show a few more traits of objects that can be learned by
   the object_info API.

 * "git rebase -i" learned to re-execute a command given with 'exec'
   to run after it failed the last time.

 * "git diff --color-moved-ws" updates.

 * Custom userformat "log --format" learned %S atom that stands for
   the tip the traversal reached the commit from, i.e. --source.

 * "git instaweb" learned to drive http.server that comes with
   "batteries included" Python installation (both Python2 & 3).

 * A new encoding UTF-16LE-BOM has been invented to force encoding to
   UTF-16 with BOM in little endian byte order, which cannot be directly
   generated by using iconv.

 * A new date format "--date=human" that morphs its output depending
   on how far the time is from the current time has been introduced.
   "--date=auto:human" can be used to use this new format (or any
   existing format) when the output is going to the pager or to the
   terminal, and otherwise the default format.


Performance, Internal Implementation, Development Support etc.

 * Code clean-up with optimization for the codepath that checks
   (non-)existence of loose objects.

 * More codepaths have become aware of working with in-core repository
   instances other than the default "the_repository".

 * The "strncat()" function is now among the banned functions.

 * Portability updates for the HPE NonStop platform.

 * Earlier we added "-Wformat-security" to developer builds, assuming
   that "-Wall" (which includes "-Wformat" which in turn is required
   to use "-Wformat-security") is always in effect.  This is not true
   when config.mak.autogen is in use, unfortunately.  This has been
   fixed by unconditionally adding "-Wall" to developer builds.

 * The loose object cache used to optimize existence look-up has been
   updated.

 * Flaky tests can now be repeatedly run under load with the
   "--stress" option.

 * Documentation/Makefile is getting prepared for manpage
   localization.

 * "git fetch-pack" now can talk the version 2 protocol.

 * sha-256 hash has been added and plumbed through the code to allow
   building Git with the "NewHash".

 * Debugging help for http transport.

 * "git fetch --deepen=<more>" has been corrected to work over v2
   protocol.

 * The code to walk tree objects has been taught that we may be
   working with object names that are not computed with SHA-1.

 * The in-core repository instances are passed through more codepaths.

 * Update the protocol message specification to allow only the limited
   use of scaled quantities.  This is to ensure potential compatibility
   issues will not get out of hand.

 * Micro-optimize the code that prepares commit objects to be walked
   by "git rev-list" when the commit-graph is available.

 * "git fetch" and "git upload-pack" learned to send all exchanges over
   the sideband channel while talking the v2 protocol.

 * The codepath to write out commit-graph has been optimized by
   following the usual pattern of visiting objects in in-pack order.

 * The codepath to show progress meter while writing out commit-graph
   file has been improved.

 * Cocci rules have been updated to encourage use of strbuf_addbuf().

 * "git rebase --merge" has been reimplemented by reusing the internal
   machinery used for "git rebase -i".

 * More code in "git bisect" has been rewritten in C.

 * Instead of going through "git-rebase--am" scriptlet to use the "am"
   backend, the built-in version of "git rebase" learned to drive the
   "am" backend directly.

 * The assumption to work on the single "in-core index" instance has
   been reduced from the library-ish part of the codebase.

 * The test lint learned to catch non-portable "sed" options.

 * "git pack-objects" learned another algorithm to compute the set of
   objects to send, that trades the resulting packfile off to save
   traversal cost to favor small pushes.

 * The travis CI scripts have been corrected to build Git with the
   compiler(s) of our choice.

 * "git submodule update" learned to abort early when core.worktree
   for the submodule is not set correctly to prevent spreading damage.

 * Test suite has been adjusted to run on Azure Pipeline.

 * Running "Documentation/doc-diff x" from anywhere other than the
   top-level of the working tree did not show the usage string
   correctly, which has been fixed.

 * Use of the sparse tool got easier to customize from the command
   line to help developers.

 * A new target "coverage-prove" to run the coverage test under
   "prove" has been added.

 * A flakey "p4" test has been removed.

 * The code and tests assume that the system supplied iconv() would
   always use BOM in its output when asked to encode to UTF-16 (or
   UTF-32), but apparently some implementations output big-endian
   without BOM.  A compile-time knob has been added to help such
   systems (e.g. NonStop) to add BOM to the output to increase
   portability.


Fixes since v2.20
-----------------

 * Updates for corner cases in merge-recursive.
   (merge cc4cb0902c en/merge-path-collision later to maint).

 * "git checkout frotz" (without any double-dash) avoids ambiguity by
   making sure 'frotz' cannot be interpreted as a revision and as a
   path at the same time.  This safety has been updated to check also
   a unique remote-tracking branch 'frotz' in a remote, when dwimming
   to create a local branch 'frotz' out of a remote-tracking branch
   'frotz' from a remote.
   (merge be4908f103 nd/checkout-dwim-fix later to maint).

 * Refspecs configured with "git -c var=val clone" did not propagate
   to the resulting repository, which has been corrected.
   (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).

 * A properly configured username/email is required under
   user.useConfigOnly in order to create commits; now "git stash"
   (even though it creates commit objects to represent stash entries)
   command is exempt from the requirement.
   (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).

 * The http-backend CGI process did not correctly clean up the child
   processes it spawns to run upload-pack etc. when it dies itself,
   which has been corrected.
   (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).

 * "git rev-list --exclude-promisor-objects" had to take an object
   that does not exist locally (and is lazily available) from the
   command line without barfing, but the code dereferenced NULL.
   (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).

 * The traversal over tree objects has learned to honor
   ":(attr:label)" pathspec match, which has been implemented only for
   enumerating paths on the filesystem.
   (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).

 * BSD port updates.
   (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
   (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
   (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).

 * Lines that begin with a certain keyword that come over the wire, as
   well as lines that consist only of one of these keywords, ought to
   be painted in color for easier eyeballing, but the latter was
   broken ever since the feature was introduced in 2.19, which has
   been corrected.
   (merge 1f67290450 hn/highlight-sideband-keywords later to maint).

 * "git log -G<regex>" looked for a hunk in the "git log -p" patch
   output that contained a string that matches the given pattern.
   Optimize this code to ignore binary files, which by default will
   not show any hunk that would match any pattern (unless textconv or
   the --text option is in effect, that is).
   (merge e0e7cb8080 tb/log-G-binary later to maint).

 * "git submodule update" ought to use a single job unless asked, but
   by mistake used multiple jobs, which has been fixed.
   (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).

 * "git stripspace" should be usable outside a git repository, but
   under the "-s" or "-c" mode, it didn't.
   (merge 957da75802 jn/stripspace-wo-repository later to maint).

 * Some of the documentation pages formatted incorrectly with
   Asciidoctor, which have been fixed.
   (merge b62eb1d2f4 ma/asciidoctor later to maint).

 * The core.worktree setting in a submodule repository should not be
   pointing at a directory when the submodule loses its working tree
   (e.g. getting deinit'ed), but the code did not properly maintain
   this invariant.

 * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
   when the completed path has a special character like SP in it,
   without any attempt to keep "path name" a single filename.  This
   has been fixed to complete it to "git cmd path\ name" just like
   Bash completion does.

 * The test suite tried to see if it is run under bash, but the check
   itself failed under some other implementations of shell (notably
   under NetBSD).  This has been corrected.
   (merge 54ea72f09c sg/test-bash-version-fix later to maint).

 * "git gc" and "git repack" did not close the open packfiles that
   they found unneeded before removing them, which didn't work on a
   platform incapable of removing an open file.  This has been
   corrected.
   (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).

 * The code to drive GIT_EXTERNAL_DIFF command relied on the string
   returned from getenv() to be non-volatile, which is not true, that
   has been corrected.
   (merge 6776a84dae kg/external-diff-save-env later to maint).

 * There were many places the code relied on the string returned from
   getenv() to be non-volatile, which is not true, that have been
   corrected.
   (merge 0da0e9268b jk/save-getenv-result later to maint).

 * The v2 upload-pack protocol implementation failed to honor
   hidden-ref configuration, which has been corrected.
   (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).

 * "git fetch --recurse-submodules" may not fetch the necessary commit
   that is bound to the superproject, which is getting corrected.
   (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).

 * "git rebase" internally runs "checkout" to switch between branches,
   and the command used to call the post-checkout hook, but the
   reimplementation stopped doing so, which is getting fixed.

 * "git add -e" got confused when the change it wants to let the user
   edit is smaller than the previous change that was left over in a
   temporary file.
   (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).

 * "git p4" failed to update a shelved change when there were moved
   files, which has been corrected.
   (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).

 * The codepath to read from the commit-graph file attempted to read
   past the end of it when the file's table-of-contents was corrupt.

 * The compat/obstack code had casts that -Wcast-function-type
   compilation option found questionable.
   (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).

 * An obvious typo in an assertion error message has been fixed.
   (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).

 * In Git for Windows, "git clone \\server\share\path" etc. that uses
   UNC paths from command line had bad interaction with its shell
   emulation.

 * "git add --ignore-errors" did not work as advertised and instead
   worked as an unintended synonym for "git add --renormalize", which
   has been fixed.
   (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).

 * On a case-insensitive filesystem, we failed to compare the part of
   the path that is above the worktree directory in an absolute
   pathname, which has been corrected.

 * Asking "git check-attr" about a macro (e.g. "binary") on a specific
   path did not work correctly, even though "git check-attr -a" listed
   such a macro correctly.  This has been corrected.
   (merge 7b95849be4 jk/attr-macro-fix later to maint).

 * "git pack-objects" incorrectly used uninitialized mutex, which has
   been corrected.
   (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).

 * "git checkout -b <new> [HEAD]" to create a new branch from the
   current commit and check it out ought to be a no-op in the index
   and the working tree in normal cases, but there are corner cases
   that do require updates to the index and the working tree.  Running
   it immediately after "git clone --no-checkout" is one of these
   cases that an earlier optimization kicked in incorrectly, which has
   been fixed.
   (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).

 * "git diff --color-moved --cc --stat -p" did not work well due to
   funny interaction between a bug in color-moved and the rest, which
   has been fixed.
   (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).

 * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
   started when modes of "git rebase" that implicitly uses the
   machinery for the interactive rebase are run, which has been
   corrected.
   (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).

 * The commit-graph facility did not work when in-core objects that
   are promoted from unknown type to commit (e.g. a commit that is
   accessed via a tag that refers to it) were involved, which has been
   corrected.
   (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).

 * "git fetch" output cleanup.
   (merge dc40b24df4 nd/fetch-compact-update later to maint).

 * "git cat-file --batch" reported a dangling symbolic link by
   mistake, when it wanted to report that a given name is ambiguous.

 * Documentation around core.crlf has been updated.
   (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).

 * The documentation of "git commit-tree" said that the command
   understands "--gpg-sign" in addition to "-S", but the command line
   parser did not know about the longhand, which has been corrected.

 * "git rebase -x $cmd" did not reject multi-line command, even though
   the command is incapable of handling such a command.  It now is
   rejected upfront.
   (merge c762aada1a pw/rebase-x-sanity-check later to maint).

 * Output from "git help" was not correctly aligned, which has been
   fixed.
   (merge 6195a76da4 nd/help-align-command-desc later to maint).

 * The "git submodule summary" subcommand showed shortened commit
   object names by mechanically truncating them at 7-hexdigit, which
   has been improved to let "rev-parse --short" scale the length of
   the abbreviation with the size of the repository.
   (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).

 * The way the OSX build jobs updates its build environment used the
   "--quiet" option to "brew update" command, but it wasn't all that
   quiet to be useful.  The use of the option has been replaced with
   an explicit redirection to the /dev/null (which incidentally would
   have worked around a breakage by recent updates to homebrew, which
   has fixed itself already).
   (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).

 * "git --work-tree=$there --git-dir=$here describe --dirty" did not
   work correctly as it did not pay attention to the location of the
   worktree specified by the user by mistake, which has been
   corrected.
   (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).

 * "git fetch" over protocol v2 that needs to make a second connection
   to backfill tags did not clear a variable that holds shallow
   repository information correctly, leading to an access of freed
   piece of memory.

 * Some errors from the other side coming over smart HTTP transport
   were not noticed, which has been corrected.

 * Code cleanup, docfix, build fix, etc.
   (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
   (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
   (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
   (merge ec36c42a63 nd/indentation-fix later to maint).
   (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
   (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
   (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
   (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
   (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
   (merge 3b3357626e nd/style-opening-brace later to maint).
   (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
   (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
   (merge 0650614982 cy/completion-typofix later to maint).
   (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
   (merge bd8d6f0def en/show-ref-doc-fix later to maint).
   (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
   (merge e01378753d cc/fetch-error-message-fix later to maint).
   (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
   (merge d609615f48 js/test-git-installed later to maint).
   (merge ba170517be ja/doc-style-fix later to maint).
   (merge 86fb1c4e77 km/init-doc-typofix later to maint).
   (merge 5cfd4a9d10 nd/commit-doc later to maint).
   (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).
   (merge 2e285e7803 tz/gpg-test-fix later to maint).
   (merge 5427de960b kl/pretty-doc-markup-fix later to maint).
   (merge 3815f64b0d js/mingw-host-cpu later to maint).
   (merge 5fe81438b5 rj/sequencer-sign-off-header-static later to maint).
   (merge 18a4f6be6b nd/fileno-may-be-macro later to maint).
   (merge 99e9ab54ab kd/t0028-octal-del-is-377-not-777 later to maint).

^ permalink raw reply	[relevance 3%]

* Git for Windows v2.21.0-rc2, was Re: [ANNOUNCE] Git v2.21.0-rc2
  2019-02-19 23:29  3% [ANNOUNCE] Git v2.21.0-rc2 Junio C Hamano
@ 2019-02-21 10:46  0% ` Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2019-02-21 10:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, git-packagers, git-for-windows

[-- Attachment #1: Type: text/plain, Size: 23761 bytes --]

Team,

the Git for Windows v2.21.0-rc pre-release followed suite last night:
https://github.com/git-for-windows/git/releases/tag/v2.21.0-rc2.windows.1

Please test (and don't worry when I don't reply during the next few days,
please, I'll reply, no worries).

Ciao,
Johannes

On Tue, 19 Feb 2019, Junio C Hamano wrote:

> A release candidate Git v2.21.0-rc2 is now available for testing
> at the usual places.  It is comprised of 474 non-merge commits
> since v2.20.0, contributed by 61 people, 16 of which are new faces.
> 
> The tarballs are found at:
> 
>     https://www.kernel.org/pub/software/scm/git/testing/
> 
> The following public repositories all have a copy of the
> 'v2.21.0-rc2' tag and the 'master' branch that the tag points at:
> 
>   url = https://kernel.googlesource.com/pub/scm/git/git
>   url = git://repo.or.cz/alt-git.git
>   url = https://github.com/gitster/git
> 
> New contributors whose contributions weren't in v2.20.0 are as follows.
> Welcome to the Git development community!
> 
>   Arti Zirk, Brandon Richardson, Chayoung You, Denis Ovsienko,
>   Emilio Cobos Álvarez, Erin Dahlgren, Force Charlie, Frank Dana,
>   Issac Trotts, Katrin Leinweber, Laura Abbott, Patrick Hogg,
>   Peter Osterlund, Shahzad Lone, Slavica Djukic, and Tanushree
>   Tumane.
> 
> Returning contributors who helped this release are as follows.
> Thanks for your continued support.
> 
>   Ævar Arnfjörð Bjarmason, Ben Peart, Brandon Williams, brian
>   m. carlson, Carlo Marcelo Arenas Belón, Christian Couder,
>   David Turner, Derrick Stolee, Elijah Newren, Eric Sunshine,
>   Eric Wong, Jean-Noël Avila, Jeff King, Johannes Schindelin,
>   Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano,
>   Kevin Daudt, Kim Gybels, Kyle Meyer, Linus Torvalds, Luke
>   Diamand, Martin Ågren, Masaya Suzuki, Matthew DeVore, Matthieu
>   Moy, Max Kirillov, Nguyễn Thái Ngọc Duy, Olga Telezhnaya,
>   Orgad Shaneh, Phillip Wood, Pranit Bauva, Ramsay Jones,
>   Randall S. Becker, René Scharfe, Sebastian Staudt, Sergey
>   Organov, Stefan Beller, Stephen P. Smith, Sven van Haastregt,
>   SZEDER Gábor, Thomas Braun, Thomas Gummerer, Todd Zullinger,
>   and Torsten Bögershausen.
> 
> ----------------------------------------------------------------
> 
> Git 2.21 Release Notes (draft)
> ==============================
> 
> Backward Compatibility Notes
> ----------------------------
> 
>  * Historically, the "-m" (mainline) option can only be used for "git
>    cherry-pick" and "git revert" when working with a merge commit.
>    This version of Git no longer warns or errors out when working with
>    a single-parent commit, as long as the argument to the "-m" option
>    is 1 (i.e. it has only one parent, and the request is to pick or
>    revert relative to that first parent).  Scripts that relied on the
>    behaviour may get broken with this change.
> 
> 
> Updates since v2.20
> -------------------
> 
> UI, Workflows & Features
> 
>  * The "http.version" configuration variable can be used with recent
>    enough versions of cURL library to force the version of HTTP used
>    to talk when fetching and pushing.
> 
>  * Small fixes and features for fast-export and fast-import, mostly on
>    the fast-export side has been made.
> 
>  * "git push $there $src:$dst" rejects when $dst is not a fully
>    qualified refname and it is not clear what the end user meant.  The
>    codepath has been taught to give a clearer error message, and also
>    guess where the push should go by taking the type of the pushed
>    object into account (e.g. a tag object would want to go under
>    refs/tags/).
> 
>  * "git checkout [<tree-ish>] path..." learned to report the number of
>    paths that have been checked out of the index or the tree-ish,
>    which gives it the same degree of noisy-ness as the case in which
>    the command checks out a branch.  "git checkout -m <pathspec>" to
>    undo conflict resolution gives a similar message.
> 
>  * "git quiltimport" learned "--keep-non-patch" option.
> 
>  * "git worktree remove" and "git worktree move" refused to work when
>    there is a submodule involved.  This has been loosened to ignore
>    uninitialized submodules.
> 
>  * "git cherry-pick -m1" was forbidden when picking a non-merge
>    commit, even though there _is_ parent number 1 for such a commit.
>    This was done to avoid mistakes back when "cherry-pick" was about
>    picking a single commit, but is no longer useful with "cherry-pick"
>    that can pick a range of commits.  Now the "-m$num" option is
>    allowed when picking any commit, as long as $num names an existing
>    parent of the commit.
> 
>  * Update "git multimail" from the upstream.
> 
>  * "git p4" update.
> 
>  * The "--format=<placeholder>" option of for-each-ref, branch and tag
>    learned to show a few more traits of objects that can be learned by
>    the object_info API.
> 
>  * "git rebase -i" learned to re-execute a command given with 'exec'
>    to run after it failed the last time.
> 
>  * "git diff --color-moved-ws" updates.
> 
>  * Custom userformat "log --format" learned %S atom that stands for
>    the tip the traversal reached the commit from, i.e. --source.
> 
>  * "git instaweb" learned to drive http.server that comes with
>    "batteries included" Python installation (both Python2 & 3).
> 
>  * A new encoding UTF-16LE-BOM has been invented to force encoding to
>    UTF-16 with BOM in little endian byte order, which cannot be directly
>    generated by using iconv.
> 
>  * A new date format "--date=human" that morphs its output depending
>    on how far the time is from the current time has been introduced.
>    "--date=auto:human" can be used to use this new format (or any
>    existing format) when the output is going to the pager or to the
>    terminal, and otherwise the default format.
> 
> 
> Performance, Internal Implementation, Development Support etc.
> 
>  * Code clean-up with optimization for the codepath that checks
>    (non-)existence of loose objects.
> 
>  * More codepaths have become aware of working with in-core repository
>    instances other than the default "the_repository".
> 
>  * The "strncat()" function is now among the banned functions.
> 
>  * Portability updates for the HPE NonStop platform.
> 
>  * Earlier we added "-Wformat-security" to developer builds, assuming
>    that "-Wall" (which includes "-Wformat" which in turn is required
>    to use "-Wformat-security") is always in effect.  This is not true
>    when config.mak.autogen is in use, unfortunately.  This has been
>    fixed by unconditionally adding "-Wall" to developer builds.
> 
>  * The loose object cache used to optimize existence look-up has been
>    updated.
> 
>  * Flaky tests can now be repeatedly run under load with the
>    "--stress" option.
> 
>  * Documentation/Makefile is getting prepared for manpage
>    localization.
> 
>  * "git fetch-pack" now can talk the version 2 protocol.
> 
>  * sha-256 hash has been added and plumbed through the code to allow
>    building Git with the "NewHash".
> 
>  * Debugging help for http transport.
> 
>  * "git fetch --deepen=<more>" has been corrected to work over v2
>    protocol.
> 
>  * The code to walk tree objects has been taught that we may be
>    working with object names that are not computed with SHA-1.
> 
>  * The in-core repository instances are passed through more codepaths.
> 
>  * Update the protocol message specification to allow only the limited
>    use of scaled quantities.  This is to ensure potential compatibility
>    issues will not get out of hand.
> 
>  * Micro-optimize the code that prepares commit objects to be walked
>    by "git rev-list" when the commit-graph is available.
> 
>  * "git fetch" and "git upload-pack" learned to send all exchanges over
>    the sideband channel while talking the v2 protocol.
> 
>  * The codepath to write out commit-graph has been optimized by
>    following the usual pattern of visiting objects in in-pack order.
> 
>  * The codepath to show progress meter while writing out commit-graph
>    file has been improved.
> 
>  * Cocci rules have been updated to encourage use of strbuf_addbuf().
> 
>  * "git rebase --merge" has been reimplemented by reusing the internal
>    machinery used for "git rebase -i".
> 
>  * More code in "git bisect" has been rewritten in C.
> 
>  * Instead of going through "git-rebase--am" scriptlet to use the "am"
>    backend, the built-in version of "git rebase" learned to drive the
>    "am" backend directly.
> 
>  * The assumption to work on the single "in-core index" instance has
>    been reduced from the library-ish part of the codebase.
> 
>  * The test lint learned to catch non-portable "sed" options.
> 
>  * "git pack-objects" learned another algorithm to compute the set of
>    objects to send, that trades the resulting packfile off to save
>    traversal cost to favor small pushes.
> 
>  * The travis CI scripts have been corrected to build Git with the
>    compiler(s) of our choice.
> 
>  * "git submodule update" learned to abort early when core.worktree
>    for the submodule is not set correctly to prevent spreading damage.
> 
>  * Test suite has been adjusted to run on Azure Pipeline.
> 
>  * Running "Documentation/doc-diff x" from anywhere other than the
>    top-level of the working tree did not show the usage string
>    correctly, which has been fixed.
> 
>  * Use of the sparse tool got easier to customize from the command
>    line to help developers.
> 
>  * A new target "coverage-prove" to run the coverage test under
>    "prove" has been added.
> 
>  * A flakey "p4" test has been removed.
> 
>  * The code and tests assume that the system supplied iconv() would
>    always use BOM in its output when asked to encode to UTF-16 (or
>    UTF-32), but apparently some implementations output big-endian
>    without BOM.  A compile-time knob has been added to help such
>    systems (e.g. NonStop) to add BOM to the output to increase
>    portability.
> 
> 
> Fixes since v2.20
> -----------------
> 
>  * Updates for corner cases in merge-recursive.
>    (merge cc4cb0902c en/merge-path-collision later to maint).
> 
>  * "git checkout frotz" (without any double-dash) avoids ambiguity by
>    making sure 'frotz' cannot be interpreted as a revision and as a
>    path at the same time.  This safety has been updated to check also
>    a unique remote-tracking branch 'frotz' in a remote, when dwimming
>    to create a local branch 'frotz' out of a remote-tracking branch
>    'frotz' from a remote.
>    (merge be4908f103 nd/checkout-dwim-fix later to maint).
> 
>  * Refspecs configured with "git -c var=val clone" did not propagate
>    to the resulting repository, which has been corrected.
>    (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).
> 
>  * A properly configured username/email is required under
>    user.useConfigOnly in order to create commits; now "git stash"
>    (even though it creates commit objects to represent stash entries)
>    command is exempt from the requirement.
>    (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).
> 
>  * The http-backend CGI process did not correctly clean up the child
>    processes it spawns to run upload-pack etc. when it dies itself,
>    which has been corrected.
>    (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).
> 
>  * "git rev-list --exclude-promisor-objects" had to take an object
>    that does not exist locally (and is lazily available) from the
>    command line without barfing, but the code dereferenced NULL.
>    (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).
> 
>  * The traversal over tree objects has learned to honor
>    ":(attr:label)" pathspec match, which has been implemented only for
>    enumerating paths on the filesystem.
>    (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).
> 
>  * BSD port updates.
>    (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
>    (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
>    (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).
> 
>  * Lines that begin with a certain keyword that come over the wire, as
>    well as lines that consist only of one of these keywords, ought to
>    be painted in color for easier eyeballing, but the latter was
>    broken ever since the feature was introduced in 2.19, which has
>    been corrected.
>    (merge 1f67290450 hn/highlight-sideband-keywords later to maint).
> 
>  * "git log -G<regex>" looked for a hunk in the "git log -p" patch
>    output that contained a string that matches the given pattern.
>    Optimize this code to ignore binary files, which by default will
>    not show any hunk that would match any pattern (unless textconv or
>    the --text option is in effect, that is).
>    (merge e0e7cb8080 tb/log-G-binary later to maint).
> 
>  * "git submodule update" ought to use a single job unless asked, but
>    by mistake used multiple jobs, which has been fixed.
>    (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).
> 
>  * "git stripspace" should be usable outside a git repository, but
>    under the "-s" or "-c" mode, it didn't.
>    (merge 957da75802 jn/stripspace-wo-repository later to maint).
> 
>  * Some of the documentation pages formatted incorrectly with
>    Asciidoctor, which have been fixed.
>    (merge b62eb1d2f4 ma/asciidoctor later to maint).
> 
>  * The core.worktree setting in a submodule repository should not be
>    pointing at a directory when the submodule loses its working tree
>    (e.g. getting deinit'ed), but the code did not properly maintain
>    this invariant.
> 
>  * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
>    when the completed path has a special character like SP in it,
>    without any attempt to keep "path name" a single filename.  This
>    has been fixed to complete it to "git cmd path\ name" just like
>    Bash completion does.
> 
>  * The test suite tried to see if it is run under bash, but the check
>    itself failed under some other implementations of shell (notably
>    under NetBSD).  This has been corrected.
>    (merge 54ea72f09c sg/test-bash-version-fix later to maint).
> 
>  * "git gc" and "git repack" did not close the open packfiles that
>    they found unneeded before removing them, which didn't work on a
>    platform incapable of removing an open file.  This has been
>    corrected.
>    (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).
> 
>  * The code to drive GIT_EXTERNAL_DIFF command relied on the string
>    returned from getenv() to be non-volatile, which is not true, that
>    has been corrected.
>    (merge 6776a84dae kg/external-diff-save-env later to maint).
> 
>  * There were many places the code relied on the string returned from
>    getenv() to be non-volatile, which is not true, that have been
>    corrected.
>    (merge 0da0e9268b jk/save-getenv-result later to maint).
> 
>  * The v2 upload-pack protocol implementation failed to honor
>    hidden-ref configuration, which has been corrected.
>    (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).
> 
>  * "git fetch --recurse-submodules" may not fetch the necessary commit
>    that is bound to the superproject, which is getting corrected.
>    (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).
> 
>  * "git rebase" internally runs "checkout" to switch between branches,
>    and the command used to call the post-checkout hook, but the
>    reimplementation stopped doing so, which is getting fixed.
> 
>  * "git add -e" got confused when the change it wants to let the user
>    edit is smaller than the previous change that was left over in a
>    temporary file.
>    (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).
> 
>  * "git p4" failed to update a shelved change when there were moved
>    files, which has been corrected.
>    (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).
> 
>  * The codepath to read from the commit-graph file attempted to read
>    past the end of it when the file's table-of-contents was corrupt.
> 
>  * The compat/obstack code had casts that -Wcast-function-type
>    compilation option found questionable.
>    (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).
> 
>  * An obvious typo in an assertion error message has been fixed.
>    (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).
> 
>  * In Git for Windows, "git clone \\server\share\path" etc. that uses
>    UNC paths from command line had bad interaction with its shell
>    emulation.
> 
>  * "git add --ignore-errors" did not work as advertised and instead
>    worked as an unintended synonym for "git add --renormalize", which
>    has been fixed.
>    (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).
> 
>  * On a case-insensitive filesystem, we failed to compare the part of
>    the path that is above the worktree directory in an absolute
>    pathname, which has been corrected.
> 
>  * Asking "git check-attr" about a macro (e.g. "binary") on a specific
>    path did not work correctly, even though "git check-attr -a" listed
>    such a macro correctly.  This has been corrected.
>    (merge 7b95849be4 jk/attr-macro-fix later to maint).
> 
>  * "git pack-objects" incorrectly used uninitialized mutex, which has
>    been corrected.
>    (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).
> 
>  * "git checkout -b <new> [HEAD]" to create a new branch from the
>    current commit and check it out ought to be a no-op in the index
>    and the working tree in normal cases, but there are corner cases
>    that do require updates to the index and the working tree.  Running
>    it immediately after "git clone --no-checkout" is one of these
>    cases that an earlier optimization kicked in incorrectly, which has
>    been fixed.
>    (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).
> 
>  * "git diff --color-moved --cc --stat -p" did not work well due to
>    funny interaction between a bug in color-moved and the rest, which
>    has been fixed.
>    (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).
> 
>  * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
>    started when modes of "git rebase" that implicitly uses the
>    machinery for the interactive rebase are run, which has been
>    corrected.
>    (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).
> 
>  * The commit-graph facility did not work when in-core objects that
>    are promoted from unknown type to commit (e.g. a commit that is
>    accessed via a tag that refers to it) were involved, which has been
>    corrected.
>    (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).
> 
>  * "git fetch" output cleanup.
>    (merge dc40b24df4 nd/fetch-compact-update later to maint).
> 
>  * "git cat-file --batch" reported a dangling symbolic link by
>    mistake, when it wanted to report that a given name is ambiguous.
> 
>  * Documentation around core.crlf has been updated.
>    (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).
> 
>  * The documentation of "git commit-tree" said that the command
>    understands "--gpg-sign" in addition to "-S", but the command line
>    parser did not know about the longhand, which has been corrected.
> 
>  * "git rebase -x $cmd" did not reject multi-line command, even though
>    the command is incapable of handling such a command.  It now is
>    rejected upfront.
>    (merge c762aada1a pw/rebase-x-sanity-check later to maint).
> 
>  * Output from "git help" was not correctly aligned, which has been
>    fixed.
>    (merge 6195a76da4 nd/help-align-command-desc later to maint).
> 
>  * The "git submodule summary" subcommand showed shortened commit
>    object names by mechanically truncating them at 7-hexdigit, which
>    has been improved to let "rev-parse --short" scale the length of
>    the abbreviation with the size of the repository.
>    (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).
> 
>  * The way the OSX build jobs updates its build environment used the
>    "--quiet" option to "brew update" command, but it wasn't all that
>    quiet to be useful.  The use of the option has been replaced with
>    an explicit redirection to the /dev/null (which incidentally would
>    have worked around a breakage by recent updates to homebrew, which
>    has fixed itself already).
>    (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).
> 
>  * "git --work-tree=$there --git-dir=$here describe --dirty" did not
>    work correctly as it did not pay attention to the location of the
>    worktree specified by the user by mistake, which has been
>    corrected.
>    (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).
> 
>  * "git fetch" over protocol v2 that needs to make a second connection
>    to backfill tags did not clear a variable that holds shallow
>    repository information correctly, leading to an access of freed
>    piece of memory.
> 
>  * Some errors from the other side coming over smart HTTP transport
>    were not noticed, which has been corrected.
> 
>  * Code cleanup, docfix, build fix, etc.
>    (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
>    (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
>    (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
>    (merge ec36c42a63 nd/indentation-fix later to maint).
>    (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
>    (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
>    (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
>    (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
>    (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
>    (merge 3b3357626e nd/style-opening-brace later to maint).
>    (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
>    (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
>    (merge 0650614982 cy/completion-typofix later to maint).
>    (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
>    (merge bd8d6f0def en/show-ref-doc-fix later to maint).
>    (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
>    (merge e01378753d cc/fetch-error-message-fix later to maint).
>    (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
>    (merge d609615f48 js/test-git-installed later to maint).
>    (merge ba170517be ja/doc-style-fix later to maint).
>    (merge 86fb1c4e77 km/init-doc-typofix later to maint).
>    (merge 5cfd4a9d10 nd/commit-doc later to maint).
>    (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).
>    (merge 2e285e7803 tz/gpg-test-fix later to maint).
>    (merge 5427de960b kl/pretty-doc-markup-fix later to maint).
>    (merge 3815f64b0d js/mingw-host-cpu later to maint).
>    (merge 5fe81438b5 rj/sequencer-sign-off-header-static later to maint).
>    (merge 18a4f6be6b nd/fileno-may-be-macro later to maint).
>    (merge 99e9ab54ab kd/t0028-octal-del-is-377-not-777 later to maint).
> 
> -- 
> You received this message because you are subscribed to the Google Groups "git-packagers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to git-packagers+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/git-packagers/xmqq8sybz7b2.fsf%40gitster-ct.c.googlers.com.
> For more options, visit https://groups.google.com/d/optout.
> 

^ permalink raw reply	[relevance 0%]

* [ANNOUNCE] Git v2.21.0-rc2
@ 2019-02-19 23:29  3% Junio C Hamano
  2019-02-21 10:46  0% ` Git for Windows v2.21.0-rc2, was " Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2019-02-19 23:29 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

A release candidate Git v2.21.0-rc2 is now available for testing
at the usual places.  It is comprised of 474 non-merge commits
since v2.20.0, contributed by 61 people, 16 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.21.0-rc2' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.20.0 are as follows.
Welcome to the Git development community!

  Arti Zirk, Brandon Richardson, Chayoung You, Denis Ovsienko,
  Emilio Cobos Álvarez, Erin Dahlgren, Force Charlie, Frank Dana,
  Issac Trotts, Katrin Leinweber, Laura Abbott, Patrick Hogg,
  Peter Osterlund, Shahzad Lone, Slavica Djukic, and Tanushree
  Tumane.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Ben Peart, Brandon Williams, brian
  m. carlson, Carlo Marcelo Arenas Belón, Christian Couder,
  David Turner, Derrick Stolee, Elijah Newren, Eric Sunshine,
  Eric Wong, Jean-Noël Avila, Jeff King, Johannes Schindelin,
  Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano,
  Kevin Daudt, Kim Gybels, Kyle Meyer, Linus Torvalds, Luke
  Diamand, Martin Ågren, Masaya Suzuki, Matthew DeVore, Matthieu
  Moy, Max Kirillov, Nguyễn Thái Ngọc Duy, Olga Telezhnaya,
  Orgad Shaneh, Phillip Wood, Pranit Bauva, Ramsay Jones,
  Randall S. Becker, René Scharfe, Sebastian Staudt, Sergey
  Organov, Stefan Beller, Stephen P. Smith, Sven van Haastregt,
  SZEDER Gábor, Thomas Braun, Thomas Gummerer, Todd Zullinger,
  and Torsten Bögershausen.

----------------------------------------------------------------

Git 2.21 Release Notes (draft)
==============================

Backward Compatibility Notes
----------------------------

 * Historically, the "-m" (mainline) option can only be used for "git
   cherry-pick" and "git revert" when working with a merge commit.
   This version of Git no longer warns or errors out when working with
   a single-parent commit, as long as the argument to the "-m" option
   is 1 (i.e. it has only one parent, and the request is to pick or
   revert relative to that first parent).  Scripts that relied on the
   behaviour may get broken with this change.


Updates since v2.20
-------------------

UI, Workflows & Features

 * The "http.version" configuration variable can be used with recent
   enough versions of cURL library to force the version of HTTP used
   to talk when fetching and pushing.

 * Small fixes and features for fast-export and fast-import, mostly on
   the fast-export side has been made.

 * "git push $there $src:$dst" rejects when $dst is not a fully
   qualified refname and it is not clear what the end user meant.  The
   codepath has been taught to give a clearer error message, and also
   guess where the push should go by taking the type of the pushed
   object into account (e.g. a tag object would want to go under
   refs/tags/).

 * "git checkout [<tree-ish>] path..." learned to report the number of
   paths that have been checked out of the index or the tree-ish,
   which gives it the same degree of noisy-ness as the case in which
   the command checks out a branch.  "git checkout -m <pathspec>" to
   undo conflict resolution gives a similar message.

 * "git quiltimport" learned "--keep-non-patch" option.

 * "git worktree remove" and "git worktree move" refused to work when
   there is a submodule involved.  This has been loosened to ignore
   uninitialized submodules.

 * "git cherry-pick -m1" was forbidden when picking a non-merge
   commit, even though there _is_ parent number 1 for such a commit.
   This was done to avoid mistakes back when "cherry-pick" was about
   picking a single commit, but is no longer useful with "cherry-pick"
   that can pick a range of commits.  Now the "-m$num" option is
   allowed when picking any commit, as long as $num names an existing
   parent of the commit.

 * Update "git multimail" from the upstream.

 * "git p4" update.

 * The "--format=<placeholder>" option of for-each-ref, branch and tag
   learned to show a few more traits of objects that can be learned by
   the object_info API.

 * "git rebase -i" learned to re-execute a command given with 'exec'
   to run after it failed the last time.

 * "git diff --color-moved-ws" updates.

 * Custom userformat "log --format" learned %S atom that stands for
   the tip the traversal reached the commit from, i.e. --source.

 * "git instaweb" learned to drive http.server that comes with
   "batteries included" Python installation (both Python2 & 3).

 * A new encoding UTF-16LE-BOM has been invented to force encoding to
   UTF-16 with BOM in little endian byte order, which cannot be directly
   generated by using iconv.

 * A new date format "--date=human" that morphs its output depending
   on how far the time is from the current time has been introduced.
   "--date=auto:human" can be used to use this new format (or any
   existing format) when the output is going to the pager or to the
   terminal, and otherwise the default format.


Performance, Internal Implementation, Development Support etc.

 * Code clean-up with optimization for the codepath that checks
   (non-)existence of loose objects.

 * More codepaths have become aware of working with in-core repository
   instances other than the default "the_repository".

 * The "strncat()" function is now among the banned functions.

 * Portability updates for the HPE NonStop platform.

 * Earlier we added "-Wformat-security" to developer builds, assuming
   that "-Wall" (which includes "-Wformat" which in turn is required
   to use "-Wformat-security") is always in effect.  This is not true
   when config.mak.autogen is in use, unfortunately.  This has been
   fixed by unconditionally adding "-Wall" to developer builds.

 * The loose object cache used to optimize existence look-up has been
   updated.

 * Flaky tests can now be repeatedly run under load with the
   "--stress" option.

 * Documentation/Makefile is getting prepared for manpage
   localization.

 * "git fetch-pack" now can talk the version 2 protocol.

 * sha-256 hash has been added and plumbed through the code to allow
   building Git with the "NewHash".

 * Debugging help for http transport.

 * "git fetch --deepen=<more>" has been corrected to work over v2
   protocol.

 * The code to walk tree objects has been taught that we may be
   working with object names that are not computed with SHA-1.

 * The in-core repository instances are passed through more codepaths.

 * Update the protocol message specification to allow only the limited
   use of scaled quantities.  This is to ensure potential compatibility
   issues will not get out of hand.

 * Micro-optimize the code that prepares commit objects to be walked
   by "git rev-list" when the commit-graph is available.

 * "git fetch" and "git upload-pack" learned to send all exchanges over
   the sideband channel while talking the v2 protocol.

 * The codepath to write out commit-graph has been optimized by
   following the usual pattern of visiting objects in in-pack order.

 * The codepath to show progress meter while writing out commit-graph
   file has been improved.

 * Cocci rules have been updated to encourage use of strbuf_addbuf().

 * "git rebase --merge" has been reimplemented by reusing the internal
   machinery used for "git rebase -i".

 * More code in "git bisect" has been rewritten in C.

 * Instead of going through "git-rebase--am" scriptlet to use the "am"
   backend, the built-in version of "git rebase" learned to drive the
   "am" backend directly.

 * The assumption to work on the single "in-core index" instance has
   been reduced from the library-ish part of the codebase.

 * The test lint learned to catch non-portable "sed" options.

 * "git pack-objects" learned another algorithm to compute the set of
   objects to send, that trades the resulting packfile off to save
   traversal cost to favor small pushes.

 * The travis CI scripts have been corrected to build Git with the
   compiler(s) of our choice.

 * "git submodule update" learned to abort early when core.worktree
   for the submodule is not set correctly to prevent spreading damage.

 * Test suite has been adjusted to run on Azure Pipeline.

 * Running "Documentation/doc-diff x" from anywhere other than the
   top-level of the working tree did not show the usage string
   correctly, which has been fixed.

 * Use of the sparse tool got easier to customize from the command
   line to help developers.

 * A new target "coverage-prove" to run the coverage test under
   "prove" has been added.

 * A flakey "p4" test has been removed.

 * The code and tests assume that the system supplied iconv() would
   always use BOM in its output when asked to encode to UTF-16 (or
   UTF-32), but apparently some implementations output big-endian
   without BOM.  A compile-time knob has been added to help such
   systems (e.g. NonStop) to add BOM to the output to increase
   portability.


Fixes since v2.20
-----------------

 * Updates for corner cases in merge-recursive.
   (merge cc4cb0902c en/merge-path-collision later to maint).

 * "git checkout frotz" (without any double-dash) avoids ambiguity by
   making sure 'frotz' cannot be interpreted as a revision and as a
   path at the same time.  This safety has been updated to check also
   a unique remote-tracking branch 'frotz' in a remote, when dwimming
   to create a local branch 'frotz' out of a remote-tracking branch
   'frotz' from a remote.
   (merge be4908f103 nd/checkout-dwim-fix later to maint).

 * Refspecs configured with "git -c var=val clone" did not propagate
   to the resulting repository, which has been corrected.
   (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).

 * A properly configured username/email is required under
   user.useConfigOnly in order to create commits; now "git stash"
   (even though it creates commit objects to represent stash entries)
   command is exempt from the requirement.
   (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).

 * The http-backend CGI process did not correctly clean up the child
   processes it spawns to run upload-pack etc. when it dies itself,
   which has been corrected.
   (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).

 * "git rev-list --exclude-promisor-objects" had to take an object
   that does not exist locally (and is lazily available) from the
   command line without barfing, but the code dereferenced NULL.
   (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).

 * The traversal over tree objects has learned to honor
   ":(attr:label)" pathspec match, which has been implemented only for
   enumerating paths on the filesystem.
   (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).

 * BSD port updates.
   (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
   (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
   (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).

 * Lines that begin with a certain keyword that come over the wire, as
   well as lines that consist only of one of these keywords, ought to
   be painted in color for easier eyeballing, but the latter was
   broken ever since the feature was introduced in 2.19, which has
   been corrected.
   (merge 1f67290450 hn/highlight-sideband-keywords later to maint).

 * "git log -G<regex>" looked for a hunk in the "git log -p" patch
   output that contained a string that matches the given pattern.
   Optimize this code to ignore binary files, which by default will
   not show any hunk that would match any pattern (unless textconv or
   the --text option is in effect, that is).
   (merge e0e7cb8080 tb/log-G-binary later to maint).

 * "git submodule update" ought to use a single job unless asked, but
   by mistake used multiple jobs, which has been fixed.
   (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).

 * "git stripspace" should be usable outside a git repository, but
   under the "-s" or "-c" mode, it didn't.
   (merge 957da75802 jn/stripspace-wo-repository later to maint).

 * Some of the documentation pages formatted incorrectly with
   Asciidoctor, which have been fixed.
   (merge b62eb1d2f4 ma/asciidoctor later to maint).

 * The core.worktree setting in a submodule repository should not be
   pointing at a directory when the submodule loses its working tree
   (e.g. getting deinit'ed), but the code did not properly maintain
   this invariant.

 * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
   when the completed path has a special character like SP in it,
   without any attempt to keep "path name" a single filename.  This
   has been fixed to complete it to "git cmd path\ name" just like
   Bash completion does.

 * The test suite tried to see if it is run under bash, but the check
   itself failed under some other implementations of shell (notably
   under NetBSD).  This has been corrected.
   (merge 54ea72f09c sg/test-bash-version-fix later to maint).

 * "git gc" and "git repack" did not close the open packfiles that
   they found unneeded before removing them, which didn't work on a
   platform incapable of removing an open file.  This has been
   corrected.
   (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).

 * The code to drive GIT_EXTERNAL_DIFF command relied on the string
   returned from getenv() to be non-volatile, which is not true, that
   has been corrected.
   (merge 6776a84dae kg/external-diff-save-env later to maint).

 * There were many places the code relied on the string returned from
   getenv() to be non-volatile, which is not true, that have been
   corrected.
   (merge 0da0e9268b jk/save-getenv-result later to maint).

 * The v2 upload-pack protocol implementation failed to honor
   hidden-ref configuration, which has been corrected.
   (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).

 * "git fetch --recurse-submodules" may not fetch the necessary commit
   that is bound to the superproject, which is getting corrected.
   (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).

 * "git rebase" internally runs "checkout" to switch between branches,
   and the command used to call the post-checkout hook, but the
   reimplementation stopped doing so, which is getting fixed.

 * "git add -e" got confused when the change it wants to let the user
   edit is smaller than the previous change that was left over in a
   temporary file.
   (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).

 * "git p4" failed to update a shelved change when there were moved
   files, which has been corrected.
   (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).

 * The codepath to read from the commit-graph file attempted to read
   past the end of it when the file's table-of-contents was corrupt.

 * The compat/obstack code had casts that -Wcast-function-type
   compilation option found questionable.
   (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).

 * An obvious typo in an assertion error message has been fixed.
   (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).

 * In Git for Windows, "git clone \\server\share\path" etc. that uses
   UNC paths from command line had bad interaction with its shell
   emulation.

 * "git add --ignore-errors" did not work as advertised and instead
   worked as an unintended synonym for "git add --renormalize", which
   has been fixed.
   (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).

 * On a case-insensitive filesystem, we failed to compare the part of
   the path that is above the worktree directory in an absolute
   pathname, which has been corrected.

 * Asking "git check-attr" about a macro (e.g. "binary") on a specific
   path did not work correctly, even though "git check-attr -a" listed
   such a macro correctly.  This has been corrected.
   (merge 7b95849be4 jk/attr-macro-fix later to maint).

 * "git pack-objects" incorrectly used uninitialized mutex, which has
   been corrected.
   (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).

 * "git checkout -b <new> [HEAD]" to create a new branch from the
   current commit and check it out ought to be a no-op in the index
   and the working tree in normal cases, but there are corner cases
   that do require updates to the index and the working tree.  Running
   it immediately after "git clone --no-checkout" is one of these
   cases that an earlier optimization kicked in incorrectly, which has
   been fixed.
   (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).

 * "git diff --color-moved --cc --stat -p" did not work well due to
   funny interaction between a bug in color-moved and the rest, which
   has been fixed.
   (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).

 * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
   started when modes of "git rebase" that implicitly uses the
   machinery for the interactive rebase are run, which has been
   corrected.
   (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).

 * The commit-graph facility did not work when in-core objects that
   are promoted from unknown type to commit (e.g. a commit that is
   accessed via a tag that refers to it) were involved, which has been
   corrected.
   (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).

 * "git fetch" output cleanup.
   (merge dc40b24df4 nd/fetch-compact-update later to maint).

 * "git cat-file --batch" reported a dangling symbolic link by
   mistake, when it wanted to report that a given name is ambiguous.

 * Documentation around core.crlf has been updated.
   (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).

 * The documentation of "git commit-tree" said that the command
   understands "--gpg-sign" in addition to "-S", but the command line
   parser did not know about the longhand, which has been corrected.

 * "git rebase -x $cmd" did not reject multi-line command, even though
   the command is incapable of handling such a command.  It now is
   rejected upfront.
   (merge c762aada1a pw/rebase-x-sanity-check later to maint).

 * Output from "git help" was not correctly aligned, which has been
   fixed.
   (merge 6195a76da4 nd/help-align-command-desc later to maint).

 * The "git submodule summary" subcommand showed shortened commit
   object names by mechanically truncating them at 7-hexdigit, which
   has been improved to let "rev-parse --short" scale the length of
   the abbreviation with the size of the repository.
   (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).

 * The way the OSX build jobs updates its build environment used the
   "--quiet" option to "brew update" command, but it wasn't all that
   quiet to be useful.  The use of the option has been replaced with
   an explicit redirection to the /dev/null (which incidentally would
   have worked around a breakage by recent updates to homebrew, which
   has fixed itself already).
   (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).

 * "git --work-tree=$there --git-dir=$here describe --dirty" did not
   work correctly as it did not pay attention to the location of the
   worktree specified by the user by mistake, which has been
   corrected.
   (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).

 * "git fetch" over protocol v2 that needs to make a second connection
   to backfill tags did not clear a variable that holds shallow
   repository information correctly, leading to an access of freed
   piece of memory.

 * Some errors from the other side coming over smart HTTP transport
   were not noticed, which has been corrected.

 * Code cleanup, docfix, build fix, etc.
   (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
   (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
   (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
   (merge ec36c42a63 nd/indentation-fix later to maint).
   (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
   (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
   (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
   (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
   (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
   (merge 3b3357626e nd/style-opening-brace later to maint).
   (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
   (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
   (merge 0650614982 cy/completion-typofix later to maint).
   (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
   (merge bd8d6f0def en/show-ref-doc-fix later to maint).
   (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
   (merge e01378753d cc/fetch-error-message-fix later to maint).
   (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
   (merge d609615f48 js/test-git-installed later to maint).
   (merge ba170517be ja/doc-style-fix later to maint).
   (merge 86fb1c4e77 km/init-doc-typofix later to maint).
   (merge 5cfd4a9d10 nd/commit-doc later to maint).
   (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).
   (merge 2e285e7803 tz/gpg-test-fix later to maint).
   (merge 5427de960b kl/pretty-doc-markup-fix later to maint).
   (merge 3815f64b0d js/mingw-host-cpu later to maint).
   (merge 5fe81438b5 rj/sequencer-sign-off-header-static later to maint).
   (merge 18a4f6be6b nd/fileno-may-be-macro later to maint).
   (merge 99e9ab54ab kd/t0028-octal-del-is-377-not-777 later to maint).

^ permalink raw reply	[relevance 3%]

* Re: [ANNOUNCE] Git v2.21.0-rc1
  2019-02-14  3:32  3% [ANNOUNCE] Git v2.21.0-rc1 Junio C Hamano
@ 2019-02-18 15:45  0% ` Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2019-02-18 15:45 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, git-packagers, git-for-windows

[-- Attachment #1: Type: text/plain, Size: 52637 bytes --]

Sorry for the late reply,

Git for Windows v2.21.0-rc1 is available (since Thursday night, actually)
from here:

    https://github.com/git-for-windows/git/releases/tag/v2.21.0-rc1.windows.1

I would be highly grateful for extensive testing, also for -rc2 (because
we just updated the MSYS2 runtime to be based on Cygwin v3.0.0) as soon as
that one comes out.

Thanks,
Johannes

On Wed, 13 Feb 2019, Junio C Hamano wrote:

> A release candidate Git v2.21.0-rc1 is now available for testing
> at the usual places.  It is comprised of 464 non-merge commits
> since v2.20.0, contributed by 60 people, 14 of which are new faces.
> 
> The tarballs are found at:
> 
>     https://www.kernel.org/pub/software/scm/git/testing/
> 
> The following public repositories all have a copy of the
> 'v2.21.0-rc1' tag and the 'master' branch that the tag points at:
> 
>   url = https://kernel.googlesource.com/pub/scm/git/git
>   url = git://repo.or.cz/alt-git.git
>   url = https://github.com/gitster/git
> 
> New contributors whose contributions weren't in v2.20.0 are as follows.
> Welcome to the Git development community!
> 
>   Arti Zirk, Brandon Richardson, Chayoung You, Denis Ovsienko,
>   Erin Dahlgren, Force Charlie, Frank Dana, Issac Trotts, Katrin
>   Leinweber, Laura Abbott, Patrick Hogg, Peter Osterlund, Shahzad
>   Lone, and Slavica Djukic.
> 
> Returning contributors who helped this release are as follows.
> Thanks for your continued support.
> 
>   Ævar Arnfjörð Bjarmason, Ben Peart, Brandon Williams, brian
>   m. carlson, Carlo Marcelo Arenas Belón, Christian Couder,
>   David Turner, Derrick Stolee, Elijah Newren, Eric Sunshine,
>   Eric Wong, Jean-Noël Avila, Jeff King, Johannes Schindelin,
>   Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano,
>   Kevin Daudt, Kim Gybels, Kyle Meyer, Linus Torvalds, Luke
>   Diamand, Martin Ågren, Masaya Suzuki, Matthew DeVore, Matthieu
>   Moy, Max Kirillov, Nguyễn Thái Ngọc Duy, Olga Telezhnaya,
>   Orgad Shaneh, Phillip Wood, Pranit Bauva, Ramsay Jones,
>   Randall S. Becker, René Scharfe, Sebastian Staudt, Sergey
>   Organov, Stefan Beller, Stephen P. Smith, Sven van Haastregt,
>   SZEDER Gábor, Thomas Braun, Thomas Gummerer, Todd Zullinger,
>   and Torsten Bögershausen.
> 
> ----------------------------------------------------------------
> 
> Git 2.21 Release Notes (draft)
> ==============================
> 
> Backward Compatibility Notes
> ----------------------------
> 
>  * Historically, the "-m" (mainline) option can only be used for "git
>    cherry-pick" and "git revert" when working with a merge commit.
>    This version of Git no longer warns or errors out when working with
>    a single-parent commit, as long as the argument to the "-m" option
>    is 1 (i.e. it has only one parent, and the request is to pick or
>    revert relative to that first parent).  Scripts that relied on the
>    behaviour may get broken with this change.
> 
> 
> Updates since v2.20
> -------------------
> 
> UI, Workflows & Features
> 
>  * The "http.version" configuration variable can be used with recent
>    enough versions of cURL library to force the version of HTTP used
>    to talk when fetching and pushing.
> 
>  * Small fixes and features for fast-export and fast-import, mostly on
>    the fast-export side has been made.
> 
>  * "git push $there $src:$dst" rejects when $dst is not a fully
>    qualified refname and it is not clear what the end user meant.  The
>    codepath has been taught to give a clearer error message, and also
>    guess where the push should go by taking the type of the pushed
>    object into account (e.g. a tag object would want to go under
>    refs/tags/).
> 
>  * "git checkout [<tree-ish>] path..." learned to report the number of
>    paths that have been checked out of the index or the tree-ish,
>    which gives it the same degree of noisy-ness as the case in which
>    the command checks out a branch.  "git checkout -m <pathspec>" to
>    undo conflict resolution gives a similar message.
> 
>  * "git quiltimport" learned "--keep-non-patch" option.
> 
>  * "git worktree remove" and "git worktree move" refused to work when
>    there is a submodule involved.  This has been loosened to ignore
>    uninitialized submodules.
> 
>  * "git cherry-pick -m1" was forbidden when picking a non-merge
>    commit, even though there _is_ parent number 1 for such a commit.
>    This was done to avoid mistakes back when "cherry-pick" was about
>    picking a single commit, but is no longer useful with "cherry-pick"
>    that can pick a range of commits.  Now the "-m$num" option is
>    allowed when picking any commit, as long as $num names an existing
>    parent of the commit.
> 
>  * Update "git multimail" from the upstream.
> 
>  * "git p4" update.
> 
>  * The "--format=<placeholder>" option of for-each-ref, branch and tag
>    learned to show a few more traits of objects that can be learned by
>    the object_info API.
> 
>  * "git rebase -i" learned to re-execute a command given with 'exec'
>    to run after it failed the last time.
> 
>  * "git diff --color-moved-ws" updates.
> 
>  * Custom userformat "log --format" learned %S atom that stands for
>    the tip the traversal reached the commit from, i.e. --source.
> 
>  * "git instaweb" learned to drive http.server that comes with
>    "batteries included" Python installation (both Python2 & 3).
> 
>  * A new encoding UTF-16LE-BOM has been invented to force encoding to
>    UTF-16 with BOM in little endian byte order, which cannot be directly
>    generated by using iconv.
> 
>  * A new date format "--date=human" that morphs its output depending
>    on how far the time is from the current time has been introduced.
>    "--date=auto:human" can be used to use this new format (or any
>    existing format) when the output is going to the pager or to the
>    terminal, and otherwise the default format.
> 
> 
> Performance, Internal Implementation, Development Support etc.
> 
>  * Code clean-up with optimization for the codepath that checks
>    (non-)existence of loose objects.
> 
>  * More codepaths have become aware of working with in-core repository
>    instances other than the default "the_repository".
> 
>  * The "strncat()" function is now among the banned functions.
> 
>  * Portability updates for the HPE NonStop platform.
> 
>  * Earlier we added "-Wformat-security" to developer builds, assuming
>    that "-Wall" (which includes "-Wformat" which in turn is required
>    to use "-Wformat-security") is always in effect.  This is not true
>    when config.mak.autogen is in use, unfortunately.  This has been
>    fixed by unconditionally adding "-Wall" to developer builds.
> 
>  * The loose object cache used to optimize existence look-up has been
>    updated.
> 
>  * Flaky tests can now be repeatedly run under load with the
>    "--stress" option.
> 
>  * Documentation/Makefile is getting prepared for manpage
>    localization.
> 
>  * "git fetch-pack" now can talk the version 2 protocol.
> 
>  * sha-256 hash has been added and plumbed through the code to allow
>    building Git with the "NewHash".
> 
>  * Debugging help for http transport.
> 
>  * "git fetch --deepen=<more>" has been corrected to work over v2
>    protocol.
> 
>  * The code to walk tree objects has been taught that we may be
>    working with object names that are not computed with SHA-1.
> 
>  * The in-core repository instances are passed through more codepaths.
> 
>  * Update the protocol message specification to allow only the limited
>    use of scaled quantities.  This is to ensure potential compatibility
>    issues will not get out of hand.
> 
>  * Micro-optimize the code that prepares commit objects to be walked
>    by "git rev-list" when the commit-graph is available.
> 
>  * "git fetch" and "git upload-pack" learned to send all exchanges over
>    the sideband channel while talking the v2 protocol.
> 
>  * The codepath to write out commit-graph has been optimized by
>    following the usual pattern of visiting objects in in-pack order.
> 
>  * The codepath to show progress meter while writing out commit-graph
>    file has been improved.
> 
>  * Cocci rules have been updated to encourage use of strbuf_addbuf().
> 
>  * "git rebase --merge" has been reimplemented by reusing the internal
>    machinery used for "git rebase -i".
> 
>  * More code in "git bisect" has been rewritten in C.
> 
>  * Instead of going through "git-rebase--am" scriptlet to use the "am"
>    backend, the built-in version of "git rebase" learned to drive the
>    "am" backend directly.
> 
>  * The assumption to work on the single "in-core index" instance has
>    been reduced from the library-ish part of the codebase.
> 
>  * The test lint learned to catch non-portable "sed" options.
> 
>  * "git pack-objects" learned another algorithm to compute the set of
>    objects to send, that trades the resulting packfile off to save
>    traversal cost to favor small pushes.
> 
>  * The travis CI scripts have been corrected to build Git with the
>    compiler(s) of our choice.
> 
>  * "git submodule update" learned to abort early when core.worktree
>    for the submodule is not set correctly to prevent spreading damage.
> 
>  * Test suite has been adjusted to run on Azure Pipeline.
> 
>  * Running "Documentation/doc-diff x" from anywhere other than the
>    top-level of the working tree did not show the usage string
>    correctly, which has been fixed.
> 
>  * Use of the sparse tool got easier to customize from the command
>    line to help developers.
> 
>  * A new target "coverage-prove" to run the coverage test under
>    "prove" has been added.
> 
>  * A flakey "p4" test has been removed.
> 
>  * The code and tests assume that the system supplied iconv() would
>    always use BOM in its output when asked to encode to UTF-16 (or
>    UTF-32), but apparently some implementations output big-endian
>    without BOM.  A compile-time knob has been added to help such
>    systems (e.g. NonStop) to add BOM to the output to increase
>    portability.
> 
> 
> Fixes since v2.20
> -----------------
> 
>  * Updates for corner cases in merge-recursive.
>    (merge cc4cb0902c en/merge-path-collision later to maint).
> 
>  * "git checkout frotz" (without any double-dash) avoids ambiguity by
>    making sure 'frotz' cannot be interpreted as a revision and as a
>    path at the same time.  This safety has been updated to check also
>    a unique remote-tracking branch 'frotz' in a remote, when dwimming
>    to create a local branch 'frotz' out of a remote-tracking branch
>    'frotz' from a remote.
>    (merge be4908f103 nd/checkout-dwim-fix later to maint).
> 
>  * Refspecs configured with "git -c var=val clone" did not propagate
>    to the resulting repository, which has been corrected.
>    (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).
> 
>  * A properly configured username/email is required under
>    user.useConfigOnly in order to create commits; now "git stash"
>    (even though it creates commit objects to represent stash entries)
>    command is exempt from the requirement.
>    (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).
> 
>  * The http-backend CGI process did not correctly clean up the child
>    processes it spawns to run upload-pack etc. when it dies itself,
>    which has been corrected.
>    (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).
> 
>  * "git rev-list --exclude-promisor-objects" had to take an object
>    that does not exist locally (and is lazily available) from the
>    command line without barfing, but the code dereferenced NULL.
>    (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).
> 
>  * The traversal over tree objects has learned to honor
>    ":(attr:label)" pathspec match, which has been implemented only for
>    enumerating paths on the filesystem.
>    (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).
> 
>  * BSD port updates.
>    (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
>    (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
>    (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).
> 
>  * Lines that begin with a certain keyword that come over the wire, as
>    well as lines that consist only of one of these keywords, ought to
>    be painted in color for easier eyeballing, but the latter was
>    broken ever since the feature was introduced in 2.19, which has
>    been corrected.
>    (merge 1f67290450 hn/highlight-sideband-keywords later to maint).
> 
>  * "git log -G<regex>" looked for a hunk in the "git log -p" patch
>    output that contained a string that matches the given pattern.
>    Optimize this code to ignore binary files, which by default will
>    not show any hunk that would match any pattern (unless textconv or
>    the --text option is in effect, that is).
>    (merge e0e7cb8080 tb/log-G-binary later to maint).
> 
>  * "git submodule update" ought to use a single job unless asked, but
>    by mistake used multiple jobs, which has been fixed.
>    (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).
> 
>  * "git stripspace" should be usable outside a git repository, but
>    under the "-s" or "-c" mode, it didn't.
>    (merge 957da75802 jn/stripspace-wo-repository later to maint).
> 
>  * Some of the documentation pages formatted incorrectly with
>    Asciidoctor, which have been fixed.
>    (merge b62eb1d2f4 ma/asciidoctor later to maint).
> 
>  * The core.worktree setting in a submodule repository should not be
>    pointing at a directory when the submodule loses its working tree
>    (e.g. getting deinit'ed), but the code did not properly maintain
>    this invariant.
> 
>  * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
>    when the completed path has a special character like SP in it,
>    without any attempt to keep "path name" a single filename.  This
>    has been fixed to complete it to "git cmd path\ name" just like
>    Bash completion does.
> 
>  * The test suite tried to see if it is run under bash, but the check
>    itself failed under some other implementations of shell (notably
>    under NetBSD).  This has been corrected.
>    (merge 54ea72f09c sg/test-bash-version-fix later to maint).
> 
>  * "git gc" and "git repack" did not close the open packfiles that
>    they found unneeded before removing them, which didn't work on a
>    platform incapable of removing an open file.  This has been
>    corrected.
>    (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).
> 
>  * The code to drive GIT_EXTERNAL_DIFF command relied on the string
>    returned from getenv() to be non-volatile, which is not true, that
>    has been corrected.
>    (merge 6776a84dae kg/external-diff-save-env later to maint).
> 
>  * There were many places the code relied on the string returned from
>    getenv() to be non-volatile, which is not true, that have been
>    corrected.
>    (merge 0da0e9268b jk/save-getenv-result later to maint).
> 
>  * The v2 upload-pack protocol implementation failed to honor
>    hidden-ref configuration, which has been corrected.
>    (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).
> 
>  * "git fetch --recurse-submodules" may not fetch the necessary commit
>    that is bound to the superproject, which is getting corrected.
>    (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).
> 
>  * "git rebase" internally runs "checkout" to switch between branches,
>    and the command used to call the post-checkout hook, but the
>    reimplementation stopped doing so, which is getting fixed.
> 
>  * "git add -e" got confused when the change it wants to let the user
>    edit is smaller than the previous change that was left over in a
>    temporary file.
>    (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).
> 
>  * "git p4" failed to update a shelved change when there were moved
>    files, which has been corrected.
>    (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).
> 
>  * The codepath to read from the commit-graph file attempted to read
>    past the end of it when the file's table-of-contents was corrupt.
> 
>  * The compat/obstack code had casts that -Wcast-function-type
>    compilation option found questionable.
>    (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).
> 
>  * An obvious typo in an assertion error message has been fixed.
>    (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).
> 
>  * In Git for Windows, "git clone \\server\share\path" etc. that uses
>    UNC paths from command line had bad interaction with its shell
>    emulation.
> 
>  * "git add --ignore-errors" did not work as advertised and instead
>    worked as an unintended synonym for "git add --renormalize", which
>    has been fixed.
>    (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).
> 
>  * On a case-insensitive filesystem, we failed to compare the part of
>    the path that is above the worktree directory in an absolute
>    pathname, which has been corrected.
> 
>  * Asking "git check-attr" about a macro (e.g. "binary") on a specific
>    path did not work correctly, even though "git check-attr -a" listed
>    such a macro correctly.  This has been corrected.
>    (merge 7b95849be4 jk/attr-macro-fix later to maint).
> 
>  * "git pack-objects" incorrectly used uninitialized mutex, which has
>    been corrected.
>    (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).
> 
>  * "git checkout -b <new> [HEAD]" to create a new branch from the
>    current commit and check it out ought to be a no-op in the index
>    and the working tree in normal cases, but there are corner cases
>    that do require updates to the index and the working tree.  Running
>    it immediately after "git clone --no-checkout" is one of these
>    cases that an earlier optimization kicked in incorrectly, which has
>    been fixed.
>    (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).
> 
>  * "git diff --color-moved --cc --stat -p" did not work well due to
>    funny interaction between a bug in color-moved and the rest, which
>    has been fixed.
>    (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).
> 
>  * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
>    started when modes of "git rebase" that implicitly uses the
>    machinery for the interactive rebase are run, which has been
>    corrected.
>    (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).
> 
>  * The commit-graph facility did not work when in-core objects that
>    are promoted from unknown type to commit (e.g. a commit that is
>    accessed via a tag that refers to it) were involved, which has been
>    corrected.
>    (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).
> 
>  * "git fetch" output cleanup.
>    (merge dc40b24df4 nd/fetch-compact-update later to maint).
> 
>  * "git cat-file --batch" reported a dangling symbolic link by
>    mistake, when it wanted to report that a given name is ambiguous.
> 
>  * Documentation around core.crlf has been updated.
>    (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).
> 
>  * The documentation of "git commit-tree" said that the command
>    understands "--gpg-sign" in addition to "-S", but the command line
>    parser did not know about the longhand, which has been corrected.
> 
>  * "git rebase -x $cmd" did not reject multi-line command, even though
>    the command is incapable of handling such a command.  It now is
>    rejected upfront.
>    (merge c762aada1a pw/rebase-x-sanity-check later to maint).
> 
>  * Output from "git help" was not correctly aligned, which has been
>    fixed.
>    (merge 6195a76da4 nd/help-align-command-desc later to maint).
> 
>  * The "git submodule summary" subcommand showed shortened commit
>    object names by mechanically truncating them at 7-hexdigit, which
>    has been improved to let "rev-parse --short" scale the length of
>    the abbreviation with the size of the repository.
>    (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).
> 
>  * The way the OSX build jobs updates its build environment used the
>    "--quiet" option to "brew update" command, but it wasn't all that
>    quiet to be useful.  The use of the option has been replaced with
>    an explicit redirection to the /dev/null (which incidentally would
>    have worked around a breakage by recent updates to homebrew, which
>    has fixed itself already).
>    (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).
> 
>  * "git --work-tree=$there --git-dir=$here describe --dirty" did not
>    work correctly as it did not pay attention to the location of the
>    worktree specified by the user by mistake, which has been
>    corrected.
>    (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).
> 
>  * "git fetch" over protocol v2 that needs to make a second connection
>    to backfill tags did not clear a variable that holds shallow
>    repository information correctly, leading to an access of freed
>    piece of memory.
> 
>  * Some errors from the other side coming over smart HTTP transport
>    were not noticed, which has been corrected.
> 
>  * Code cleanup, docfix, build fix, etc.
>    (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
>    (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
>    (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
>    (merge ec36c42a63 nd/indentation-fix later to maint).
>    (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
>    (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
>    (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
>    (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
>    (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
>    (merge 3b3357626e nd/style-opening-brace later to maint).
>    (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
>    (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
>    (merge 0650614982 cy/completion-typofix later to maint).
>    (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
>    (merge bd8d6f0def en/show-ref-doc-fix later to maint).
>    (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
>    (merge e01378753d cc/fetch-error-message-fix later to maint).
>    (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
>    (merge d609615f48 js/test-git-installed later to maint).
>    (merge ba170517be ja/doc-style-fix later to maint).
>    (merge 86fb1c4e77 km/init-doc-typofix later to maint).
>    (merge 5cfd4a9d10 nd/commit-doc later to maint).
>    (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).
>    (merge 2e285e7803 tz/gpg-test-fix later to maint).
>    (merge 5427de960b kl/pretty-doc-markup-fix later to maint).
>    (merge 3815f64b0d js/mingw-host-cpu later to maint).
>    (merge 5fe81438b5 rj/sequencer-sign-off-header-static later to maint).
>    (merge 18a4f6be6b nd/fileno-may-be-macro later to maint).
>    (merge 99e9ab54ab kd/t0028-octal-del-is-377-not-777 later to maint).
> 
> ----------------------------------------------------------------
> 
> Changes since v2.20.0 are as follows:
> 
> Arti Zirk (1):
>       git-instaweb: add Python builtin http.server support
> 
> Ben Peart (2):
>       checkout: add test demonstrating regression with checkout -b on initial commit
>       checkout: fix regression in checkout -b on intitial checkout
> 
> Brandon Richardson (1):
>       commit-tree: add missing --gpg-sign flag
> 
> Brandon Williams (1):
>       mailmap: update brandon williams's email address
> 
> Carlo Marcelo Arenas Belón (4):
>       t6036: avoid non-portable "cp -a"
>       tests: add lint for non portable cp -a
>       t5004: avoid using tar for empty packages
>       config.mak.uname: OpenBSD uses BSD semantics with fread for directories
> 
> Chayoung You (3):
>       zsh: complete unquoted paths with spaces correctly
>       completion: treat results of git ls-tree as file paths
>       completion: fix typo in git-completion.bash
> 
> Christian Couder (3):
>       fetch: fix extensions.partialclone name in error message
>       partial-clone: add missing 'is' in doc
>       helper/test-ref-store: fix "new-sha1" vs "old-sha1" typo
> 
> David Turner (1):
>       Do not print 'dangling' for cat-file in case of ambiguity
> 
> Denis Ovsienko (1):
>       docs: fix $strict_export text in gitweb.conf.txt
> 
> Derrick Stolee (10):
>       merge-recursive: combine error handling
>       .gitattributes: ensure t/oid-info/* has eol=lf
>       commit-graph: writing missing parents is a BUG
>       git-gc.txt: fix typo about gc.writeCommitGraph
>       revision: add mark_tree_uninteresting_sparse
>       list-objects: consume sparse tree walk
>       revision: implement sparse algorithm
>       pack-objects: create pack.useSparse setting
>       pack-objects: create GIT_TEST_PACK_SPARSE
>       Makefile: add coverage-prove target
> 
> Elijah Newren (30):
>       t6042: add tests for consistency in file collision conflict handling
>       t6036, t6042: testcases for rename collision of already conflicting files
>       merge-recursive: increase marker length with depth of recursion
>       merge-recursive: new function for better colliding conflict resolutions
>       merge-recursive: fix rename/add conflict handling
>       merge-recursive: improve handling for rename/rename(2to1) conflicts
>       merge-recursive: use handle_file_collision for add/add conflicts
>       merge-recursive: improve rename/rename(1to2)/add[/add] handling
>       t6036, t6043: increase code coverage for file collision handling
>       fast-export: convert sha1 to oid
>       git-fast-import.txt: fix documentation for --quiet option
>       git-fast-export.txt: clarify misleading documentation about rev-list args
>       fast-export: use value from correct enum
>       fast-export: avoid dying when filtering by paths and old tags exist
>       fast-export: move commit rewriting logic into a function for reuse
>       fast-export: when using paths, avoid corrupt stream with non-existent mark
>       fast-export: ensure we export requested refs
>       fast-export: add --reference-excluded-parents option
>       fast-import: remove unmaintained duplicate documentation
>       fast-export: add a --show-original-ids option to show original names
>       git-rebase.txt: update note about directory rename detection and am
>       rebase: make builtin and legacy script error messages the same
>       rebase: fix incompatible options error message
>       t5407: add a test demonstrating how interactive handles --skip differently
>       am, rebase--merge: do not overlook --skip'ed commits with post-rewrite
>       git-rebase, sequencer: extend --quiet option for the interactive machinery
>       git-legacy-rebase: simplify unnecessary triply-nested if
>       rebase: define linearization ordering and enforce it
>       rebase: implement --merge via the interactive machinery
>       git-show-ref.txt: fix order of flags
> 
> Eric Sunshine (1):
>       doc/config: do a better job of introducing 'worktree.guessRemote'
> 
> Eric Wong (2):
>       banned.h: mark strncat() as banned
>       t1512: test ambiguous cat-file --batch and --batch-output
> 
> Erin Dahlgren (1):
>       Simplify handling of setup_git_directory_gently() failure cases.
> 
> Force Charlie (1):
>       http: add support selecting http version
> 
> Frank Dana (1):
>       docs/gitweb.conf: config variable typo
> 
> Issac Trotts (1):
>       log: add %S option (like --source) to log --format
> 
> Jean-Noël Avila (3):
>       Documentation/Makefile add optional targets for l10n
>       doc: tidy asciidoc style
>       Fix typos in translatable strings for v2.21.0
> 
> Jeff King (54):
>       fsck: do not reuse child_process structs
>       submodule--helper: prefer strip_suffix() to ends_with()
>       rename "alternate_object_database" to "object_directory"
>       sha1_file_name(): overwrite buffer instead of appending
>       handle alternates paths the same as the main object dir
>       sha1-file: use an object_directory for the main object dir
>       object-store: provide helpers for loose_objects_cache
>       sha1-file: use loose object cache for quick existence check
>       fetch-pack: drop custom loose object cache
>       odb_load_loose_cache: fix strbuf leak
>       transport-helper: drop read/write errno checks
>       sha1-file: fix outdated sha1 comment references
>       update comment references to sha1_object_info()
>       http: use struct object_id instead of bare sha1
>       sha1-file: modernize loose object file functions
>       sha1-file: modernize loose header/stream functions
>       sha1-file: convert pass-through functions to object_id
>       convert has_sha1_file() callers to has_object_file()
>       sha1-file: drop has_sha1_file()
>       sha1-file: prefer "loose object file" to "sha1 file" in messages
>       sha1-file: avoid "sha1 file" for generic use in messages
>       prefer "hash mismatch" to "sha1 mismatch"
>       upload-pack: support hidden refs with protocol v2
>       remote: check config validity before creating rewrite struct
>       get_super_prefix(): copy getenv() result
>       commit: copy saved getenv() result
>       config: make a copy of $GIT_CONFIG string
>       init: make a copy of $GIT_DIR string
>       merge-recursive: copy $GITHEAD strings
>       builtin_diff(): read $GIT_DIFF_OPTS closer to use
>       add: use separate ADD_CACHE_RENORMALIZE flag
>       attr: do not mark queried macros as unset
>       t4006: resurrect commented-out tests
>       diff: clear emitted_symbols flag after use
>       combine-diff: factor out stat-format mask
>       combine-diff: treat --shortstat like --stat
>       combine-diff: treat --summary like --stat
>       combine-diff: treat --dirstat like --stat
>       match-trees: drop unused path parameter from score functions
>       apply: drop unused "def" parameter from find_name_gnu()
>       create_bundle(): drop unused "header" parameter
>       column: drop unused "opts" parameter in item_length()
>       show_date_relative(): drop unused "tz" parameter
>       config: drop unused parameter from maybe_remove_section()
>       convert: drop len parameter from conversion checks
>       convert: drop path parameter from actual conversion functions
>       doc/gitattributes: clarify "autocrlf overrides eol"
>       docs/config: clarify "text property" in core.eol
>       test-date: drop unused parameter to getnanos()
>       remote-curl: refactor smart-http discovery
>       remote-curl: tighten "version 2" check for smart-http
>       add_to_index(): convert forgotten HASH_RENORMALIZE check
>       RelNotes/2.21: tweak "--date=auto" mention
>       RelNotes/2.21: misc typo/English fixups
> 
> Johannes Schindelin (43):
>       rebase: introduce --reschedule-failed-exec
>       rebase: add a config option to default to --reschedule-failed-exec
>       rebase: introduce a shortcut for --reschedule-failed-exec
>       help.h: fix coding style
>       help -a: handle aliases with long names gracefully
>       t4256: mark support files as LF-only
>       t9902: 'send-email' test case requires PERL
>       gc/repack: release packs when needed
>       add --edit: truncate the patch file
>       t6042: work around speed optimization on Windows
>       abspath_part_inside_repo: respect core.ignoreCase
>       rebase: move `reset_head()` into a better spot
>       rebase: avoid double reflog entry when switching branches
>       rebase: teach `reset_head()` to optionally skip the worktree
>       built-in rebase: call `git am` directly
>       mingw (t5580): document bug when cloning from backslashed UNC paths
>       mingw: special-case arguments to `sh`
>       tests: explicitly use `test-tool.exe` on Windows
>       travis: fix skipping tagged releases
>       ci: rename the library of common functions
>       ci/lib.sh: encapsulate Travis-specific things
>       ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
>       ci: use a junction on Windows instead of a symlink
>       test-date: add a subcommand to measure times in shell scripts
>       tests: optionally write results as JUnit-style .xml
>       ci/lib.sh: add support for Azure Pipelines
>       Add a build definition for Azure DevOps
>       ci: add a Windows job to the Azure Pipelines definition
>       ci: use git-sdk-64-minimal build artifact
>       mingw: be more generous when wrapping up the setitimer() emulation
>       README: add a build badge (status of the Azure Pipelines build)
>       tests: avoid calling Perl just to determine file sizes
>       tests: include detailed trace logs with --write-junit-xml upon failure
>       mingw: try to work around issues with the test cleanup
>       tests: add t/helper/ to the PATH with --with-dashes
>       t0061: workaround issues with --with-dashes and RUNTIME_PREFIX
>       tests: optionally skip bin-wrappers/
>       ci: speed up Windows phase
>       ci: parallelize testing on Windows
>       Revert "rebase: introduce a shortcut for --reschedule-failed-exec"
>       mingw: fix CPU reporting in `git version --build-options`
>       .mailmap: map Clemens Buchacher's mail addresses
>       mingw: use a more canonical method to fix the CPU reporting
> 
> Jonathan Nieder (1):
>       stripspace: allow -s/-c outside git repository
> 
> Jonathan Tan (9):
>       revision: use commit graph in get_reference()
>       fetch-pack: support protocol version 2
>       fetch-pack: do not take shallow lock unnecessarily
>       upload-pack: teach deepen-relative in protocol v2
>       pkt-line: introduce struct packet_writer
>       sideband: reverse its dependency on pkt-line
>       {fetch,upload}-pack: sideband v2 fetch response
>       tests: define GIT_TEST_SIDEBAND_ALL
>       ls-refs: filter refs using namespace-stripped name
> 
> Josh Steadmon (7):
>       filter-options: expand scaled numbers
>       commit-graph, fuzz: add fuzzer for commit-graph
>       commit-graph: fix buffer read-overflow
>       Makefile: correct example fuzz build
>       t5551: test server-side ERR packet
>       fuzz-commit-graph: initialize repo object
>       object: fix leak of shallow_stat
> 
> Junio C Hamano (16):
>       t0027: squelch checkout path run outside test_expect_* block
>       t0061: do not fail test if '.' is part of $PATH
>       run-command: report exec failure
>       submodule update: run at most one fetch job unless otherwise set
>       Git 2.20.1
>       Prepare for 2.21 cycle to start soonish
>       First batch after 2.20.1
>       ref-filter: give uintmax_t to format with %PRIuMAX
>       Second batch after 2.20
>       Third batch after 2.20
>       Fourth batch after 2.20
>       Fifth batch for 2.21
>       Git 2.21-rc0
>       ci: clear and mark MAKEFLAGS exported just once
>       Seventh batch for 2.21
>       Git 2.21-rc1
> 
> Katrin Leinweber (1):
>       doc: prevent overflowing <code> tag in rendered HTML
> 
> Kevin Daudt (1):
>       t0028: fix wrong octal values for BOM in setup
> 
> Kim Gybels (1):
>       diff: ensure correct lifetime of external_diff_cmd
> 
> Kyle Meyer (2):
>       rebase docs: drop stray word in merge command description
>       init docs: correct a punctuation typo
> 
> Laura Abbott (1):
>       git-quiltimport: add --keep-non-patch option
> 
> Linus Torvalds (1):
>       Add 'human' date format
> 
> Luke Diamand (3):
>       git-p4: add failing test for shelved CL update involving move/copy
>       git-p4: handle update of moved/copied files when updating a shelve
>       git-p4: remove ticket expiry test
> 
> Martin Ågren (5):
>       git-column.txt: fix section header
>       Documentation: do not nest open blocks
>       git-status.txt: render tables correctly under Asciidoctor
>       t7510: invoke git as part of &&-chain
>       doc-diff: don't `cd_to_toplevel`
> 
> Masaya Suzuki (7):
>       Use packet_reader instead of packet_read_line
>       pack-protocol.txt: accept error packets in any context
>       http: support file handles for HTTP_KEEP_ERROR
>       http: enable keep_error for HTTP requests
>       remote-curl: define struct for CURLOPT_WRITEFUNCTION
>       remote-curl: unset CURLOPT_FAILONERROR
>       test: test GIT_CURL_VERBOSE=1 shows an error
> 
> Matthew DeVore (4):
>       list-objects.c: don't segfault for missing cmdline objects
>       revision.c: put promisor option in specialized struct
>       list-objects-filter: teach tree:# how to handle >0
>       tree:<depth>: skip some trees even when collecting omits
> 
> Matthieu Moy (1):
>       git-multimail: update to release 1.5.0
> 
> Max Kirillov (1):
>       http-backend: enable cleaning up forked upload/receive-pack on exit
> 
> Nguyễn Thái Ngọc Duy (68):
>       git.c: mark more strings for translation
>       alias.c: mark split_cmdline_strerror() strings for translation
>       archive.c: mark more strings for translation
>       attr.c: mark more string for translation
>       read-cache.c: turn die("internal error") to BUG()
>       read-cache.c: mark more strings for translation
>       read-cache.c: add missing colon separators
>       reflog: mark strings for translation
>       remote.c: turn some error() or die() to BUG()
>       remote.c: mark messages for translation
>       repack: mark more strings for translation
>       parse-options: replace opterror() with optname()
>       parse-options.c: turn some die() to BUG()
>       parse-options.c: mark more strings for translation
>       fsck: reduce word legos to help i18n
>       fsck: mark strings for translation
>       wt-status.c: remove implicit dependency on the_index
>       wt-status.c: remove implicit dependency the_repository
>       list-objects-filter.c: remove implicit dependency on the_index
>       list-objects.c: reduce the_repository references
>       notes-merge.c: remove implicit dependency on the_index
>       notes-merge.c: remove implicit dependency the_repository
>       transport.c: remove implicit dependency on the_index
>       sequencer.c: remove implicit dependency on the_index
>       sequencer.c: remove implicit dependency on the_repository
>       blame.c: remove implicit dependency the_repository
>       bisect.c: remove the_repository reference
>       branch.c: remove the_repository reference
>       bundle.c: remove the_repository references
>       cache-tree.c: remove the_repository references
>       delta-islands.c: remove the_repository references
>       diff-lib.c: remove the_repository references
>       line-log.c: remove the_repository reference
>       notes-cache.c: remove the_repository references
>       pack-check.c: remove the_repository references
>       pack-*.c: remove the_repository references
>       rerere.c: remove the_repository references
>       rebase-interactive.c: remove the_repository references
>       checkout: disambiguate dwim tracking branches and local files
>       checkout: print something when checking out paths
>       tree.c: make read_tree*() take 'struct repository *'
>       tree-walk.c: make tree_entry_interesting() take an index
>       pathspec.h: clean up "extern" in function declarations
>       dir.c: move, rename and export match_attrs()
>       tree-walk: support :(attr) matching
>       Indent code with TABs
>       style: the opening '{' of a function is in a separate line
>       parse-options: fix SunCC compiler warning
>       worktree: allow to (re)move worktrees with uninitialized submodules
>       grep: use grep_opt->repo instead of explict repo argument
>       notes-utils.c: remove the_repository references
>       repository.c: replace hold_locked_index() with repo_hold_locked_index()
>       checkout: avoid the_index when possible
>       read-cache.c: kill read_index()
>       read-cache.c: replace update_index_if_able with repo_&
>       sha1-name.c: remove implicit dependency on the_index
>       merge-recursive.c: remove implicit dependency on the_index
>       merge-recursive.c: remove implicit dependency on the_repository
>       read-cache.c: remove the_* from index_has_changes()
>       cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch
>       fetch: prefer suffix substitution in compact fetch.output
>       help: align the longest command in the command listing
>       git-commit.txt: better description what it does
>       checkout: update count-checkouts messages
>       checkout: count and print -m paths separately
>       imap-send.c: add a missing space in error message
>       git-compat-util: work around fileno(fp) that is a macro
>       get_oid_with_context(): match prototype and implementation
> 
> Olga Telezhnaya (6):
>       ref-filter: add objectsize:disk option
>       ref-filter: add check for negative file size
>       ref-filter: add tests for objectsize:disk
>       ref-filter: add deltabase option
>       ref-filter: add tests for deltabase
>       ref-filter: add docs for new options
> 
> Orgad Shaneh (2):
>       t5403: simplify by using a single repository
>       rebase: run post-checkout hook on checkout
> 
> Patrick Hogg (2):
>       pack-objects: move read mutex to packing_data struct
>       pack-objects: merge read_lock and lock in packing_data struct
> 
> Peter Osterlund (1):
>       git-p4: fix problem when p4 login is not necessary
> 
> Phillip Wood (11):
>       diff: document --no-color-moved
>       Use "whitespace" consistently
>       diff: allow --no-color-moved-ws
>       diff --color-moved-ws: demonstrate false positives
>       diff --color-moved-ws: fix false positives
>       diff --color-moved=zebra: be stricter with color alternation
>       diff --color-moved-ws: optimize allow-indentation-change
>       diff --color-moved-ws: modify allow-indentation-change
>       diff --color-moved-ws: handle blank lines
>       implicit interactive rebase: don't run sequence editor
>       rebase -x: sanity check command
> 
> Pranit Bauva (7):
>       bisect--helper: `bisect_reset` shell function in C
>       bisect--helper: `bisect_write` shell function in C
>       wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()
>       bisect--helper: `check_and_set_terms` shell function in C
>       bisect--helper: `bisect_next_check` shell function in C
>       bisect--helper: `get_terms` & `bisect_terms` shell function in C
>       bisect--helper: `bisect_start` shell function partially in C
> 
> Ramsay Jones (3):
>       config.mak.uname: remove obsolete SPARSE_FLAGS setting
>       Makefile: improve SPARSE_FLAGS customisation
>       sequencer: make sign_off_header a file local symbol
> 
> Randall S. Becker (10):
>       transport-helper: use xread instead of read
>       config.mak.uname: support for modern HPE NonStop config.
>       git-compat-util.h: add FLOSS headers for HPE NonStop
>       compat/regex/regcomp.c: define intptr_t and uintptr_t on NonStop
>       t5403: correct bash ambiguous redirect error in subtest 8 by quoting $GIT_DIR
>       config.mak.uname: add FREAD_READS_DIRECTORIES for NonStop platform
>       test-lib-functions.sh: add generate_zero_bytes function
>       t5318: replace use of /dev/zero with generate_zero_bytes
>       t5562: replace /dev/zero with a pipe from generate_zero_bytes
>       config.mak.uname: move location of bash on NonStop to CoreUtils
> 
> René Scharfe (5):
>       sha1-file: close fd of empty file in map_sha1_file_1()
>       object-store: factor out odb_loose_cache()
>       object-store: factor out odb_clear_loose_cache()
>       object-store: use one oid_array per subdirectory for loose cache
>       object-store: retire odb_load_loose_cache()
> 
> SZEDER Gábor (25):
>       clone: use a more appropriate variable name for the default refspec
>       clone: respect additional configured fetch refspecs during initial fetch
>       Documentation/clone: document ignored configuration variables
>       test-lib: check Bash version for '-x' without using shell arrays
>       test-lib: translate SIGTERM and SIGHUP to an exit
>       test-lib: extract Bash version check for '-x' tracing
>       test-lib: parse options in a for loop to keep $@ intact
>       test-lib: parse command line options earlier
>       test-lib: consolidate naming of test-results paths
>       test-lib: set $TRASH_DIRECTORY earlier
>       test-lib-functions: introduce the 'test_set_port' helper function
>       test-lib: add the '--stress' option to run a test repeatedly under load
>       compat/obstack: fix -Wcast-function-type warnings
>       .gitignore: ignore external debug symbols from GCC on macOS
>       travis-ci: don't be '--quiet' when running the tests
>       travis-ci: switch to Xcode 10.1 macOS image
>       travis-ci: build with the right compiler
>       commit-graph: rename "large edges" to "extra edges"
>       commit-graph: don't call write_graph_chunk_extra_edges() unnecessarily
>       strbuf.cocci: suggest strbuf_addbuf() to add one strbuf to an other
>       object_as_type: initialize commit-graph-related fields of 'struct commit'
>       travis-ci: make the OSX build jobs' 'brew update' more quiet
>       ci: make sure we build Git parallel
>       test-lib: make '--stress' more bisect-friendly
>       test-lib: fix non-portable pattern bracket expressions
> 
> Sebastian Staudt (2):
>       describe: setup working tree for --dirty
>       t6120: test for describe with a bare repository
> 
> Sergey Organov (4):
>       t3510: stop using '-m 1' to force failure mid-sequence of cherry-picks
>       cherry-pick: do not error on non-merge commits when '-m 1' is specified
>       t3502: validate '-m 1' argument is now accepted for non-merge commits
>       t3506: validate '-m 1 -ff' is now accepted for non-merge commits
> 
> Shahzad Lone (1):
>       various: tighten constness of some local variables
> 
> Slavica Djukic (1):
>       stash: tolerate missing user identity
> 
> Stefan Beller (39):
>       sha1_file: allow read_object to read objects in arbitrary repositories
>       packfile: allow has_packed_and_bad to handle arbitrary repositories
>       diff: align move detection error handling with other options
>       object-store: allow read_object_file_extended to read from any repo
>       object-store: prepare read_object_file to deal with any repo
>       object-store: prepare has_{sha1, object}_file to handle any repo
>       object: parse_object to honor its repository argument
>       commit: allow parse_commit* to handle any repo
>       commit-reach.c: allow paint_down_to_common to handle any repo
>       commit-reach.c: allow merge_bases_many to handle any repo
>       commit-reach.c: allow remove_redundant to handle any repo
>       commit-reach.c: allow get_merge_bases_many_0 to handle any repo
>       commit-reach: prepare get_merge_bases to handle any repo
>       commit-reach: prepare in_merge_bases[_many] to handle any repo
>       commit: prepare get_commit_buffer to handle any repo
>       commit: prepare repo_unuse_commit_buffer to handle any repo
>       commit: prepare logmsg_reencode to handle arbitrary repositories
>       pretty: prepare format_commit_message to handle arbitrary repositories
>       sideband: color lines with keyword only
>       sha1-array: provide oid_array_filter
>       submodule.c: fix indentation
>       submodule.c: sort changed_submodule_names before searching it
>       submodule.c: tighten scope of changed_submodule_names struct
>       submodule: store OIDs in changed_submodule_names
>       repository: repo_submodule_init to take a submodule struct
>       submodule: migrate get_next_submodule to use repository structs
>       submodule.c: fetch in submodules git directory instead of in worktree
>       fetch: ensure submodule objects fetched
>       submodule update: add regression test with old style setups
>       submodule: unset core.worktree if no working tree is present
>       submodule--helper: fix BUG message in ensure_core_worktree
>       submodule deinit: unset core.worktree
>       submodule: use submodule repos for object lookup
>       submodule: don't add submodule as odb for push
>       commit-graph: convert remaining functions to handle any repo
>       commit: prepare free_commit_buffer and release_commit_memory for any repo
>       path.h: make REPO_GIT_PATH_FUNC repository agnostic
>       t/helper/test-repository: celebrate independence from the_repository
>       git-submodule: abort if core.worktree could not be set correctly
> 
> Stephen P. Smith (4):
>       Replace the proposed 'auto' mode with 'auto:'
>       Add 'human' date format documentation
>       Add `human` format to test-tool
>       Add `human` date format tests.
> 
> Sven van Haastregt (1):
>       git-submodule.sh: shorten submodule SHA-1s using rev-parse
> 
> Thomas Braun (1):
>       log -G: ignore binary files
> 
> Thomas Gummerer (3):
>       t5570: drop racy test
>       Revert "t/lib-git-daemon: record daemon log"
>       config.mak.dev: add -Wall, primarily for -Wformat, to help autoconf users
> 
> Todd Zullinger (2):
>       t/lib-gpg: quote path to ${GNUPGHOME}/trustlist.txt
>       t/lib-gpg: drop redundant killing of gpg-agent
> 
> Torsten Bögershausen (3):
>       git clone <url> C:\cygwin\home\USER\repo' is working (again)
>       test-lint: only use only sed [-n] [-e command] [-f command_file]
>       Support working-tree-encoding "UTF-16LE-BOM"
> 
> brian m. carlson (20):
>       sha1-file: rename algorithm to "sha1"
>       sha1-file: provide functions to look up hash algorithms
>       hex: introduce functions to print arbitrary hashes
>       cache: make hashcmp and hasheq work with larger hashes
>       t: add basic tests for our SHA-1 implementation
>       t: make the sha1 test-tool helper generic
>       sha1-file: add a constant for hash block size
>       t/helper: add a test helper to compute hash speed
>       commit-graph: convert to using the_hash_algo
>       Add a base implementation of SHA-256 support
>       sha256: add an SHA-256 implementation using libgcrypt
>       hash: add an SHA-256 implementation using OpenSSL
>       tree-walk: copy object ID before use
>       match-trees: compute buffer offset correctly when splicing
>       match-trees: use hashcpy to splice trees
>       tree-walk: store object_id in a separate member
>       cache: make oidcpy always copy GIT_MAX_RAWSZ bytes
>       fetch-pack: clear alternate shallow when complete
>       fetch-pack: clear alternate shallow in one more place
>       utf8: handle systems that don't write BOM for UTF-16
> 
> Ævar Arnfjörð Bjarmason (18):
>       remote.c: add braces in anticipation of a follow-up change
>       i18n: remote.c: mark error(...) messages for translation
>       push: improve the error shown on unqualified <dst> push
>       push: move unqualified refname error into a function
>       push: add an advice on unqualified <dst> push
>       push: test that <src> doesn't DWYM if <dst> is unqualified
>       push doc: document the DWYM behavior pushing to unqualified <dst>
>       commit-graph: split up close_reachable() progress output
>       commit-graph write: use pack order when finding commits
>       commit-graph write: add "Writing out" progress output
>       commit-graph write: more descriptive "writing out" output
>       commit-graph write: show progress for object search
>       commit-graph write: add more descriptive progress output
>       commit-graph write: remove empty line for readability
>       commit-graph write: add itermediate progress
>       commit-graph write: emit a percentage for all progress
>       diff-tree doc: correct & remove wrong documentation
>       rebase: fix regression in rebase.useBuiltin=false test mode
> 
> -- 
> You received this message because you are subscribed to the Google Groups "git-packagers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to git-packagers+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/git-packagers/xmqq8syj9h9b.fsf%40gitster-ct.c.googlers.com.
> For more options, visit https://groups.google.com/d/optout.
> 

^ permalink raw reply	[relevance 0%]

* [ANNOUNCE] Git v2.21.0-rc1
@ 2019-02-14  3:32  3% Junio C Hamano
  2019-02-18 15:45  0% ` Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2019-02-14  3:32 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

A release candidate Git v2.21.0-rc1 is now available for testing
at the usual places.  It is comprised of 464 non-merge commits
since v2.20.0, contributed by 60 people, 14 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.21.0-rc1' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.20.0 are as follows.
Welcome to the Git development community!

  Arti Zirk, Brandon Richardson, Chayoung You, Denis Ovsienko,
  Erin Dahlgren, Force Charlie, Frank Dana, Issac Trotts, Katrin
  Leinweber, Laura Abbott, Patrick Hogg, Peter Osterlund, Shahzad
  Lone, and Slavica Djukic.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Ben Peart, Brandon Williams, brian
  m. carlson, Carlo Marcelo Arenas Belón, Christian Couder,
  David Turner, Derrick Stolee, Elijah Newren, Eric Sunshine,
  Eric Wong, Jean-Noël Avila, Jeff King, Johannes Schindelin,
  Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano,
  Kevin Daudt, Kim Gybels, Kyle Meyer, Linus Torvalds, Luke
  Diamand, Martin Ågren, Masaya Suzuki, Matthew DeVore, Matthieu
  Moy, Max Kirillov, Nguyễn Thái Ngọc Duy, Olga Telezhnaya,
  Orgad Shaneh, Phillip Wood, Pranit Bauva, Ramsay Jones,
  Randall S. Becker, René Scharfe, Sebastian Staudt, Sergey
  Organov, Stefan Beller, Stephen P. Smith, Sven van Haastregt,
  SZEDER Gábor, Thomas Braun, Thomas Gummerer, Todd Zullinger,
  and Torsten Bögershausen.

----------------------------------------------------------------

Git 2.21 Release Notes (draft)
==============================

Backward Compatibility Notes
----------------------------

 * Historically, the "-m" (mainline) option can only be used for "git
   cherry-pick" and "git revert" when working with a merge commit.
   This version of Git no longer warns or errors out when working with
   a single-parent commit, as long as the argument to the "-m" option
   is 1 (i.e. it has only one parent, and the request is to pick or
   revert relative to that first parent).  Scripts that relied on the
   behaviour may get broken with this change.


Updates since v2.20
-------------------

UI, Workflows & Features

 * The "http.version" configuration variable can be used with recent
   enough versions of cURL library to force the version of HTTP used
   to talk when fetching and pushing.

 * Small fixes and features for fast-export and fast-import, mostly on
   the fast-export side has been made.

 * "git push $there $src:$dst" rejects when $dst is not a fully
   qualified refname and it is not clear what the end user meant.  The
   codepath has been taught to give a clearer error message, and also
   guess where the push should go by taking the type of the pushed
   object into account (e.g. a tag object would want to go under
   refs/tags/).

 * "git checkout [<tree-ish>] path..." learned to report the number of
   paths that have been checked out of the index or the tree-ish,
   which gives it the same degree of noisy-ness as the case in which
   the command checks out a branch.  "git checkout -m <pathspec>" to
   undo conflict resolution gives a similar message.

 * "git quiltimport" learned "--keep-non-patch" option.

 * "git worktree remove" and "git worktree move" refused to work when
   there is a submodule involved.  This has been loosened to ignore
   uninitialized submodules.

 * "git cherry-pick -m1" was forbidden when picking a non-merge
   commit, even though there _is_ parent number 1 for such a commit.
   This was done to avoid mistakes back when "cherry-pick" was about
   picking a single commit, but is no longer useful with "cherry-pick"
   that can pick a range of commits.  Now the "-m$num" option is
   allowed when picking any commit, as long as $num names an existing
   parent of the commit.

 * Update "git multimail" from the upstream.

 * "git p4" update.

 * The "--format=<placeholder>" option of for-each-ref, branch and tag
   learned to show a few more traits of objects that can be learned by
   the object_info API.

 * "git rebase -i" learned to re-execute a command given with 'exec'
   to run after it failed the last time.

 * "git diff --color-moved-ws" updates.

 * Custom userformat "log --format" learned %S atom that stands for
   the tip the traversal reached the commit from, i.e. --source.

 * "git instaweb" learned to drive http.server that comes with
   "batteries included" Python installation (both Python2 & 3).

 * A new encoding UTF-16LE-BOM has been invented to force encoding to
   UTF-16 with BOM in little endian byte order, which cannot be directly
   generated by using iconv.

 * A new date format "--date=human" that morphs its output depending
   on how far the time is from the current time has been introduced.
   "--date=auto:human" can be used to use this new format (or any
   existing format) when the output is going to the pager or to the
   terminal, and otherwise the default format.


Performance, Internal Implementation, Development Support etc.

 * Code clean-up with optimization for the codepath that checks
   (non-)existence of loose objects.

 * More codepaths have become aware of working with in-core repository
   instances other than the default "the_repository".

 * The "strncat()" function is now among the banned functions.

 * Portability updates for the HPE NonStop platform.

 * Earlier we added "-Wformat-security" to developer builds, assuming
   that "-Wall" (which includes "-Wformat" which in turn is required
   to use "-Wformat-security") is always in effect.  This is not true
   when config.mak.autogen is in use, unfortunately.  This has been
   fixed by unconditionally adding "-Wall" to developer builds.

 * The loose object cache used to optimize existence look-up has been
   updated.

 * Flaky tests can now be repeatedly run under load with the
   "--stress" option.

 * Documentation/Makefile is getting prepared for manpage
   localization.

 * "git fetch-pack" now can talk the version 2 protocol.

 * sha-256 hash has been added and plumbed through the code to allow
   building Git with the "NewHash".

 * Debugging help for http transport.

 * "git fetch --deepen=<more>" has been corrected to work over v2
   protocol.

 * The code to walk tree objects has been taught that we may be
   working with object names that are not computed with SHA-1.

 * The in-core repository instances are passed through more codepaths.

 * Update the protocol message specification to allow only the limited
   use of scaled quantities.  This is to ensure potential compatibility
   issues will not get out of hand.

 * Micro-optimize the code that prepares commit objects to be walked
   by "git rev-list" when the commit-graph is available.

 * "git fetch" and "git upload-pack" learned to send all exchanges over
   the sideband channel while talking the v2 protocol.

 * The codepath to write out commit-graph has been optimized by
   following the usual pattern of visiting objects in in-pack order.

 * The codepath to show progress meter while writing out commit-graph
   file has been improved.

 * Cocci rules have been updated to encourage use of strbuf_addbuf().

 * "git rebase --merge" has been reimplemented by reusing the internal
   machinery used for "git rebase -i".

 * More code in "git bisect" has been rewritten in C.

 * Instead of going through "git-rebase--am" scriptlet to use the "am"
   backend, the built-in version of "git rebase" learned to drive the
   "am" backend directly.

 * The assumption to work on the single "in-core index" instance has
   been reduced from the library-ish part of the codebase.

 * The test lint learned to catch non-portable "sed" options.

 * "git pack-objects" learned another algorithm to compute the set of
   objects to send, that trades the resulting packfile off to save
   traversal cost to favor small pushes.

 * The travis CI scripts have been corrected to build Git with the
   compiler(s) of our choice.

 * "git submodule update" learned to abort early when core.worktree
   for the submodule is not set correctly to prevent spreading damage.

 * Test suite has been adjusted to run on Azure Pipeline.

 * Running "Documentation/doc-diff x" from anywhere other than the
   top-level of the working tree did not show the usage string
   correctly, which has been fixed.

 * Use of the sparse tool got easier to customize from the command
   line to help developers.

 * A new target "coverage-prove" to run the coverage test under
   "prove" has been added.

 * A flakey "p4" test has been removed.

 * The code and tests assume that the system supplied iconv() would
   always use BOM in its output when asked to encode to UTF-16 (or
   UTF-32), but apparently some implementations output big-endian
   without BOM.  A compile-time knob has been added to help such
   systems (e.g. NonStop) to add BOM to the output to increase
   portability.


Fixes since v2.20
-----------------

 * Updates for corner cases in merge-recursive.
   (merge cc4cb0902c en/merge-path-collision later to maint).

 * "git checkout frotz" (without any double-dash) avoids ambiguity by
   making sure 'frotz' cannot be interpreted as a revision and as a
   path at the same time.  This safety has been updated to check also
   a unique remote-tracking branch 'frotz' in a remote, when dwimming
   to create a local branch 'frotz' out of a remote-tracking branch
   'frotz' from a remote.
   (merge be4908f103 nd/checkout-dwim-fix later to maint).

 * Refspecs configured with "git -c var=val clone" did not propagate
   to the resulting repository, which has been corrected.
   (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).

 * A properly configured username/email is required under
   user.useConfigOnly in order to create commits; now "git stash"
   (even though it creates commit objects to represent stash entries)
   command is exempt from the requirement.
   (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).

 * The http-backend CGI process did not correctly clean up the child
   processes it spawns to run upload-pack etc. when it dies itself,
   which has been corrected.
   (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).

 * "git rev-list --exclude-promisor-objects" had to take an object
   that does not exist locally (and is lazily available) from the
   command line without barfing, but the code dereferenced NULL.
   (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).

 * The traversal over tree objects has learned to honor
   ":(attr:label)" pathspec match, which has been implemented only for
   enumerating paths on the filesystem.
   (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).

 * BSD port updates.
   (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
   (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
   (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).

 * Lines that begin with a certain keyword that come over the wire, as
   well as lines that consist only of one of these keywords, ought to
   be painted in color for easier eyeballing, but the latter was
   broken ever since the feature was introduced in 2.19, which has
   been corrected.
   (merge 1f67290450 hn/highlight-sideband-keywords later to maint).

 * "git log -G<regex>" looked for a hunk in the "git log -p" patch
   output that contained a string that matches the given pattern.
   Optimize this code to ignore binary files, which by default will
   not show any hunk that would match any pattern (unless textconv or
   the --text option is in effect, that is).
   (merge e0e7cb8080 tb/log-G-binary later to maint).

 * "git submodule update" ought to use a single job unless asked, but
   by mistake used multiple jobs, which has been fixed.
   (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).

 * "git stripspace" should be usable outside a git repository, but
   under the "-s" or "-c" mode, it didn't.
   (merge 957da75802 jn/stripspace-wo-repository later to maint).

 * Some of the documentation pages formatted incorrectly with
   Asciidoctor, which have been fixed.
   (merge b62eb1d2f4 ma/asciidoctor later to maint).

 * The core.worktree setting in a submodule repository should not be
   pointing at a directory when the submodule loses its working tree
   (e.g. getting deinit'ed), but the code did not properly maintain
   this invariant.

 * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
   when the completed path has a special character like SP in it,
   without any attempt to keep "path name" a single filename.  This
   has been fixed to complete it to "git cmd path\ name" just like
   Bash completion does.

 * The test suite tried to see if it is run under bash, but the check
   itself failed under some other implementations of shell (notably
   under NetBSD).  This has been corrected.
   (merge 54ea72f09c sg/test-bash-version-fix later to maint).

 * "git gc" and "git repack" did not close the open packfiles that
   they found unneeded before removing them, which didn't work on a
   platform incapable of removing an open file.  This has been
   corrected.
   (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).

 * The code to drive GIT_EXTERNAL_DIFF command relied on the string
   returned from getenv() to be non-volatile, which is not true, that
   has been corrected.
   (merge 6776a84dae kg/external-diff-save-env later to maint).

 * There were many places the code relied on the string returned from
   getenv() to be non-volatile, which is not true, that have been
   corrected.
   (merge 0da0e9268b jk/save-getenv-result later to maint).

 * The v2 upload-pack protocol implementation failed to honor
   hidden-ref configuration, which has been corrected.
   (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).

 * "git fetch --recurse-submodules" may not fetch the necessary commit
   that is bound to the superproject, which is getting corrected.
   (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).

 * "git rebase" internally runs "checkout" to switch between branches,
   and the command used to call the post-checkout hook, but the
   reimplementation stopped doing so, which is getting fixed.

 * "git add -e" got confused when the change it wants to let the user
   edit is smaller than the previous change that was left over in a
   temporary file.
   (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).

 * "git p4" failed to update a shelved change when there were moved
   files, which has been corrected.
   (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).

 * The codepath to read from the commit-graph file attempted to read
   past the end of it when the file's table-of-contents was corrupt.

 * The compat/obstack code had casts that -Wcast-function-type
   compilation option found questionable.
   (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).

 * An obvious typo in an assertion error message has been fixed.
   (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).

 * In Git for Windows, "git clone \\server\share\path" etc. that uses
   UNC paths from command line had bad interaction with its shell
   emulation.

 * "git add --ignore-errors" did not work as advertised and instead
   worked as an unintended synonym for "git add --renormalize", which
   has been fixed.
   (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).

 * On a case-insensitive filesystem, we failed to compare the part of
   the path that is above the worktree directory in an absolute
   pathname, which has been corrected.

 * Asking "git check-attr" about a macro (e.g. "binary") on a specific
   path did not work correctly, even though "git check-attr -a" listed
   such a macro correctly.  This has been corrected.
   (merge 7b95849be4 jk/attr-macro-fix later to maint).

 * "git pack-objects" incorrectly used uninitialized mutex, which has
   been corrected.
   (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).

 * "git checkout -b <new> [HEAD]" to create a new branch from the
   current commit and check it out ought to be a no-op in the index
   and the working tree in normal cases, but there are corner cases
   that do require updates to the index and the working tree.  Running
   it immediately after "git clone --no-checkout" is one of these
   cases that an earlier optimization kicked in incorrectly, which has
   been fixed.
   (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).

 * "git diff --color-moved --cc --stat -p" did not work well due to
   funny interaction between a bug in color-moved and the rest, which
   has been fixed.
   (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).

 * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
   started when modes of "git rebase" that implicitly uses the
   machinery for the interactive rebase are run, which has been
   corrected.
   (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).

 * The commit-graph facility did not work when in-core objects that
   are promoted from unknown type to commit (e.g. a commit that is
   accessed via a tag that refers to it) were involved, which has been
   corrected.
   (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).

 * "git fetch" output cleanup.
   (merge dc40b24df4 nd/fetch-compact-update later to maint).

 * "git cat-file --batch" reported a dangling symbolic link by
   mistake, when it wanted to report that a given name is ambiguous.

 * Documentation around core.crlf has been updated.
   (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).

 * The documentation of "git commit-tree" said that the command
   understands "--gpg-sign" in addition to "-S", but the command line
   parser did not know about the longhand, which has been corrected.

 * "git rebase -x $cmd" did not reject multi-line command, even though
   the command is incapable of handling such a command.  It now is
   rejected upfront.
   (merge c762aada1a pw/rebase-x-sanity-check later to maint).

 * Output from "git help" was not correctly aligned, which has been
   fixed.
   (merge 6195a76da4 nd/help-align-command-desc later to maint).

 * The "git submodule summary" subcommand showed shortened commit
   object names by mechanically truncating them at 7-hexdigit, which
   has been improved to let "rev-parse --short" scale the length of
   the abbreviation with the size of the repository.
   (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).

 * The way the OSX build jobs updates its build environment used the
   "--quiet" option to "brew update" command, but it wasn't all that
   quiet to be useful.  The use of the option has been replaced with
   an explicit redirection to the /dev/null (which incidentally would
   have worked around a breakage by recent updates to homebrew, which
   has fixed itself already).
   (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).

 * "git --work-tree=$there --git-dir=$here describe --dirty" did not
   work correctly as it did not pay attention to the location of the
   worktree specified by the user by mistake, which has been
   corrected.
   (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).

 * "git fetch" over protocol v2 that needs to make a second connection
   to backfill tags did not clear a variable that holds shallow
   repository information correctly, leading to an access of freed
   piece of memory.

 * Some errors from the other side coming over smart HTTP transport
   were not noticed, which has been corrected.

 * Code cleanup, docfix, build fix, etc.
   (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
   (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
   (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
   (merge ec36c42a63 nd/indentation-fix later to maint).
   (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
   (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
   (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
   (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
   (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
   (merge 3b3357626e nd/style-opening-brace later to maint).
   (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
   (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
   (merge 0650614982 cy/completion-typofix later to maint).
   (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
   (merge bd8d6f0def en/show-ref-doc-fix later to maint).
   (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
   (merge e01378753d cc/fetch-error-message-fix later to maint).
   (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
   (merge d609615f48 js/test-git-installed later to maint).
   (merge ba170517be ja/doc-style-fix later to maint).
   (merge 86fb1c4e77 km/init-doc-typofix later to maint).
   (merge 5cfd4a9d10 nd/commit-doc later to maint).
   (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).
   (merge 2e285e7803 tz/gpg-test-fix later to maint).
   (merge 5427de960b kl/pretty-doc-markup-fix later to maint).
   (merge 3815f64b0d js/mingw-host-cpu later to maint).
   (merge 5fe81438b5 rj/sequencer-sign-off-header-static later to maint).
   (merge 18a4f6be6b nd/fileno-may-be-macro later to maint).
   (merge 99e9ab54ab kd/t0028-octal-del-is-377-not-777 later to maint).

----------------------------------------------------------------

Changes since v2.20.0 are as follows:

Arti Zirk (1):
      git-instaweb: add Python builtin http.server support

Ben Peart (2):
      checkout: add test demonstrating regression with checkout -b on initial commit
      checkout: fix regression in checkout -b on intitial checkout

Brandon Richardson (1):
      commit-tree: add missing --gpg-sign flag

Brandon Williams (1):
      mailmap: update brandon williams's email address

Carlo Marcelo Arenas Belón (4):
      t6036: avoid non-portable "cp -a"
      tests: add lint for non portable cp -a
      t5004: avoid using tar for empty packages
      config.mak.uname: OpenBSD uses BSD semantics with fread for directories

Chayoung You (3):
      zsh: complete unquoted paths with spaces correctly
      completion: treat results of git ls-tree as file paths
      completion: fix typo in git-completion.bash

Christian Couder (3):
      fetch: fix extensions.partialclone name in error message
      partial-clone: add missing 'is' in doc
      helper/test-ref-store: fix "new-sha1" vs "old-sha1" typo

David Turner (1):
      Do not print 'dangling' for cat-file in case of ambiguity

Denis Ovsienko (1):
      docs: fix $strict_export text in gitweb.conf.txt

Derrick Stolee (10):
      merge-recursive: combine error handling
      .gitattributes: ensure t/oid-info/* has eol=lf
      commit-graph: writing missing parents is a BUG
      git-gc.txt: fix typo about gc.writeCommitGraph
      revision: add mark_tree_uninteresting_sparse
      list-objects: consume sparse tree walk
      revision: implement sparse algorithm
      pack-objects: create pack.useSparse setting
      pack-objects: create GIT_TEST_PACK_SPARSE
      Makefile: add coverage-prove target

Elijah Newren (30):
      t6042: add tests for consistency in file collision conflict handling
      t6036, t6042: testcases for rename collision of already conflicting files
      merge-recursive: increase marker length with depth of recursion
      merge-recursive: new function for better colliding conflict resolutions
      merge-recursive: fix rename/add conflict handling
      merge-recursive: improve handling for rename/rename(2to1) conflicts
      merge-recursive: use handle_file_collision for add/add conflicts
      merge-recursive: improve rename/rename(1to2)/add[/add] handling
      t6036, t6043: increase code coverage for file collision handling
      fast-export: convert sha1 to oid
      git-fast-import.txt: fix documentation for --quiet option
      git-fast-export.txt: clarify misleading documentation about rev-list args
      fast-export: use value from correct enum
      fast-export: avoid dying when filtering by paths and old tags exist
      fast-export: move commit rewriting logic into a function for reuse
      fast-export: when using paths, avoid corrupt stream with non-existent mark
      fast-export: ensure we export requested refs
      fast-export: add --reference-excluded-parents option
      fast-import: remove unmaintained duplicate documentation
      fast-export: add a --show-original-ids option to show original names
      git-rebase.txt: update note about directory rename detection and am
      rebase: make builtin and legacy script error messages the same
      rebase: fix incompatible options error message
      t5407: add a test demonstrating how interactive handles --skip differently
      am, rebase--merge: do not overlook --skip'ed commits with post-rewrite
      git-rebase, sequencer: extend --quiet option for the interactive machinery
      git-legacy-rebase: simplify unnecessary triply-nested if
      rebase: define linearization ordering and enforce it
      rebase: implement --merge via the interactive machinery
      git-show-ref.txt: fix order of flags

Eric Sunshine (1):
      doc/config: do a better job of introducing 'worktree.guessRemote'

Eric Wong (2):
      banned.h: mark strncat() as banned
      t1512: test ambiguous cat-file --batch and --batch-output

Erin Dahlgren (1):
      Simplify handling of setup_git_directory_gently() failure cases.

Force Charlie (1):
      http: add support selecting http version

Frank Dana (1):
      docs/gitweb.conf: config variable typo

Issac Trotts (1):
      log: add %S option (like --source) to log --format

Jean-Noël Avila (3):
      Documentation/Makefile add optional targets for l10n
      doc: tidy asciidoc style
      Fix typos in translatable strings for v2.21.0

Jeff King (54):
      fsck: do not reuse child_process structs
      submodule--helper: prefer strip_suffix() to ends_with()
      rename "alternate_object_database" to "object_directory"
      sha1_file_name(): overwrite buffer instead of appending
      handle alternates paths the same as the main object dir
      sha1-file: use an object_directory for the main object dir
      object-store: provide helpers for loose_objects_cache
      sha1-file: use loose object cache for quick existence check
      fetch-pack: drop custom loose object cache
      odb_load_loose_cache: fix strbuf leak
      transport-helper: drop read/write errno checks
      sha1-file: fix outdated sha1 comment references
      update comment references to sha1_object_info()
      http: use struct object_id instead of bare sha1
      sha1-file: modernize loose object file functions
      sha1-file: modernize loose header/stream functions
      sha1-file: convert pass-through functions to object_id
      convert has_sha1_file() callers to has_object_file()
      sha1-file: drop has_sha1_file()
      sha1-file: prefer "loose object file" to "sha1 file" in messages
      sha1-file: avoid "sha1 file" for generic use in messages
      prefer "hash mismatch" to "sha1 mismatch"
      upload-pack: support hidden refs with protocol v2
      remote: check config validity before creating rewrite struct
      get_super_prefix(): copy getenv() result
      commit: copy saved getenv() result
      config: make a copy of $GIT_CONFIG string
      init: make a copy of $GIT_DIR string
      merge-recursive: copy $GITHEAD strings
      builtin_diff(): read $GIT_DIFF_OPTS closer to use
      add: use separate ADD_CACHE_RENORMALIZE flag
      attr: do not mark queried macros as unset
      t4006: resurrect commented-out tests
      diff: clear emitted_symbols flag after use
      combine-diff: factor out stat-format mask
      combine-diff: treat --shortstat like --stat
      combine-diff: treat --summary like --stat
      combine-diff: treat --dirstat like --stat
      match-trees: drop unused path parameter from score functions
      apply: drop unused "def" parameter from find_name_gnu()
      create_bundle(): drop unused "header" parameter
      column: drop unused "opts" parameter in item_length()
      show_date_relative(): drop unused "tz" parameter
      config: drop unused parameter from maybe_remove_section()
      convert: drop len parameter from conversion checks
      convert: drop path parameter from actual conversion functions
      doc/gitattributes: clarify "autocrlf overrides eol"
      docs/config: clarify "text property" in core.eol
      test-date: drop unused parameter to getnanos()
      remote-curl: refactor smart-http discovery
      remote-curl: tighten "version 2" check for smart-http
      add_to_index(): convert forgotten HASH_RENORMALIZE check
      RelNotes/2.21: tweak "--date=auto" mention
      RelNotes/2.21: misc typo/English fixups

Johannes Schindelin (43):
      rebase: introduce --reschedule-failed-exec
      rebase: add a config option to default to --reschedule-failed-exec
      rebase: introduce a shortcut for --reschedule-failed-exec
      help.h: fix coding style
      help -a: handle aliases with long names gracefully
      t4256: mark support files as LF-only
      t9902: 'send-email' test case requires PERL
      gc/repack: release packs when needed
      add --edit: truncate the patch file
      t6042: work around speed optimization on Windows
      abspath_part_inside_repo: respect core.ignoreCase
      rebase: move `reset_head()` into a better spot
      rebase: avoid double reflog entry when switching branches
      rebase: teach `reset_head()` to optionally skip the worktree
      built-in rebase: call `git am` directly
      mingw (t5580): document bug when cloning from backslashed UNC paths
      mingw: special-case arguments to `sh`
      tests: explicitly use `test-tool.exe` on Windows
      travis: fix skipping tagged releases
      ci: rename the library of common functions
      ci/lib.sh: encapsulate Travis-specific things
      ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
      ci: use a junction on Windows instead of a symlink
      test-date: add a subcommand to measure times in shell scripts
      tests: optionally write results as JUnit-style .xml
      ci/lib.sh: add support for Azure Pipelines
      Add a build definition for Azure DevOps
      ci: add a Windows job to the Azure Pipelines definition
      ci: use git-sdk-64-minimal build artifact
      mingw: be more generous when wrapping up the setitimer() emulation
      README: add a build badge (status of the Azure Pipelines build)
      tests: avoid calling Perl just to determine file sizes
      tests: include detailed trace logs with --write-junit-xml upon failure
      mingw: try to work around issues with the test cleanup
      tests: add t/helper/ to the PATH with --with-dashes
      t0061: workaround issues with --with-dashes and RUNTIME_PREFIX
      tests: optionally skip bin-wrappers/
      ci: speed up Windows phase
      ci: parallelize testing on Windows
      Revert "rebase: introduce a shortcut for --reschedule-failed-exec"
      mingw: fix CPU reporting in `git version --build-options`
      .mailmap: map Clemens Buchacher's mail addresses
      mingw: use a more canonical method to fix the CPU reporting

Jonathan Nieder (1):
      stripspace: allow -s/-c outside git repository

Jonathan Tan (9):
      revision: use commit graph in get_reference()
      fetch-pack: support protocol version 2
      fetch-pack: do not take shallow lock unnecessarily
      upload-pack: teach deepen-relative in protocol v2
      pkt-line: introduce struct packet_writer
      sideband: reverse its dependency on pkt-line
      {fetch,upload}-pack: sideband v2 fetch response
      tests: define GIT_TEST_SIDEBAND_ALL
      ls-refs: filter refs using namespace-stripped name

Josh Steadmon (7):
      filter-options: expand scaled numbers
      commit-graph, fuzz: add fuzzer for commit-graph
      commit-graph: fix buffer read-overflow
      Makefile: correct example fuzz build
      t5551: test server-side ERR packet
      fuzz-commit-graph: initialize repo object
      object: fix leak of shallow_stat

Junio C Hamano (16):
      t0027: squelch checkout path run outside test_expect_* block
      t0061: do not fail test if '.' is part of $PATH
      run-command: report exec failure
      submodule update: run at most one fetch job unless otherwise set
      Git 2.20.1
      Prepare for 2.21 cycle to start soonish
      First batch after 2.20.1
      ref-filter: give uintmax_t to format with %PRIuMAX
      Second batch after 2.20
      Third batch after 2.20
      Fourth batch after 2.20
      Fifth batch for 2.21
      Git 2.21-rc0
      ci: clear and mark MAKEFLAGS exported just once
      Seventh batch for 2.21
      Git 2.21-rc1

Katrin Leinweber (1):
      doc: prevent overflowing <code> tag in rendered HTML

Kevin Daudt (1):
      t0028: fix wrong octal values for BOM in setup

Kim Gybels (1):
      diff: ensure correct lifetime of external_diff_cmd

Kyle Meyer (2):
      rebase docs: drop stray word in merge command description
      init docs: correct a punctuation typo

Laura Abbott (1):
      git-quiltimport: add --keep-non-patch option

Linus Torvalds (1):
      Add 'human' date format

Luke Diamand (3):
      git-p4: add failing test for shelved CL update involving move/copy
      git-p4: handle update of moved/copied files when updating a shelve
      git-p4: remove ticket expiry test

Martin Ågren (5):
      git-column.txt: fix section header
      Documentation: do not nest open blocks
      git-status.txt: render tables correctly under Asciidoctor
      t7510: invoke git as part of &&-chain
      doc-diff: don't `cd_to_toplevel`

Masaya Suzuki (7):
      Use packet_reader instead of packet_read_line
      pack-protocol.txt: accept error packets in any context
      http: support file handles for HTTP_KEEP_ERROR
      http: enable keep_error for HTTP requests
      remote-curl: define struct for CURLOPT_WRITEFUNCTION
      remote-curl: unset CURLOPT_FAILONERROR
      test: test GIT_CURL_VERBOSE=1 shows an error

Matthew DeVore (4):
      list-objects.c: don't segfault for missing cmdline objects
      revision.c: put promisor option in specialized struct
      list-objects-filter: teach tree:# how to handle >0
      tree:<depth>: skip some trees even when collecting omits

Matthieu Moy (1):
      git-multimail: update to release 1.5.0

Max Kirillov (1):
      http-backend: enable cleaning up forked upload/receive-pack on exit

Nguyễn Thái Ngọc Duy (68):
      git.c: mark more strings for translation
      alias.c: mark split_cmdline_strerror() strings for translation
      archive.c: mark more strings for translation
      attr.c: mark more string for translation
      read-cache.c: turn die("internal error") to BUG()
      read-cache.c: mark more strings for translation
      read-cache.c: add missing colon separators
      reflog: mark strings for translation
      remote.c: turn some error() or die() to BUG()
      remote.c: mark messages for translation
      repack: mark more strings for translation
      parse-options: replace opterror() with optname()
      parse-options.c: turn some die() to BUG()
      parse-options.c: mark more strings for translation
      fsck: reduce word legos to help i18n
      fsck: mark strings for translation
      wt-status.c: remove implicit dependency on the_index
      wt-status.c: remove implicit dependency the_repository
      list-objects-filter.c: remove implicit dependency on the_index
      list-objects.c: reduce the_repository references
      notes-merge.c: remove implicit dependency on the_index
      notes-merge.c: remove implicit dependency the_repository
      transport.c: remove implicit dependency on the_index
      sequencer.c: remove implicit dependency on the_index
      sequencer.c: remove implicit dependency on the_repository
      blame.c: remove implicit dependency the_repository
      bisect.c: remove the_repository reference
      branch.c: remove the_repository reference
      bundle.c: remove the_repository references
      cache-tree.c: remove the_repository references
      delta-islands.c: remove the_repository references
      diff-lib.c: remove the_repository references
      line-log.c: remove the_repository reference
      notes-cache.c: remove the_repository references
      pack-check.c: remove the_repository references
      pack-*.c: remove the_repository references
      rerere.c: remove the_repository references
      rebase-interactive.c: remove the_repository references
      checkout: disambiguate dwim tracking branches and local files
      checkout: print something when checking out paths
      tree.c: make read_tree*() take 'struct repository *'
      tree-walk.c: make tree_entry_interesting() take an index
      pathspec.h: clean up "extern" in function declarations
      dir.c: move, rename and export match_attrs()
      tree-walk: support :(attr) matching
      Indent code with TABs
      style: the opening '{' of a function is in a separate line
      parse-options: fix SunCC compiler warning
      worktree: allow to (re)move worktrees with uninitialized submodules
      grep: use grep_opt->repo instead of explict repo argument
      notes-utils.c: remove the_repository references
      repository.c: replace hold_locked_index() with repo_hold_locked_index()
      checkout: avoid the_index when possible
      read-cache.c: kill read_index()
      read-cache.c: replace update_index_if_able with repo_&
      sha1-name.c: remove implicit dependency on the_index
      merge-recursive.c: remove implicit dependency on the_index
      merge-recursive.c: remove implicit dependency on the_repository
      read-cache.c: remove the_* from index_has_changes()
      cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch
      fetch: prefer suffix substitution in compact fetch.output
      help: align the longest command in the command listing
      git-commit.txt: better description what it does
      checkout: update count-checkouts messages
      checkout: count and print -m paths separately
      imap-send.c: add a missing space in error message
      git-compat-util: work around fileno(fp) that is a macro
      get_oid_with_context(): match prototype and implementation

Olga Telezhnaya (6):
      ref-filter: add objectsize:disk option
      ref-filter: add check for negative file size
      ref-filter: add tests for objectsize:disk
      ref-filter: add deltabase option
      ref-filter: add tests for deltabase
      ref-filter: add docs for new options

Orgad Shaneh (2):
      t5403: simplify by using a single repository
      rebase: run post-checkout hook on checkout

Patrick Hogg (2):
      pack-objects: move read mutex to packing_data struct
      pack-objects: merge read_lock and lock in packing_data struct

Peter Osterlund (1):
      git-p4: fix problem when p4 login is not necessary

Phillip Wood (11):
      diff: document --no-color-moved
      Use "whitespace" consistently
      diff: allow --no-color-moved-ws
      diff --color-moved-ws: demonstrate false positives
      diff --color-moved-ws: fix false positives
      diff --color-moved=zebra: be stricter with color alternation
      diff --color-moved-ws: optimize allow-indentation-change
      diff --color-moved-ws: modify allow-indentation-change
      diff --color-moved-ws: handle blank lines
      implicit interactive rebase: don't run sequence editor
      rebase -x: sanity check command

Pranit Bauva (7):
      bisect--helper: `bisect_reset` shell function in C
      bisect--helper: `bisect_write` shell function in C
      wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()
      bisect--helper: `check_and_set_terms` shell function in C
      bisect--helper: `bisect_next_check` shell function in C
      bisect--helper: `get_terms` & `bisect_terms` shell function in C
      bisect--helper: `bisect_start` shell function partially in C

Ramsay Jones (3):
      config.mak.uname: remove obsolete SPARSE_FLAGS setting
      Makefile: improve SPARSE_FLAGS customisation
      sequencer: make sign_off_header a file local symbol

Randall S. Becker (10):
      transport-helper: use xread instead of read
      config.mak.uname: support for modern HPE NonStop config.
      git-compat-util.h: add FLOSS headers for HPE NonStop
      compat/regex/regcomp.c: define intptr_t and uintptr_t on NonStop
      t5403: correct bash ambiguous redirect error in subtest 8 by quoting $GIT_DIR
      config.mak.uname: add FREAD_READS_DIRECTORIES for NonStop platform
      test-lib-functions.sh: add generate_zero_bytes function
      t5318: replace use of /dev/zero with generate_zero_bytes
      t5562: replace /dev/zero with a pipe from generate_zero_bytes
      config.mak.uname: move location of bash on NonStop to CoreUtils

René Scharfe (5):
      sha1-file: close fd of empty file in map_sha1_file_1()
      object-store: factor out odb_loose_cache()
      object-store: factor out odb_clear_loose_cache()
      object-store: use one oid_array per subdirectory for loose cache
      object-store: retire odb_load_loose_cache()

SZEDER Gábor (25):
      clone: use a more appropriate variable name for the default refspec
      clone: respect additional configured fetch refspecs during initial fetch
      Documentation/clone: document ignored configuration variables
      test-lib: check Bash version for '-x' without using shell arrays
      test-lib: translate SIGTERM and SIGHUP to an exit
      test-lib: extract Bash version check for '-x' tracing
      test-lib: parse options in a for loop to keep $@ intact
      test-lib: parse command line options earlier
      test-lib: consolidate naming of test-results paths
      test-lib: set $TRASH_DIRECTORY earlier
      test-lib-functions: introduce the 'test_set_port' helper function
      test-lib: add the '--stress' option to run a test repeatedly under load
      compat/obstack: fix -Wcast-function-type warnings
      .gitignore: ignore external debug symbols from GCC on macOS
      travis-ci: don't be '--quiet' when running the tests
      travis-ci: switch to Xcode 10.1 macOS image
      travis-ci: build with the right compiler
      commit-graph: rename "large edges" to "extra edges"
      commit-graph: don't call write_graph_chunk_extra_edges() unnecessarily
      strbuf.cocci: suggest strbuf_addbuf() to add one strbuf to an other
      object_as_type: initialize commit-graph-related fields of 'struct commit'
      travis-ci: make the OSX build jobs' 'brew update' more quiet
      ci: make sure we build Git parallel
      test-lib: make '--stress' more bisect-friendly
      test-lib: fix non-portable pattern bracket expressions

Sebastian Staudt (2):
      describe: setup working tree for --dirty
      t6120: test for describe with a bare repository

Sergey Organov (4):
      t3510: stop using '-m 1' to force failure mid-sequence of cherry-picks
      cherry-pick: do not error on non-merge commits when '-m 1' is specified
      t3502: validate '-m 1' argument is now accepted for non-merge commits
      t3506: validate '-m 1 -ff' is now accepted for non-merge commits

Shahzad Lone (1):
      various: tighten constness of some local variables

Slavica Djukic (1):
      stash: tolerate missing user identity

Stefan Beller (39):
      sha1_file: allow read_object to read objects in arbitrary repositories
      packfile: allow has_packed_and_bad to handle arbitrary repositories
      diff: align move detection error handling with other options
      object-store: allow read_object_file_extended to read from any repo
      object-store: prepare read_object_file to deal with any repo
      object-store: prepare has_{sha1, object}_file to handle any repo
      object: parse_object to honor its repository argument
      commit: allow parse_commit* to handle any repo
      commit-reach.c: allow paint_down_to_common to handle any repo
      commit-reach.c: allow merge_bases_many to handle any repo
      commit-reach.c: allow remove_redundant to handle any repo
      commit-reach.c: allow get_merge_bases_many_0 to handle any repo
      commit-reach: prepare get_merge_bases to handle any repo
      commit-reach: prepare in_merge_bases[_many] to handle any repo
      commit: prepare get_commit_buffer to handle any repo
      commit: prepare repo_unuse_commit_buffer to handle any repo
      commit: prepare logmsg_reencode to handle arbitrary repositories
      pretty: prepare format_commit_message to handle arbitrary repositories
      sideband: color lines with keyword only
      sha1-array: provide oid_array_filter
      submodule.c: fix indentation
      submodule.c: sort changed_submodule_names before searching it
      submodule.c: tighten scope of changed_submodule_names struct
      submodule: store OIDs in changed_submodule_names
      repository: repo_submodule_init to take a submodule struct
      submodule: migrate get_next_submodule to use repository structs
      submodule.c: fetch in submodules git directory instead of in worktree
      fetch: ensure submodule objects fetched
      submodule update: add regression test with old style setups
      submodule: unset core.worktree if no working tree is present
      submodule--helper: fix BUG message in ensure_core_worktree
      submodule deinit: unset core.worktree
      submodule: use submodule repos for object lookup
      submodule: don't add submodule as odb for push
      commit-graph: convert remaining functions to handle any repo
      commit: prepare free_commit_buffer and release_commit_memory for any repo
      path.h: make REPO_GIT_PATH_FUNC repository agnostic
      t/helper/test-repository: celebrate independence from the_repository
      git-submodule: abort if core.worktree could not be set correctly

Stephen P. Smith (4):
      Replace the proposed 'auto' mode with 'auto:'
      Add 'human' date format documentation
      Add `human` format to test-tool
      Add `human` date format tests.

Sven van Haastregt (1):
      git-submodule.sh: shorten submodule SHA-1s using rev-parse

Thomas Braun (1):
      log -G: ignore binary files

Thomas Gummerer (3):
      t5570: drop racy test
      Revert "t/lib-git-daemon: record daemon log"
      config.mak.dev: add -Wall, primarily for -Wformat, to help autoconf users

Todd Zullinger (2):
      t/lib-gpg: quote path to ${GNUPGHOME}/trustlist.txt
      t/lib-gpg: drop redundant killing of gpg-agent

Torsten Bögershausen (3):
      git clone <url> C:\cygwin\home\USER\repo' is working (again)
      test-lint: only use only sed [-n] [-e command] [-f command_file]
      Support working-tree-encoding "UTF-16LE-BOM"

brian m. carlson (20):
      sha1-file: rename algorithm to "sha1"
      sha1-file: provide functions to look up hash algorithms
      hex: introduce functions to print arbitrary hashes
      cache: make hashcmp and hasheq work with larger hashes
      t: add basic tests for our SHA-1 implementation
      t: make the sha1 test-tool helper generic
      sha1-file: add a constant for hash block size
      t/helper: add a test helper to compute hash speed
      commit-graph: convert to using the_hash_algo
      Add a base implementation of SHA-256 support
      sha256: add an SHA-256 implementation using libgcrypt
      hash: add an SHA-256 implementation using OpenSSL
      tree-walk: copy object ID before use
      match-trees: compute buffer offset correctly when splicing
      match-trees: use hashcpy to splice trees
      tree-walk: store object_id in a separate member
      cache: make oidcpy always copy GIT_MAX_RAWSZ bytes
      fetch-pack: clear alternate shallow when complete
      fetch-pack: clear alternate shallow in one more place
      utf8: handle systems that don't write BOM for UTF-16

Ævar Arnfjörð Bjarmason (18):
      remote.c: add braces in anticipation of a follow-up change
      i18n: remote.c: mark error(...) messages for translation
      push: improve the error shown on unqualified <dst> push
      push: move unqualified refname error into a function
      push: add an advice on unqualified <dst> push
      push: test that <src> doesn't DWYM if <dst> is unqualified
      push doc: document the DWYM behavior pushing to unqualified <dst>
      commit-graph: split up close_reachable() progress output
      commit-graph write: use pack order when finding commits
      commit-graph write: add "Writing out" progress output
      commit-graph write: more descriptive "writing out" output
      commit-graph write: show progress for object search
      commit-graph write: add more descriptive progress output
      commit-graph write: remove empty line for readability
      commit-graph write: add itermediate progress
      commit-graph write: emit a percentage for all progress
      diff-tree doc: correct & remove wrong documentation
      rebase: fix regression in rebase.useBuiltin=false test mode


^ permalink raw reply	[relevance 3%]

* Re: [ANNOUNCE] Git v2.21.0-rc0
  2019-02-07  7:28  3% [ANNOUNCE] Git v2.21.0-rc0 Junio C Hamano
@ 2019-02-07 19:47  0% ` Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2019-02-07 19:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, git-packagers, git-for-windows

[-- Attachment #1: Type: text/plain, Size: 48551 bytes --]

Team,

the Windows version of v2.21.0-rc0 can be found here:

https://github.com/git-for-windows/git/releases/tag/v2.21.0-rc0.windows.1

Thanks for testing!
Johannes

On Wed, 6 Feb 2019, Junio C Hamano wrote:

> An early preview release Git v2.21.0-rc0 is now available for
> testing at the usual places.  It is comprised of 426 non-merge
> commits since v2.20.0, contributed by 57 people, 13 of which are
> new faces.
> 
> The tarballs are found at:
> 
>     https://www.kernel.org/pub/software/scm/git/testing/
> 
> The following public repositories all have a copy of the
> 'v2.21.0-rc0' tag and the 'master' branch that the tag points at:
> 
>   url = https://kernel.googlesource.com/pub/scm/git/git
>   url = git://repo.or.cz/alt-git.git
>   url = https://github.com/gitster/git
> 
> New contributors whose contributions weren't in v2.20.0 are as follows.
> Welcome to the Git development community!
> 
>   Arti Zirk, Brandon Richardson, Chayoung You, Denis Ovsienko, Erin
>   Dahlgren, Force Charlie, Frank Dana, Issac Trotts, Laura Abbott,
>   Patrick Hogg, Peter Osterlund, Shahzad Lone, and Slavica Djukic.
> 
> Returning contributors who helped this release are as follows.
> Thanks for your continued support.
> 
>   Ævar Arnfjörð Bjarmason, Ben Peart, Brandon Williams, brian
>   m. carlson, Carlo Marcelo Arenas Belón, Christian Couder,
>   David Turner, Derrick Stolee, Elijah Newren, Eric Sunshine,
>   Eric Wong, Jean-Noël Avila, Jeff King, Johannes Schindelin,
>   Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano, Kim
>   Gybels, Kyle Meyer, Linus Torvalds, Luke Diamand, Martin Ågren,
>   Masaya Suzuki, Matthew DeVore, Matthieu Moy, Max Kirillov,
>   Nguyễn Thái Ngọc Duy, Olga Telezhnaya, Orgad Shaneh,
>   Phillip Wood, Pranit Bauva, Ramsay Jones, Randall S. Becker,
>   René Scharfe, Sebastian Staudt, Sergey Organov, Stefan Beller,
>   Stephen P. Smith, Sven van Haastregt, SZEDER Gábor, Thomas
>   Braun, Thomas Gummerer, and Torsten Bögershausen.
> 
> ----------------------------------------------------------------
> 
> Git 2.21 Release Notes (draft)
> ==============================
> 
> Backward Compatibility Notes
> ----------------------------
> 
>  * Historically, the "-m" (mainline) option can only be used for "git
>    cherry-pick" and "git revert" when working with a merge commit.
>    This version of Git no longer warns or errors out when working with
>    a single-parent commit, as long as the argument to the "-m" option
>    is 1 (i.e. it has only one parent, and the request is to pick or
>    revert relative to that first parent).  Scripts that relied on the
>    behaviour may get broken with this change.
> 
> 
> Updates since v2.20
> -------------------
> 
> UI, Workflows & Features
> 
>  * The "http.version" configuration variable can be used with recent
>    enough versions of cURL library to force the version of HTTP used
>    to talk when fetching and pushing.
> 
>  * Small fixes and features for fast-export and fast-import, mostly on
>    the fast-export side has been made.
> 
>  * "git push $there $src:$dst" rejects when $dst is not a fully
>    qualified refname and not clear what the end user meant.  The
>    codepath has been taught to give a clearer error message, and also
>    guess where the push should go by taking the type of the pushed
>    object into account (e.g. a tag object would want to go under
>    refs/tags/).
> 
>  * "git checkout [<tree-ish>] path..." learned to report the number of
>    paths that have been checked out of the index or the tree-ish,
>    which gives it the same degree of noisy-ness as the case in which
>    the command checks out a branch.
> 
>  * "git quiltimport" learned "--keep-non-patch" option.
> 
>  * "git worktree remove" and "git worktree move" refused to work when
>    there is a submodule involved.  This has been loosened to ignore
>    uninitialized submodules.
> 
>  * "git cherry-pick -m1" was forbidden when picking a non-merge
>    commit, even though there _is_ parent number 1 for such a commit.
>    This was done to avoid mistakes back when "cherry-pick" was about
>    picking a single commit, but is no longer useful with "cherry-pick"
>    that can pick a range of commits.  Now the "-m$num" option is
>    allowed when picking any commit, as long as $num names an existing
>    parent of the commit.
> 
>  * Update "git multimail" from the upstream.
> 
>  * "git p4" update.
> 
>  * The "--format=<placeholder>" option of for-each-ref, branch and tag
>    learned to show a few more traits of objects that can be learned by
>    the object_info API.
> 
>  * "git rebase -i" learned to re-execute a command given with 'exec'
>    to run after it failed the last time.
> 
>  * "git diff --color-moved-ws" updates.
> 
>  * Custom userformat "log --format" learned %S atom that stands for
>    the tip the traversal reached the commit from, i.e. --source.
> 
>  * "git instaweb" learned to drive http.server that comes with
>    "batteries included" Python installation (both Python2 & 3).
> 
>  * A new encoding UTF-16LE-BOM has been invented to force encoding to
>    UTF-16 with BOM in little endian byte order, which cannot be directly
>    generated by using iconv.
> 
>  * A new date format "--date=human" that morphs its output depending
>    on how far the time is from the current time has been introduced.
>    "--date=auto" can be used to use this new format when the output is
>    going to the pager or to the terminal and otherwise the default
>    format.
> 
> 
> Performance, Internal Implementation, Development Support etc.
> 
>  * Code clean-up with optimization for the codepath that checks
>    (non-)existence of loose objects.
> 
>  * More codepaths have become aware of working with in-core repository
>    instance other than the default "the_repository".
> 
>  * The "strncat()" function is now among the banned functions.
> 
>  * Portability updates for the HPE NonStop platform.
> 
>  * Earlier we added "-Wformat-security" to developer builds, assuming
>    that "-Wall" (which includes "-Wformat" which in turn is required
>    to use "-Wformat-security") is always in effect.  This is not true
>    when config.mak.autogen is in use, unfortunately.  This has been
>    fixed by unconditionally adding "-Wall" to developer builds.
> 
>  * The loose object cache used to optimize existence look-up has been
>    updated.
> 
>  * Flaky tests can now be repeatedly run under load with the
>    "--stress" option.
> 
>  * Documentation/Makefile is getting prepared for manpage
>    localization.
> 
>  * "git fetch-pack" now can talk the version 2 protocol.
> 
>  * sha-256 hash has been added and plumbed through the code to allow
>    building Git with the "NewHash".
> 
>  * Debugging help for http transport.
> 
>  * "git fetch --deepen=<more>" has been corrected to work over v2
>    protocol.
> 
>  * The code to walk tree objects has been taught that we may be
>    working with object names that are not computed with SHA-1.
> 
>  * The in-core repository instances are passed through more codepaths.
> 
>  * Update the protocol message specification to allow only the limited
>    use of scaled quantities.  This is ensure potential compatibility
>    issues will not go out of hand.
> 
>  * Micro-optimize the code that prepares commit objects to be walked
>    by "git rev-list" when the commit-graph is available.
> 
>  * "git fetch" and "git upload-pack" learned to send all exchange over
>    the sideband channel while talking the v2 protocol.
> 
>  * The codepath to write out commit-graph has been optimized by
>    following the usual pattern of visiting objects in in-pack order.
> 
>  * The codepath to show progress meter while writing out commit-graph
>    file has been improved.
> 
>  * Cocci rules have been updated to encourage use of strbuf_addbuf().
> 
>  * "git rebase --merge" has been reimplemented by reusing the internal
>    machinery used for "git rebase -i".
> 
>  * More code in "git bisect" has been rewritten in C.
> 
>  * Instead of going through "git-rebase--am" scriptlet to use the "am"
>    backend, the built-in version of "git rebase" learned to drive the
>    "am" backend directly.
> 
>  * The assumption to work on the single "in-core index" instance has
>    been reduced from the library-ish part of the codebase.
> 
>  * The test lint learned to catch non-portable "sed" options.
> 
>  * "git pack-objects" learned another algorithm to compute the set of
>    objects to send, that trades the resulting packfile off to save
>    traversal cost to favor small pushes.
> 
>  * The travis CI scripts have been corrected to build Git with the
>    compiler(s) of our choice.
> 
>  * "git submodule update" learned to abort early when core.worktree
>    for the submodule is not set correctly to prevent spreading damage.
> 
>  * Test suite has been adjusted to run on Azure Pipeline.
> 
>  * Running "Documentation/doc-diff x" from anywhere other than the
>    top-level of the working tree did not show the usage string
>    correctly, which has been fixed.
> 
>  * Use of the sparse tool got easier to customize from the command
>    line to help developers.
> 
> 
> Fixes since v2.20
> -----------------
> 
>  * Updates for corner cases in merge-recursive.
>    (merge cc4cb0902c en/merge-path-collision later to maint).
> 
>  * "git checkout frotz" (without any double-dash) avoids ambiguity by
>    making sure 'frotz' cannot be interpreted as a revision and as a
>    path at the same time.  This safety has been updated to check also
>    a unique remote-tracking branch 'frotz' in a remote, when dwimming
>    to create a local branch 'frotz' out of a remote-tracking branch
>    'frotz' from a remote.
>    (merge be4908f103 nd/checkout-dwim-fix later to maint).
> 
>  * Refspecs configured with "git -c var=val clone" did not propagate
>    to the resulting repository, which has been corrected.
>    (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).
> 
>  * A properly configured username/email is required under
>    user.useConfigOnly in order to create commits; now "git stash"
>    (even though it creates commit objects to represent stash entries)
>    command is exempt from the requirement.
>    (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).
> 
>  * The http-backend CGI process did not correctly clean up the child
>    processes it spawns to run upload-pack etc. when it dies itself,
>    which has been corrected.
>    (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).
> 
>  * "git rev-list --exclude-promisor-objects" had to take an object
>    that does not exist locally (and is lazily available) from the
>    command line without barfing, but the code dereferenced NULL.
>    (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).
> 
>  * The traversal over tree objects has learned to honor
>    ":(attr:label)" pathspec match, which has been implemented only for
>    enumerating paths on the filesystem.
>    (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).
> 
>  * BSD port updates.
>    (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
>    (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
>    (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).
> 
>  * Lines that begin with a certain keyword that come over the wire, as
>    well as lines that consist only of one of these keywords, ought to
>    be painted in color for easier eyeballing, but the latter was
>    broken ever since the feature was introduced in 2.19, which has
>    been corrected.
>    (merge 1f67290450 hn/highlight-sideband-keywords later to maint).
> 
>  * "git log -G<regex>" looked for a hunk in the "git log -p" patch
>    output that contained a string that matches the given pattern.
>    Optimize this code to ignore binary files, which by default will
>    not show any hunk that would match any pattern (unless textconv or
>    the --text option is in effect, that is).
>    (merge e0e7cb8080 tb/log-G-binary later to maint).
> 
>  * "git submodule update" ought to use a single job unless asked, but
>    by mistake used multiple jobs, which has been fixed.
>    (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).
> 
>  * "git stripspace" should be usable outside a git repository, but
>    under the "-s" or "-c" mode, it didn't.
>    (merge 957da75802 jn/stripspace-wo-repository later to maint).
> 
>  * Some of the documentation pages formatted incorrectly with
>    Asciidoctor, which have been fixed.
>    (merge b62eb1d2f4 ma/asciidoctor later to maint).
> 
>  * The core.worktree setting in a submodule repository should not be
>    pointing at a directory when the submodule loses its working tree
>    (e.g. getting deinit'ed), but the code did not properly maintain
>    this invariant.
> 
>  * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
>    when the completed path has a special character like SP in it,
>    without any attempt to keep "path name" a single filename.  This
>    has been fixed to complete it to "git cmd path\ name" just like
>    Bash completion does.
> 
>  * The test suite tried to see if it is run under bash, but the check
>    itself failed under some other implementations of shell (notably
>    under NetBSD).  This has been corrected.
>    (merge 54ea72f09c sg/test-bash-version-fix later to maint).
> 
>  * "git gc" and "git repack" did not close the open packfiles that
>    they found unneeded before removing them, which didn't work on a
>    platform incapable of removing an open file.  This has been
>    corrected.
>    (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).
> 
>  * The code to drive GIT_EXTERNAL_DIFF command relied on the string
>    returned from getenv() to be non-volatile, which is not true, that
>    has been corrected.
>    (merge 6776a84dae kg/external-diff-save-env later to maint).
> 
>  * There were many places the code relied on the string returned from
>    getenv() to be non-volatile, which is not true, that have been
>    corrected.
>    (merge 0da0e9268b jk/save-getenv-result later to maint).
> 
>  * The v2 upload-pack protocol implementation failed to honor
>    hidden-ref configuration, which has been corrected.
>    (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).
> 
>  * "git fetch --recurse-submodules" may not fetch the necessary commit
>    that is bound to the superproject, which is getting corrected.
>    (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).
> 
>  * "git rebase" internally runs "checkout" to switch between branches,
>    and the command used to call the post-checkout hook, but the
>    reimplementation stopped doing so, which is getting fixed.
> 
>  * "git add -e" got confused when the change it wants to let the user
>    edit is smaller than the previous change that was left over in a
>    temporary file.
>    (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).
> 
>  * "git p4" failed to update a shelved change when there were moved
>    files, which has been corrected.
>    (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).
> 
>  * The codepath to read from the commit-graph file attempted to read
>    past the end of it when the file's table-of-contents was corrupt.
> 
>  * The compat/obstack code had casts that -Wcast-function-type
>    compilation option found questionable.
>    (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).
> 
>  * An obvious typo in an assertion error message has been fixed.
>    (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).
> 
>  * In Git for Windows, "git clone \\server\share\path" etc. that uses
>    UNC paths from command line had bad interaction with its shell
>    emulation.
> 
>  * "git add --ignore-errors" did not work as advertised and instead
>    worked as an unintended synonym for "git add --renormalize", which
>    has been fixed.
>    (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).
> 
>  * On a case-insensitive filesystem, we failed to compare the part of
>    the path that is above the worktree directory in an absolute
>    pathname, which has been corrected.
> 
>  * Asking "git check-attr" about a macro (e.g. "binary") on a specific
>    path did not work correctly, even though "git check-attr -a" listed
>    such a macro correctly.  This has been corrected.
>    (merge 7b95849be4 jk/attr-macro-fix later to maint).
> 
>  * "git pack-objects" incorrectly used uninitialized mutex, which has
>    been corrected.
>    (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).
> 
>  * "git checkout -b <new> [HEAD]" to create a new branch from the
>    current commit and check it out ought to be a no-op in the index
>    and the working tree in normal cases, but there are corner cases
>    that do require updates to the index and the working tree.  Running
>    it immediately after "git clone --no-checkout" is one of these
>    cases that an earlier optimization kicked in incorrectly, which has
>    been fixed.
>    (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).
> 
>  * "git diff --color-moved --cc --stat -p" did not work well due to
>    funny interaction between a bug in color-moved and the rest, which
>    has been fixed.
>    (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).
> 
>  * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
>    started when modes of "git rebase" that implicitly uses the
>    machinery for the interactive rebase are run, which has been
>    corrected.
>    (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).
> 
>  * The commit-graph facility did not work when in-core objects that
>    are promoted from unknown type to commit (e.g. a commit that is
>    accessed via a tag that refers to it) were involved, which has been
>    corrected.
>    (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).
> 
>  * "git fetch" output cleanup.
>    (merge dc40b24df4 nd/fetch-compact-update later to maint).
> 
>  * "git cat-file --batch" reported a dangling symbolic link by
>    mistake, when it wanted to report that a given name is ambiguous.
> 
>  * Documentation around core.crlf has been updated.
>    (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).
> 
>  * The documentation of "git commit-tree" said that the command
>    understands "--gpg-sign" in addition to "-S", but the command line
>    parser did not know about the longhand, which has been corrected.
> 
>  * "git rebase -x $cmd" did not reject multi-line command, even though
>    the command is incapable of handling such a command.  It now is
>    rejected upfront.
>    (merge c762aada1a pw/rebase-x-sanity-check later to maint).
> 
>  * Output from "git help" was not correctly aligned, which has been
>    fixed.
>    (merge 6195a76da4 nd/help-align-command-desc later to maint).
> 
>  * The "git submodule summary" subcommand showed shortened commit
>    object names by mechanically truncating them at 7-hexdigit, which
>    has been improved to let "rev-parse --short" scale the length of
>    the abbreviation with the size of the repository.
>    (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).
> 
>  * The way the OSX build jobs updates its build environment used the
>    "--quiet" option to "brew update" command, but it wasn't all that
>    quiet to be useful.  The use of the option has been replaced with
>    an explicit redirection to the /dev/null (which incidentally would
>    have worked around a breakage by recent updates to homebrew, which
>    has fixed itself already).
>    (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).
> 
>  * "git --work-tree=$there --git-dir=$here describe --dirty" did not
>    work correctly as it did not pay attention to the location of the
>    worktree specified by the user by mistake, which has been
>    corrected.
>    (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).
> 
>  * "git fetch" over protocol v2 that needs to make a second connection
>    to backfill tags did not clear a variable that holds shallow
>    repository information correctly, leading to an access of freed
>    piece of memory.
> 
>  * Code cleanup, docfix, build fix, etc.
>    (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
>    (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
>    (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
>    (merge ec36c42a63 nd/indentation-fix later to maint).
>    (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
>    (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
>    (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
>    (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
>    (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
>    (merge 3b3357626e nd/style-opening-brace later to maint).
>    (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
>    (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
>    (merge 0650614982 cy/completion-typofix later to maint).
>    (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
>    (merge bd8d6f0def en/show-ref-doc-fix later to maint).
>    (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
>    (merge e01378753d cc/fetch-error-message-fix later to maint).
>    (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
>    (merge d609615f48 js/test-git-installed later to maint).
>    (merge ba170517be ja/doc-style-fix later to maint).
>    (merge 86fb1c4e77 km/init-doc-typofix later to maint).
>    (merge 5cfd4a9d10 nd/commit-doc later to maint).
>    (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).
> 
> ----------------------------------------------------------------
> 
> Changes since v2.20.0 are as follows:
> 
> Arti Zirk (1):
>       git-instaweb: add Python builtin http.server support
> 
> Ben Peart (2):
>       checkout: add test demonstrating regression with checkout -b on initial commit
>       checkout: fix regression in checkout -b on intitial checkout
> 
> Brandon Richardson (1):
>       commit-tree: add missing --gpg-sign flag
> 
> Brandon Williams (1):
>       mailmap: update brandon williams's email address
> 
> Carlo Marcelo Arenas Belón (4):
>       t6036: avoid non-portable "cp -a"
>       tests: add lint for non portable cp -a
>       t5004: avoid using tar for empty packages
>       config.mak.uname: OpenBSD uses BSD semantics with fread for directories
> 
> Chayoung You (3):
>       zsh: complete unquoted paths with spaces correctly
>       completion: treat results of git ls-tree as file paths
>       completion: fix typo in git-completion.bash
> 
> Christian Couder (3):
>       fetch: fix extensions.partialclone name in error message
>       partial-clone: add missing 'is' in doc
>       helper/test-ref-store: fix "new-sha1" vs "old-sha1" typo
> 
> David Turner (1):
>       Do not print 'dangling' for cat-file in case of ambiguity
> 
> Denis Ovsienko (1):
>       docs: fix $strict_export text in gitweb.conf.txt
> 
> Derrick Stolee (9):
>       merge-recursive: combine error handling
>       .gitattributes: ensure t/oid-info/* has eol=lf
>       commit-graph: writing missing parents is a BUG
>       git-gc.txt: fix typo about gc.writeCommitGraph
>       revision: add mark_tree_uninteresting_sparse
>       list-objects: consume sparse tree walk
>       revision: implement sparse algorithm
>       pack-objects: create pack.useSparse setting
>       pack-objects: create GIT_TEST_PACK_SPARSE
> 
> Elijah Newren (30):
>       t6042: add tests for consistency in file collision conflict handling
>       t6036, t6042: testcases for rename collision of already conflicting files
>       merge-recursive: increase marker length with depth of recursion
>       merge-recursive: new function for better colliding conflict resolutions
>       merge-recursive: fix rename/add conflict handling
>       merge-recursive: improve handling for rename/rename(2to1) conflicts
>       merge-recursive: use handle_file_collision for add/add conflicts
>       merge-recursive: improve rename/rename(1to2)/add[/add] handling
>       t6036, t6043: increase code coverage for file collision handling
>       fast-export: convert sha1 to oid
>       git-fast-import.txt: fix documentation for --quiet option
>       git-fast-export.txt: clarify misleading documentation about rev-list args
>       fast-export: use value from correct enum
>       fast-export: avoid dying when filtering by paths and old tags exist
>       fast-export: move commit rewriting logic into a function for reuse
>       fast-export: when using paths, avoid corrupt stream with non-existent mark
>       fast-export: ensure we export requested refs
>       fast-export: add --reference-excluded-parents option
>       fast-import: remove unmaintained duplicate documentation
>       fast-export: add a --show-original-ids option to show original names
>       git-rebase.txt: update note about directory rename detection and am
>       rebase: make builtin and legacy script error messages the same
>       rebase: fix incompatible options error message
>       t5407: add a test demonstrating how interactive handles --skip differently
>       am, rebase--merge: do not overlook --skip'ed commits with post-rewrite
>       git-rebase, sequencer: extend --quiet option for the interactive machinery
>       git-legacy-rebase: simplify unnecessary triply-nested if
>       rebase: define linearization ordering and enforce it
>       rebase: implement --merge via the interactive machinery
>       git-show-ref.txt: fix order of flags
> 
> Eric Sunshine (1):
>       doc/config: do a better job of introducing 'worktree.guessRemote'
> 
> Eric Wong (2):
>       banned.h: mark strncat() as banned
>       t1512: test ambiguous cat-file --batch and --batch-output
> 
> Erin Dahlgren (1):
>       Simplify handling of setup_git_directory_gently() failure cases.
> 
> Force Charlie (1):
>       http: add support selecting http version
> 
> Frank Dana (1):
>       docs/gitweb.conf: config variable typo
> 
> Issac Trotts (1):
>       log: add %S option (like --source) to log --format
> 
> Jean-Noël Avila (2):
>       Documentation/Makefile add optional targets for l10n
>       doc: tidy asciidoc style
> 
> Jeff King (50):
>       fsck: do not reuse child_process structs
>       submodule--helper: prefer strip_suffix() to ends_with()
>       rename "alternate_object_database" to "object_directory"
>       sha1_file_name(): overwrite buffer instead of appending
>       handle alternates paths the same as the main object dir
>       sha1-file: use an object_directory for the main object dir
>       object-store: provide helpers for loose_objects_cache
>       sha1-file: use loose object cache for quick existence check
>       fetch-pack: drop custom loose object cache
>       odb_load_loose_cache: fix strbuf leak
>       transport-helper: drop read/write errno checks
>       sha1-file: fix outdated sha1 comment references
>       update comment references to sha1_object_info()
>       http: use struct object_id instead of bare sha1
>       sha1-file: modernize loose object file functions
>       sha1-file: modernize loose header/stream functions
>       sha1-file: convert pass-through functions to object_id
>       convert has_sha1_file() callers to has_object_file()
>       sha1-file: drop has_sha1_file()
>       sha1-file: prefer "loose object file" to "sha1 file" in messages
>       sha1-file: avoid "sha1 file" for generic use in messages
>       prefer "hash mismatch" to "sha1 mismatch"
>       upload-pack: support hidden refs with protocol v2
>       remote: check config validity before creating rewrite struct
>       get_super_prefix(): copy getenv() result
>       commit: copy saved getenv() result
>       config: make a copy of $GIT_CONFIG string
>       init: make a copy of $GIT_DIR string
>       merge-recursive: copy $GITHEAD strings
>       builtin_diff(): read $GIT_DIFF_OPTS closer to use
>       add: use separate ADD_CACHE_RENORMALIZE flag
>       attr: do not mark queried macros as unset
>       t4006: resurrect commented-out tests
>       diff: clear emitted_symbols flag after use
>       combine-diff: factor out stat-format mask
>       combine-diff: treat --shortstat like --stat
>       combine-diff: treat --summary like --stat
>       combine-diff: treat --dirstat like --stat
>       match-trees: drop unused path parameter from score functions
>       apply: drop unused "def" parameter from find_name_gnu()
>       create_bundle(): drop unused "header" parameter
>       column: drop unused "opts" parameter in item_length()
>       show_date_relative(): drop unused "tz" parameter
>       config: drop unused parameter from maybe_remove_section()
>       convert: drop len parameter from conversion checks
>       convert: drop path parameter from actual conversion functions
>       doc/gitattributes: clarify "autocrlf overrides eol"
>       docs/config: clarify "text property" in core.eol
>       test-date: drop unused parameter to getnanos()
>       add_to_index(): convert forgotten HASH_RENORMALIZE check
> 
> Johannes Schindelin (39):
>       rebase: introduce --reschedule-failed-exec
>       rebase: add a config option to default to --reschedule-failed-exec
>       rebase: introduce a shortcut for --reschedule-failed-exec
>       help.h: fix coding style
>       help -a: handle aliases with long names gracefully
>       t4256: mark support files as LF-only
>       t9902: 'send-email' test case requires PERL
>       gc/repack: release packs when needed
>       add --edit: truncate the patch file
>       t6042: work around speed optimization on Windows
>       abspath_part_inside_repo: respect core.ignoreCase
>       rebase: move `reset_head()` into a better spot
>       rebase: avoid double reflog entry when switching branches
>       rebase: teach `reset_head()` to optionally skip the worktree
>       built-in rebase: call `git am` directly
>       mingw (t5580): document bug when cloning from backslashed UNC paths
>       mingw: special-case arguments to `sh`
>       tests: explicitly use `test-tool.exe` on Windows
>       travis: fix skipping tagged releases
>       ci: rename the library of common functions
>       ci/lib.sh: encapsulate Travis-specific things
>       ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
>       ci: use a junction on Windows instead of a symlink
>       test-date: add a subcommand to measure times in shell scripts
>       tests: optionally write results as JUnit-style .xml
>       ci/lib.sh: add support for Azure Pipelines
>       Add a build definition for Azure DevOps
>       ci: add a Windows job to the Azure Pipelines definition
>       ci: use git-sdk-64-minimal build artifact
>       mingw: be more generous when wrapping up the setitimer() emulation
>       README: add a build badge (status of the Azure Pipelines build)
>       tests: avoid calling Perl just to determine file sizes
>       tests: include detailed trace logs with --write-junit-xml upon failure
>       mingw: try to work around issues with the test cleanup
>       tests: add t/helper/ to the PATH with --with-dashes
>       t0061: workaround issues with --with-dashes and RUNTIME_PREFIX
>       tests: optionally skip bin-wrappers/
>       ci: speed up Windows phase
>       ci: parallelize testing on Windows
> 
> Jonathan Nieder (1):
>       stripspace: allow -s/-c outside git repository
> 
> Jonathan Tan (9):
>       revision: use commit graph in get_reference()
>       fetch-pack: support protocol version 2
>       fetch-pack: do not take shallow lock unnecessarily
>       upload-pack: teach deepen-relative in protocol v2
>       pkt-line: introduce struct packet_writer
>       sideband: reverse its dependency on pkt-line
>       {fetch,upload}-pack: sideband v2 fetch response
>       tests: define GIT_TEST_SIDEBAND_ALL
>       ls-refs: filter refs using namespace-stripped name
> 
> Josh Steadmon (4):
>       filter-options: expand scaled numbers
>       commit-graph, fuzz: add fuzzer for commit-graph
>       commit-graph: fix buffer read-overflow
>       Makefile: correct example fuzz build
> 
> Junio C Hamano (13):
>       t0027: squelch checkout path run outside test_expect_* block
>       t0061: do not fail test if '.' is part of $PATH
>       run-command: report exec failure
>       submodule update: run at most one fetch job unless otherwise set
>       Git 2.20.1
>       Prepare for 2.21 cycle to start soonish
>       First batch after 2.20.1
>       ref-filter: give uintmax_t to format with %PRIuMAX
>       Second batch after 2.20
>       Third batch after 2.20
>       Fourth batch after 2.20
>       Fifth batch for 2.21
>       Git 2.21-rc0
> 
> Kim Gybels (1):
>       diff: ensure correct lifetime of external_diff_cmd
> 
> Kyle Meyer (2):
>       rebase docs: drop stray word in merge command description
>       init docs: correct a punctuation typo
> 
> Laura Abbott (1):
>       git-quiltimport: add --keep-non-patch option
> 
> Linus Torvalds (1):
>       Add 'human' date format
> 
> Luke Diamand (2):
>       git-p4: add failing test for shelved CL update involving move/copy
>       git-p4: handle update of moved/copied files when updating a shelve
> 
> Martin Ågren (5):
>       git-column.txt: fix section header
>       Documentation: do not nest open blocks
>       git-status.txt: render tables correctly under Asciidoctor
>       t7510: invoke git as part of &&-chain
>       doc-diff: don't `cd_to_toplevel`
> 
> Masaya Suzuki (7):
>       Use packet_reader instead of packet_read_line
>       pack-protocol.txt: accept error packets in any context
>       http: support file handles for HTTP_KEEP_ERROR
>       http: enable keep_error for HTTP requests
>       remote-curl: define struct for CURLOPT_WRITEFUNCTION
>       remote-curl: unset CURLOPT_FAILONERROR
>       test: test GIT_CURL_VERBOSE=1 shows an error
> 
> Matthew DeVore (4):
>       list-objects.c: don't segfault for missing cmdline objects
>       revision.c: put promisor option in specialized struct
>       list-objects-filter: teach tree:# how to handle >0
>       tree:<depth>: skip some trees even when collecting omits
> 
> Matthieu Moy (1):
>       git-multimail: update to release 1.5.0
> 
> Max Kirillov (1):
>       http-backend: enable cleaning up forked upload/receive-pack on exit
> 
> Nguyễn Thái Ngọc Duy (63):
>       git.c: mark more strings for translation
>       alias.c: mark split_cmdline_strerror() strings for translation
>       archive.c: mark more strings for translation
>       attr.c: mark more string for translation
>       read-cache.c: turn die("internal error") to BUG()
>       read-cache.c: mark more strings for translation
>       read-cache.c: add missing colon separators
>       reflog: mark strings for translation
>       remote.c: turn some error() or die() to BUG()
>       remote.c: mark messages for translation
>       repack: mark more strings for translation
>       parse-options: replace opterror() with optname()
>       parse-options.c: turn some die() to BUG()
>       parse-options.c: mark more strings for translation
>       fsck: reduce word legos to help i18n
>       fsck: mark strings for translation
>       wt-status.c: remove implicit dependency on the_index
>       wt-status.c: remove implicit dependency the_repository
>       list-objects-filter.c: remove implicit dependency on the_index
>       list-objects.c: reduce the_repository references
>       notes-merge.c: remove implicit dependency on the_index
>       notes-merge.c: remove implicit dependency the_repository
>       transport.c: remove implicit dependency on the_index
>       sequencer.c: remove implicit dependency on the_index
>       sequencer.c: remove implicit dependency on the_repository
>       blame.c: remove implicit dependency the_repository
>       bisect.c: remove the_repository reference
>       branch.c: remove the_repository reference
>       bundle.c: remove the_repository references
>       cache-tree.c: remove the_repository references
>       delta-islands.c: remove the_repository references
>       diff-lib.c: remove the_repository references
>       line-log.c: remove the_repository reference
>       notes-cache.c: remove the_repository references
>       pack-check.c: remove the_repository references
>       pack-*.c: remove the_repository references
>       rerere.c: remove the_repository references
>       rebase-interactive.c: remove the_repository references
>       checkout: disambiguate dwim tracking branches and local files
>       checkout: print something when checking out paths
>       tree.c: make read_tree*() take 'struct repository *'
>       tree-walk.c: make tree_entry_interesting() take an index
>       pathspec.h: clean up "extern" in function declarations
>       dir.c: move, rename and export match_attrs()
>       tree-walk: support :(attr) matching
>       Indent code with TABs
>       style: the opening '{' of a function is in a separate line
>       parse-options: fix SunCC compiler warning
>       worktree: allow to (re)move worktrees with uninitialized submodules
>       grep: use grep_opt->repo instead of explict repo argument
>       notes-utils.c: remove the_repository references
>       repository.c: replace hold_locked_index() with repo_hold_locked_index()
>       checkout: avoid the_index when possible
>       read-cache.c: kill read_index()
>       read-cache.c: replace update_index_if_able with repo_&
>       sha1-name.c: remove implicit dependency on the_index
>       merge-recursive.c: remove implicit dependency on the_index
>       merge-recursive.c: remove implicit dependency on the_repository
>       read-cache.c: remove the_* from index_has_changes()
>       cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch
>       fetch: prefer suffix substitution in compact fetch.output
>       help: align the longest command in the command listing
>       git-commit.txt: better description what it does
> 
> Olga Telezhnaya (6):
>       ref-filter: add objectsize:disk option
>       ref-filter: add check for negative file size
>       ref-filter: add tests for objectsize:disk
>       ref-filter: add deltabase option
>       ref-filter: add tests for deltabase
>       ref-filter: add docs for new options
> 
> Orgad Shaneh (2):
>       t5403: simplify by using a single repository
>       rebase: run post-checkout hook on checkout
> 
> Patrick Hogg (2):
>       pack-objects: move read mutex to packing_data struct
>       pack-objects: merge read_lock and lock in packing_data struct
> 
> Peter Osterlund (1):
>       git-p4: fix problem when p4 login is not necessary
> 
> Phillip Wood (11):
>       diff: document --no-color-moved
>       Use "whitespace" consistently
>       diff: allow --no-color-moved-ws
>       diff --color-moved-ws: demonstrate false positives
>       diff --color-moved-ws: fix false positives
>       diff --color-moved=zebra: be stricter with color alternation
>       diff --color-moved-ws: optimize allow-indentation-change
>       diff --color-moved-ws: modify allow-indentation-change
>       diff --color-moved-ws: handle blank lines
>       implicit interactive rebase: don't run sequence editor
>       rebase -x: sanity check command
> 
> Pranit Bauva (7):
>       bisect--helper: `bisect_reset` shell function in C
>       bisect--helper: `bisect_write` shell function in C
>       wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()
>       bisect--helper: `check_and_set_terms` shell function in C
>       bisect--helper: `bisect_next_check` shell function in C
>       bisect--helper: `get_terms` & `bisect_terms` shell function in C
>       bisect--helper: `bisect_start` shell function partially in C
> 
> Ramsay Jones (2):
>       config.mak.uname: remove obsolete SPARSE_FLAGS setting
>       Makefile: improve SPARSE_FLAGS customisation
> 
> Randall S. Becker (4):
>       transport-helper: use xread instead of read
>       config.mak.uname: support for modern HPE NonStop config.
>       git-compat-util.h: add FLOSS headers for HPE NonStop
>       compat/regex/regcomp.c: define intptr_t and uintptr_t on NonStop
> 
> René Scharfe (5):
>       sha1-file: close fd of empty file in map_sha1_file_1()
>       object-store: factor out odb_loose_cache()
>       object-store: factor out odb_clear_loose_cache()
>       object-store: use one oid_array per subdirectory for loose cache
>       object-store: retire odb_load_loose_cache()
> 
> SZEDER Gábor (22):
>       clone: use a more appropriate variable name for the default refspec
>       clone: respect additional configured fetch refspecs during initial fetch
>       Documentation/clone: document ignored configuration variables
>       test-lib: check Bash version for '-x' without using shell arrays
>       test-lib: translate SIGTERM and SIGHUP to an exit
>       test-lib: extract Bash version check for '-x' tracing
>       test-lib: parse options in a for loop to keep $@ intact
>       test-lib: parse command line options earlier
>       test-lib: consolidate naming of test-results paths
>       test-lib: set $TRASH_DIRECTORY earlier
>       test-lib-functions: introduce the 'test_set_port' helper function
>       test-lib: add the '--stress' option to run a test repeatedly under load
>       compat/obstack: fix -Wcast-function-type warnings
>       .gitignore: ignore external debug symbols from GCC on macOS
>       travis-ci: don't be '--quiet' when running the tests
>       travis-ci: switch to Xcode 10.1 macOS image
>       travis-ci: build with the right compiler
>       commit-graph: rename "large edges" to "extra edges"
>       commit-graph: don't call write_graph_chunk_extra_edges() unnecessarily
>       strbuf.cocci: suggest strbuf_addbuf() to add one strbuf to an other
>       object_as_type: initialize commit-graph-related fields of 'struct commit'
>       travis-ci: make the OSX build jobs' 'brew update' more quiet
> 
> Sebastian Staudt (2):
>       describe: setup working tree for --dirty
>       t6120: test for describe with a bare repository
> 
> Sergey Organov (4):
>       t3510: stop using '-m 1' to force failure mid-sequence of cherry-picks
>       cherry-pick: do not error on non-merge commits when '-m 1' is specified
>       t3502: validate '-m 1' argument is now accepted for non-merge commits
>       t3506: validate '-m 1 -ff' is now accepted for non-merge commits
> 
> Shahzad Lone (1):
>       various: tighten constness of some local variables
> 
> Slavica Djukic (1):
>       stash: tolerate missing user identity
> 
> Stefan Beller (39):
>       sha1_file: allow read_object to read objects in arbitrary repositories
>       packfile: allow has_packed_and_bad to handle arbitrary repositories
>       diff: align move detection error handling with other options
>       object-store: allow read_object_file_extended to read from any repo
>       object-store: prepare read_object_file to deal with any repo
>       object-store: prepare has_{sha1, object}_file to handle any repo
>       object: parse_object to honor its repository argument
>       commit: allow parse_commit* to handle any repo
>       commit-reach.c: allow paint_down_to_common to handle any repo
>       commit-reach.c: allow merge_bases_many to handle any repo
>       commit-reach.c: allow remove_redundant to handle any repo
>       commit-reach.c: allow get_merge_bases_many_0 to handle any repo
>       commit-reach: prepare get_merge_bases to handle any repo
>       commit-reach: prepare in_merge_bases[_many] to handle any repo
>       commit: prepare get_commit_buffer to handle any repo
>       commit: prepare repo_unuse_commit_buffer to handle any repo
>       commit: prepare logmsg_reencode to handle arbitrary repositories
>       pretty: prepare format_commit_message to handle arbitrary repositories
>       sideband: color lines with keyword only
>       sha1-array: provide oid_array_filter
>       submodule.c: fix indentation
>       submodule.c: sort changed_submodule_names before searching it
>       submodule.c: tighten scope of changed_submodule_names struct
>       submodule: store OIDs in changed_submodule_names
>       repository: repo_submodule_init to take a submodule struct
>       submodule: migrate get_next_submodule to use repository structs
>       submodule.c: fetch in submodules git directory instead of in worktree
>       fetch: ensure submodule objects fetched
>       submodule update: add regression test with old style setups
>       submodule: unset core.worktree if no working tree is present
>       submodule--helper: fix BUG message in ensure_core_worktree
>       submodule deinit: unset core.worktree
>       submodule: use submodule repos for object lookup
>       submodule: don't add submodule as odb for push
>       commit-graph: convert remaining functions to handle any repo
>       commit: prepare free_commit_buffer and release_commit_memory for any repo
>       path.h: make REPO_GIT_PATH_FUNC repository agnostic
>       t/helper/test-repository: celebrate independence from the_repository
>       git-submodule: abort if core.worktree could not be set correctly
> 
> Stephen P. Smith (4):
>       Replace the proposed 'auto' mode with 'auto:'
>       Add 'human' date format documentation
>       Add `human` format to test-tool
>       Add `human` date format tests.
> 
> Sven van Haastregt (1):
>       git-submodule.sh: shorten submodule SHA-1s using rev-parse
> 
> Thomas Braun (1):
>       log -G: ignore binary files
> 
> Thomas Gummerer (3):
>       t5570: drop racy test
>       Revert "t/lib-git-daemon: record daemon log"
>       config.mak.dev: add -Wall, primarily for -Wformat, to help autoconf users
> 
> Torsten Bögershausen (3):
>       git clone <url> C:\cygwin\home\USER\repo' is working (again)
>       test-lint: only use only sed [-n] [-e command] [-f command_file]
>       Support working-tree-encoding "UTF-16LE-BOM"
> 
> brian m. carlson (19):
>       sha1-file: rename algorithm to "sha1"
>       sha1-file: provide functions to look up hash algorithms
>       hex: introduce functions to print arbitrary hashes
>       cache: make hashcmp and hasheq work with larger hashes
>       t: add basic tests for our SHA-1 implementation
>       t: make the sha1 test-tool helper generic
>       sha1-file: add a constant for hash block size
>       t/helper: add a test helper to compute hash speed
>       commit-graph: convert to using the_hash_algo
>       Add a base implementation of SHA-256 support
>       sha256: add an SHA-256 implementation using libgcrypt
>       hash: add an SHA-256 implementation using OpenSSL
>       tree-walk: copy object ID before use
>       match-trees: compute buffer offset correctly when splicing
>       match-trees: use hashcpy to splice trees
>       tree-walk: store object_id in a separate member
>       cache: make oidcpy always copy GIT_MAX_RAWSZ bytes
>       fetch-pack: clear alternate shallow when complete
>       fetch-pack: clear alternate shallow in one more place
> 
> Ævar Arnfjörð Bjarmason (17):
>       remote.c: add braces in anticipation of a follow-up change
>       i18n: remote.c: mark error(...) messages for translation
>       push: improve the error shown on unqualified <dst> push
>       push: move unqualified refname error into a function
>       push: add an advice on unqualified <dst> push
>       push: test that <src> doesn't DWYM if <dst> is unqualified
>       push doc: document the DWYM behavior pushing to unqualified <dst>
>       commit-graph: split up close_reachable() progress output
>       commit-graph write: use pack order when finding commits
>       commit-graph write: add "Writing out" progress output
>       commit-graph write: more descriptive "writing out" output
>       commit-graph write: show progress for object search
>       commit-graph write: add more descriptive progress output
>       commit-graph write: remove empty line for readability
>       commit-graph write: add itermediate progress
>       commit-graph write: emit a percentage for all progress
>       diff-tree doc: correct & remove wrong documentation
> 
> 

^ permalink raw reply	[relevance 0%]

* [ANNOUNCE] Git v2.21.0-rc0
@ 2019-02-07  7:28  3% Junio C Hamano
  2019-02-07 19:47  0% ` Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2019-02-07  7:28 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

An early preview release Git v2.21.0-rc0 is now available for
testing at the usual places.  It is comprised of 426 non-merge
commits since v2.20.0, contributed by 57 people, 13 of which are
new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.21.0-rc0' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.20.0 are as follows.
Welcome to the Git development community!

  Arti Zirk, Brandon Richardson, Chayoung You, Denis Ovsienko, Erin
  Dahlgren, Force Charlie, Frank Dana, Issac Trotts, Laura Abbott,
  Patrick Hogg, Peter Osterlund, Shahzad Lone, and Slavica Djukic.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Ben Peart, Brandon Williams, brian
  m. carlson, Carlo Marcelo Arenas Belón, Christian Couder,
  David Turner, Derrick Stolee, Elijah Newren, Eric Sunshine,
  Eric Wong, Jean-Noël Avila, Jeff King, Johannes Schindelin,
  Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano, Kim
  Gybels, Kyle Meyer, Linus Torvalds, Luke Diamand, Martin Ågren,
  Masaya Suzuki, Matthew DeVore, Matthieu Moy, Max Kirillov,
  Nguyễn Thái Ngọc Duy, Olga Telezhnaya, Orgad Shaneh,
  Phillip Wood, Pranit Bauva, Ramsay Jones, Randall S. Becker,
  René Scharfe, Sebastian Staudt, Sergey Organov, Stefan Beller,
  Stephen P. Smith, Sven van Haastregt, SZEDER Gábor, Thomas
  Braun, Thomas Gummerer, and Torsten Bögershausen.

----------------------------------------------------------------

Git 2.21 Release Notes (draft)
==============================

Backward Compatibility Notes
----------------------------

 * Historically, the "-m" (mainline) option can only be used for "git
   cherry-pick" and "git revert" when working with a merge commit.
   This version of Git no longer warns or errors out when working with
   a single-parent commit, as long as the argument to the "-m" option
   is 1 (i.e. it has only one parent, and the request is to pick or
   revert relative to that first parent).  Scripts that relied on the
   behaviour may get broken with this change.


Updates since v2.20
-------------------

UI, Workflows & Features

 * The "http.version" configuration variable can be used with recent
   enough versions of cURL library to force the version of HTTP used
   to talk when fetching and pushing.

 * Small fixes and features for fast-export and fast-import, mostly on
   the fast-export side has been made.

 * "git push $there $src:$dst" rejects when $dst is not a fully
   qualified refname and not clear what the end user meant.  The
   codepath has been taught to give a clearer error message, and also
   guess where the push should go by taking the type of the pushed
   object into account (e.g. a tag object would want to go under
   refs/tags/).

 * "git checkout [<tree-ish>] path..." learned to report the number of
   paths that have been checked out of the index or the tree-ish,
   which gives it the same degree of noisy-ness as the case in which
   the command checks out a branch.

 * "git quiltimport" learned "--keep-non-patch" option.

 * "git worktree remove" and "git worktree move" refused to work when
   there is a submodule involved.  This has been loosened to ignore
   uninitialized submodules.

 * "git cherry-pick -m1" was forbidden when picking a non-merge
   commit, even though there _is_ parent number 1 for such a commit.
   This was done to avoid mistakes back when "cherry-pick" was about
   picking a single commit, but is no longer useful with "cherry-pick"
   that can pick a range of commits.  Now the "-m$num" option is
   allowed when picking any commit, as long as $num names an existing
   parent of the commit.

 * Update "git multimail" from the upstream.

 * "git p4" update.

 * The "--format=<placeholder>" option of for-each-ref, branch and tag
   learned to show a few more traits of objects that can be learned by
   the object_info API.

 * "git rebase -i" learned to re-execute a command given with 'exec'
   to run after it failed the last time.

 * "git diff --color-moved-ws" updates.

 * Custom userformat "log --format" learned %S atom that stands for
   the tip the traversal reached the commit from, i.e. --source.

 * "git instaweb" learned to drive http.server that comes with
   "batteries included" Python installation (both Python2 & 3).

 * A new encoding UTF-16LE-BOM has been invented to force encoding to
   UTF-16 with BOM in little endian byte order, which cannot be directly
   generated by using iconv.

 * A new date format "--date=human" that morphs its output depending
   on how far the time is from the current time has been introduced.
   "--date=auto" can be used to use this new format when the output is
   going to the pager or to the terminal and otherwise the default
   format.


Performance, Internal Implementation, Development Support etc.

 * Code clean-up with optimization for the codepath that checks
   (non-)existence of loose objects.

 * More codepaths have become aware of working with in-core repository
   instance other than the default "the_repository".

 * The "strncat()" function is now among the banned functions.

 * Portability updates for the HPE NonStop platform.

 * Earlier we added "-Wformat-security" to developer builds, assuming
   that "-Wall" (which includes "-Wformat" which in turn is required
   to use "-Wformat-security") is always in effect.  This is not true
   when config.mak.autogen is in use, unfortunately.  This has been
   fixed by unconditionally adding "-Wall" to developer builds.

 * The loose object cache used to optimize existence look-up has been
   updated.

 * Flaky tests can now be repeatedly run under load with the
   "--stress" option.

 * Documentation/Makefile is getting prepared for manpage
   localization.

 * "git fetch-pack" now can talk the version 2 protocol.

 * sha-256 hash has been added and plumbed through the code to allow
   building Git with the "NewHash".

 * Debugging help for http transport.

 * "git fetch --deepen=<more>" has been corrected to work over v2
   protocol.

 * The code to walk tree objects has been taught that we may be
   working with object names that are not computed with SHA-1.

 * The in-core repository instances are passed through more codepaths.

 * Update the protocol message specification to allow only the limited
   use of scaled quantities.  This is ensure potential compatibility
   issues will not go out of hand.

 * Micro-optimize the code that prepares commit objects to be walked
   by "git rev-list" when the commit-graph is available.

 * "git fetch" and "git upload-pack" learned to send all exchange over
   the sideband channel while talking the v2 protocol.

 * The codepath to write out commit-graph has been optimized by
   following the usual pattern of visiting objects in in-pack order.

 * The codepath to show progress meter while writing out commit-graph
   file has been improved.

 * Cocci rules have been updated to encourage use of strbuf_addbuf().

 * "git rebase --merge" has been reimplemented by reusing the internal
   machinery used for "git rebase -i".

 * More code in "git bisect" has been rewritten in C.

 * Instead of going through "git-rebase--am" scriptlet to use the "am"
   backend, the built-in version of "git rebase" learned to drive the
   "am" backend directly.

 * The assumption to work on the single "in-core index" instance has
   been reduced from the library-ish part of the codebase.

 * The test lint learned to catch non-portable "sed" options.

 * "git pack-objects" learned another algorithm to compute the set of
   objects to send, that trades the resulting packfile off to save
   traversal cost to favor small pushes.

 * The travis CI scripts have been corrected to build Git with the
   compiler(s) of our choice.

 * "git submodule update" learned to abort early when core.worktree
   for the submodule is not set correctly to prevent spreading damage.

 * Test suite has been adjusted to run on Azure Pipeline.

 * Running "Documentation/doc-diff x" from anywhere other than the
   top-level of the working tree did not show the usage string
   correctly, which has been fixed.

 * Use of the sparse tool got easier to customize from the command
   line to help developers.


Fixes since v2.20
-----------------

 * Updates for corner cases in merge-recursive.
   (merge cc4cb0902c en/merge-path-collision later to maint).

 * "git checkout frotz" (without any double-dash) avoids ambiguity by
   making sure 'frotz' cannot be interpreted as a revision and as a
   path at the same time.  This safety has been updated to check also
   a unique remote-tracking branch 'frotz' in a remote, when dwimming
   to create a local branch 'frotz' out of a remote-tracking branch
   'frotz' from a remote.
   (merge be4908f103 nd/checkout-dwim-fix later to maint).

 * Refspecs configured with "git -c var=val clone" did not propagate
   to the resulting repository, which has been corrected.
   (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).

 * A properly configured username/email is required under
   user.useConfigOnly in order to create commits; now "git stash"
   (even though it creates commit objects to represent stash entries)
   command is exempt from the requirement.
   (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).

 * The http-backend CGI process did not correctly clean up the child
   processes it spawns to run upload-pack etc. when it dies itself,
   which has been corrected.
   (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).

 * "git rev-list --exclude-promisor-objects" had to take an object
   that does not exist locally (and is lazily available) from the
   command line without barfing, but the code dereferenced NULL.
   (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).

 * The traversal over tree objects has learned to honor
   ":(attr:label)" pathspec match, which has been implemented only for
   enumerating paths on the filesystem.
   (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).

 * BSD port updates.
   (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
   (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
   (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).

 * Lines that begin with a certain keyword that come over the wire, as
   well as lines that consist only of one of these keywords, ought to
   be painted in color for easier eyeballing, but the latter was
   broken ever since the feature was introduced in 2.19, which has
   been corrected.
   (merge 1f67290450 hn/highlight-sideband-keywords later to maint).

 * "git log -G<regex>" looked for a hunk in the "git log -p" patch
   output that contained a string that matches the given pattern.
   Optimize this code to ignore binary files, which by default will
   not show any hunk that would match any pattern (unless textconv or
   the --text option is in effect, that is).
   (merge e0e7cb8080 tb/log-G-binary later to maint).

 * "git submodule update" ought to use a single job unless asked, but
   by mistake used multiple jobs, which has been fixed.
   (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).

 * "git stripspace" should be usable outside a git repository, but
   under the "-s" or "-c" mode, it didn't.
   (merge 957da75802 jn/stripspace-wo-repository later to maint).

 * Some of the documentation pages formatted incorrectly with
   Asciidoctor, which have been fixed.
   (merge b62eb1d2f4 ma/asciidoctor later to maint).

 * The core.worktree setting in a submodule repository should not be
   pointing at a directory when the submodule loses its working tree
   (e.g. getting deinit'ed), but the code did not properly maintain
   this invariant.

 * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
   when the completed path has a special character like SP in it,
   without any attempt to keep "path name" a single filename.  This
   has been fixed to complete it to "git cmd path\ name" just like
   Bash completion does.

 * The test suite tried to see if it is run under bash, but the check
   itself failed under some other implementations of shell (notably
   under NetBSD).  This has been corrected.
   (merge 54ea72f09c sg/test-bash-version-fix later to maint).

 * "git gc" and "git repack" did not close the open packfiles that
   they found unneeded before removing them, which didn't work on a
   platform incapable of removing an open file.  This has been
   corrected.
   (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).

 * The code to drive GIT_EXTERNAL_DIFF command relied on the string
   returned from getenv() to be non-volatile, which is not true, that
   has been corrected.
   (merge 6776a84dae kg/external-diff-save-env later to maint).

 * There were many places the code relied on the string returned from
   getenv() to be non-volatile, which is not true, that have been
   corrected.
   (merge 0da0e9268b jk/save-getenv-result later to maint).

 * The v2 upload-pack protocol implementation failed to honor
   hidden-ref configuration, which has been corrected.
   (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).

 * "git fetch --recurse-submodules" may not fetch the necessary commit
   that is bound to the superproject, which is getting corrected.
   (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).

 * "git rebase" internally runs "checkout" to switch between branches,
   and the command used to call the post-checkout hook, but the
   reimplementation stopped doing so, which is getting fixed.

 * "git add -e" got confused when the change it wants to let the user
   edit is smaller than the previous change that was left over in a
   temporary file.
   (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).

 * "git p4" failed to update a shelved change when there were moved
   files, which has been corrected.
   (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).

 * The codepath to read from the commit-graph file attempted to read
   past the end of it when the file's table-of-contents was corrupt.

 * The compat/obstack code had casts that -Wcast-function-type
   compilation option found questionable.
   (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).

 * An obvious typo in an assertion error message has been fixed.
   (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).

 * In Git for Windows, "git clone \\server\share\path" etc. that uses
   UNC paths from command line had bad interaction with its shell
   emulation.

 * "git add --ignore-errors" did not work as advertised and instead
   worked as an unintended synonym for "git add --renormalize", which
   has been fixed.
   (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).

 * On a case-insensitive filesystem, we failed to compare the part of
   the path that is above the worktree directory in an absolute
   pathname, which has been corrected.

 * Asking "git check-attr" about a macro (e.g. "binary") on a specific
   path did not work correctly, even though "git check-attr -a" listed
   such a macro correctly.  This has been corrected.
   (merge 7b95849be4 jk/attr-macro-fix later to maint).

 * "git pack-objects" incorrectly used uninitialized mutex, which has
   been corrected.
   (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).

 * "git checkout -b <new> [HEAD]" to create a new branch from the
   current commit and check it out ought to be a no-op in the index
   and the working tree in normal cases, but there are corner cases
   that do require updates to the index and the working tree.  Running
   it immediately after "git clone --no-checkout" is one of these
   cases that an earlier optimization kicked in incorrectly, which has
   been fixed.
   (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).

 * "git diff --color-moved --cc --stat -p" did not work well due to
   funny interaction between a bug in color-moved and the rest, which
   has been fixed.
   (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).

 * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
   started when modes of "git rebase" that implicitly uses the
   machinery for the interactive rebase are run, which has been
   corrected.
   (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).

 * The commit-graph facility did not work when in-core objects that
   are promoted from unknown type to commit (e.g. a commit that is
   accessed via a tag that refers to it) were involved, which has been
   corrected.
   (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).

 * "git fetch" output cleanup.
   (merge dc40b24df4 nd/fetch-compact-update later to maint).

 * "git cat-file --batch" reported a dangling symbolic link by
   mistake, when it wanted to report that a given name is ambiguous.

 * Documentation around core.crlf has been updated.
   (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).

 * The documentation of "git commit-tree" said that the command
   understands "--gpg-sign" in addition to "-S", but the command line
   parser did not know about the longhand, which has been corrected.

 * "git rebase -x $cmd" did not reject multi-line command, even though
   the command is incapable of handling such a command.  It now is
   rejected upfront.
   (merge c762aada1a pw/rebase-x-sanity-check later to maint).

 * Output from "git help" was not correctly aligned, which has been
   fixed.
   (merge 6195a76da4 nd/help-align-command-desc later to maint).

 * The "git submodule summary" subcommand showed shortened commit
   object names by mechanically truncating them at 7-hexdigit, which
   has been improved to let "rev-parse --short" scale the length of
   the abbreviation with the size of the repository.
   (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).

 * The way the OSX build jobs updates its build environment used the
   "--quiet" option to "brew update" command, but it wasn't all that
   quiet to be useful.  The use of the option has been replaced with
   an explicit redirection to the /dev/null (which incidentally would
   have worked around a breakage by recent updates to homebrew, which
   has fixed itself already).
   (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).

 * "git --work-tree=$there --git-dir=$here describe --dirty" did not
   work correctly as it did not pay attention to the location of the
   worktree specified by the user by mistake, which has been
   corrected.
   (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).

 * "git fetch" over protocol v2 that needs to make a second connection
   to backfill tags did not clear a variable that holds shallow
   repository information correctly, leading to an access of freed
   piece of memory.

 * Code cleanup, docfix, build fix, etc.
   (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
   (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
   (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
   (merge ec36c42a63 nd/indentation-fix later to maint).
   (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
   (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
   (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
   (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
   (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
   (merge 3b3357626e nd/style-opening-brace later to maint).
   (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
   (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
   (merge 0650614982 cy/completion-typofix later to maint).
   (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
   (merge bd8d6f0def en/show-ref-doc-fix later to maint).
   (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
   (merge e01378753d cc/fetch-error-message-fix later to maint).
   (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
   (merge d609615f48 js/test-git-installed later to maint).
   (merge ba170517be ja/doc-style-fix later to maint).
   (merge 86fb1c4e77 km/init-doc-typofix later to maint).
   (merge 5cfd4a9d10 nd/commit-doc later to maint).
   (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).

----------------------------------------------------------------

Changes since v2.20.0 are as follows:

Arti Zirk (1):
      git-instaweb: add Python builtin http.server support

Ben Peart (2):
      checkout: add test demonstrating regression with checkout -b on initial commit
      checkout: fix regression in checkout -b on intitial checkout

Brandon Richardson (1):
      commit-tree: add missing --gpg-sign flag

Brandon Williams (1):
      mailmap: update brandon williams's email address

Carlo Marcelo Arenas Belón (4):
      t6036: avoid non-portable "cp -a"
      tests: add lint for non portable cp -a
      t5004: avoid using tar for empty packages
      config.mak.uname: OpenBSD uses BSD semantics with fread for directories

Chayoung You (3):
      zsh: complete unquoted paths with spaces correctly
      completion: treat results of git ls-tree as file paths
      completion: fix typo in git-completion.bash

Christian Couder (3):
      fetch: fix extensions.partialclone name in error message
      partial-clone: add missing 'is' in doc
      helper/test-ref-store: fix "new-sha1" vs "old-sha1" typo

David Turner (1):
      Do not print 'dangling' for cat-file in case of ambiguity

Denis Ovsienko (1):
      docs: fix $strict_export text in gitweb.conf.txt

Derrick Stolee (9):
      merge-recursive: combine error handling
      .gitattributes: ensure t/oid-info/* has eol=lf
      commit-graph: writing missing parents is a BUG
      git-gc.txt: fix typo about gc.writeCommitGraph
      revision: add mark_tree_uninteresting_sparse
      list-objects: consume sparse tree walk
      revision: implement sparse algorithm
      pack-objects: create pack.useSparse setting
      pack-objects: create GIT_TEST_PACK_SPARSE

Elijah Newren (30):
      t6042: add tests for consistency in file collision conflict handling
      t6036, t6042: testcases for rename collision of already conflicting files
      merge-recursive: increase marker length with depth of recursion
      merge-recursive: new function for better colliding conflict resolutions
      merge-recursive: fix rename/add conflict handling
      merge-recursive: improve handling for rename/rename(2to1) conflicts
      merge-recursive: use handle_file_collision for add/add conflicts
      merge-recursive: improve rename/rename(1to2)/add[/add] handling
      t6036, t6043: increase code coverage for file collision handling
      fast-export: convert sha1 to oid
      git-fast-import.txt: fix documentation for --quiet option
      git-fast-export.txt: clarify misleading documentation about rev-list args
      fast-export: use value from correct enum
      fast-export: avoid dying when filtering by paths and old tags exist
      fast-export: move commit rewriting logic into a function for reuse
      fast-export: when using paths, avoid corrupt stream with non-existent mark
      fast-export: ensure we export requested refs
      fast-export: add --reference-excluded-parents option
      fast-import: remove unmaintained duplicate documentation
      fast-export: add a --show-original-ids option to show original names
      git-rebase.txt: update note about directory rename detection and am
      rebase: make builtin and legacy script error messages the same
      rebase: fix incompatible options error message
      t5407: add a test demonstrating how interactive handles --skip differently
      am, rebase--merge: do not overlook --skip'ed commits with post-rewrite
      git-rebase, sequencer: extend --quiet option for the interactive machinery
      git-legacy-rebase: simplify unnecessary triply-nested if
      rebase: define linearization ordering and enforce it
      rebase: implement --merge via the interactive machinery
      git-show-ref.txt: fix order of flags

Eric Sunshine (1):
      doc/config: do a better job of introducing 'worktree.guessRemote'

Eric Wong (2):
      banned.h: mark strncat() as banned
      t1512: test ambiguous cat-file --batch and --batch-output

Erin Dahlgren (1):
      Simplify handling of setup_git_directory_gently() failure cases.

Force Charlie (1):
      http: add support selecting http version

Frank Dana (1):
      docs/gitweb.conf: config variable typo

Issac Trotts (1):
      log: add %S option (like --source) to log --format

Jean-Noël Avila (2):
      Documentation/Makefile add optional targets for l10n
      doc: tidy asciidoc style

Jeff King (50):
      fsck: do not reuse child_process structs
      submodule--helper: prefer strip_suffix() to ends_with()
      rename "alternate_object_database" to "object_directory"
      sha1_file_name(): overwrite buffer instead of appending
      handle alternates paths the same as the main object dir
      sha1-file: use an object_directory for the main object dir
      object-store: provide helpers for loose_objects_cache
      sha1-file: use loose object cache for quick existence check
      fetch-pack: drop custom loose object cache
      odb_load_loose_cache: fix strbuf leak
      transport-helper: drop read/write errno checks
      sha1-file: fix outdated sha1 comment references
      update comment references to sha1_object_info()
      http: use struct object_id instead of bare sha1
      sha1-file: modernize loose object file functions
      sha1-file: modernize loose header/stream functions
      sha1-file: convert pass-through functions to object_id
      convert has_sha1_file() callers to has_object_file()
      sha1-file: drop has_sha1_file()
      sha1-file: prefer "loose object file" to "sha1 file" in messages
      sha1-file: avoid "sha1 file" for generic use in messages
      prefer "hash mismatch" to "sha1 mismatch"
      upload-pack: support hidden refs with protocol v2
      remote: check config validity before creating rewrite struct
      get_super_prefix(): copy getenv() result
      commit: copy saved getenv() result
      config: make a copy of $GIT_CONFIG string
      init: make a copy of $GIT_DIR string
      merge-recursive: copy $GITHEAD strings
      builtin_diff(): read $GIT_DIFF_OPTS closer to use
      add: use separate ADD_CACHE_RENORMALIZE flag
      attr: do not mark queried macros as unset
      t4006: resurrect commented-out tests
      diff: clear emitted_symbols flag after use
      combine-diff: factor out stat-format mask
      combine-diff: treat --shortstat like --stat
      combine-diff: treat --summary like --stat
      combine-diff: treat --dirstat like --stat
      match-trees: drop unused path parameter from score functions
      apply: drop unused "def" parameter from find_name_gnu()
      create_bundle(): drop unused "header" parameter
      column: drop unused "opts" parameter in item_length()
      show_date_relative(): drop unused "tz" parameter
      config: drop unused parameter from maybe_remove_section()
      convert: drop len parameter from conversion checks
      convert: drop path parameter from actual conversion functions
      doc/gitattributes: clarify "autocrlf overrides eol"
      docs/config: clarify "text property" in core.eol
      test-date: drop unused parameter to getnanos()
      add_to_index(): convert forgotten HASH_RENORMALIZE check

Johannes Schindelin (39):
      rebase: introduce --reschedule-failed-exec
      rebase: add a config option to default to --reschedule-failed-exec
      rebase: introduce a shortcut for --reschedule-failed-exec
      help.h: fix coding style
      help -a: handle aliases with long names gracefully
      t4256: mark support files as LF-only
      t9902: 'send-email' test case requires PERL
      gc/repack: release packs when needed
      add --edit: truncate the patch file
      t6042: work around speed optimization on Windows
      abspath_part_inside_repo: respect core.ignoreCase
      rebase: move `reset_head()` into a better spot
      rebase: avoid double reflog entry when switching branches
      rebase: teach `reset_head()` to optionally skip the worktree
      built-in rebase: call `git am` directly
      mingw (t5580): document bug when cloning from backslashed UNC paths
      mingw: special-case arguments to `sh`
      tests: explicitly use `test-tool.exe` on Windows
      travis: fix skipping tagged releases
      ci: rename the library of common functions
      ci/lib.sh: encapsulate Travis-specific things
      ci: inherit --jobs via MAKEFLAGS in run-build-and-tests
      ci: use a junction on Windows instead of a symlink
      test-date: add a subcommand to measure times in shell scripts
      tests: optionally write results as JUnit-style .xml
      ci/lib.sh: add support for Azure Pipelines
      Add a build definition for Azure DevOps
      ci: add a Windows job to the Azure Pipelines definition
      ci: use git-sdk-64-minimal build artifact
      mingw: be more generous when wrapping up the setitimer() emulation
      README: add a build badge (status of the Azure Pipelines build)
      tests: avoid calling Perl just to determine file sizes
      tests: include detailed trace logs with --write-junit-xml upon failure
      mingw: try to work around issues with the test cleanup
      tests: add t/helper/ to the PATH with --with-dashes
      t0061: workaround issues with --with-dashes and RUNTIME_PREFIX
      tests: optionally skip bin-wrappers/
      ci: speed up Windows phase
      ci: parallelize testing on Windows

Jonathan Nieder (1):
      stripspace: allow -s/-c outside git repository

Jonathan Tan (9):
      revision: use commit graph in get_reference()
      fetch-pack: support protocol version 2
      fetch-pack: do not take shallow lock unnecessarily
      upload-pack: teach deepen-relative in protocol v2
      pkt-line: introduce struct packet_writer
      sideband: reverse its dependency on pkt-line
      {fetch,upload}-pack: sideband v2 fetch response
      tests: define GIT_TEST_SIDEBAND_ALL
      ls-refs: filter refs using namespace-stripped name

Josh Steadmon (4):
      filter-options: expand scaled numbers
      commit-graph, fuzz: add fuzzer for commit-graph
      commit-graph: fix buffer read-overflow
      Makefile: correct example fuzz build

Junio C Hamano (13):
      t0027: squelch checkout path run outside test_expect_* block
      t0061: do not fail test if '.' is part of $PATH
      run-command: report exec failure
      submodule update: run at most one fetch job unless otherwise set
      Git 2.20.1
      Prepare for 2.21 cycle to start soonish
      First batch after 2.20.1
      ref-filter: give uintmax_t to format with %PRIuMAX
      Second batch after 2.20
      Third batch after 2.20
      Fourth batch after 2.20
      Fifth batch for 2.21
      Git 2.21-rc0

Kim Gybels (1):
      diff: ensure correct lifetime of external_diff_cmd

Kyle Meyer (2):
      rebase docs: drop stray word in merge command description
      init docs: correct a punctuation typo

Laura Abbott (1):
      git-quiltimport: add --keep-non-patch option

Linus Torvalds (1):
      Add 'human' date format

Luke Diamand (2):
      git-p4: add failing test for shelved CL update involving move/copy
      git-p4: handle update of moved/copied files when updating a shelve

Martin Ågren (5):
      git-column.txt: fix section header
      Documentation: do not nest open blocks
      git-status.txt: render tables correctly under Asciidoctor
      t7510: invoke git as part of &&-chain
      doc-diff: don't `cd_to_toplevel`

Masaya Suzuki (7):
      Use packet_reader instead of packet_read_line
      pack-protocol.txt: accept error packets in any context
      http: support file handles for HTTP_KEEP_ERROR
      http: enable keep_error for HTTP requests
      remote-curl: define struct for CURLOPT_WRITEFUNCTION
      remote-curl: unset CURLOPT_FAILONERROR
      test: test GIT_CURL_VERBOSE=1 shows an error

Matthew DeVore (4):
      list-objects.c: don't segfault for missing cmdline objects
      revision.c: put promisor option in specialized struct
      list-objects-filter: teach tree:# how to handle >0
      tree:<depth>: skip some trees even when collecting omits

Matthieu Moy (1):
      git-multimail: update to release 1.5.0

Max Kirillov (1):
      http-backend: enable cleaning up forked upload/receive-pack on exit

Nguyễn Thái Ngọc Duy (63):
      git.c: mark more strings for translation
      alias.c: mark split_cmdline_strerror() strings for translation
      archive.c: mark more strings for translation
      attr.c: mark more string for translation
      read-cache.c: turn die("internal error") to BUG()
      read-cache.c: mark more strings for translation
      read-cache.c: add missing colon separators
      reflog: mark strings for translation
      remote.c: turn some error() or die() to BUG()
      remote.c: mark messages for translation
      repack: mark more strings for translation
      parse-options: replace opterror() with optname()
      parse-options.c: turn some die() to BUG()
      parse-options.c: mark more strings for translation
      fsck: reduce word legos to help i18n
      fsck: mark strings for translation
      wt-status.c: remove implicit dependency on the_index
      wt-status.c: remove implicit dependency the_repository
      list-objects-filter.c: remove implicit dependency on the_index
      list-objects.c: reduce the_repository references
      notes-merge.c: remove implicit dependency on the_index
      notes-merge.c: remove implicit dependency the_repository
      transport.c: remove implicit dependency on the_index
      sequencer.c: remove implicit dependency on the_index
      sequencer.c: remove implicit dependency on the_repository
      blame.c: remove implicit dependency the_repository
      bisect.c: remove the_repository reference
      branch.c: remove the_repository reference
      bundle.c: remove the_repository references
      cache-tree.c: remove the_repository references
      delta-islands.c: remove the_repository references
      diff-lib.c: remove the_repository references
      line-log.c: remove the_repository reference
      notes-cache.c: remove the_repository references
      pack-check.c: remove the_repository references
      pack-*.c: remove the_repository references
      rerere.c: remove the_repository references
      rebase-interactive.c: remove the_repository references
      checkout: disambiguate dwim tracking branches and local files
      checkout: print something when checking out paths
      tree.c: make read_tree*() take 'struct repository *'
      tree-walk.c: make tree_entry_interesting() take an index
      pathspec.h: clean up "extern" in function declarations
      dir.c: move, rename and export match_attrs()
      tree-walk: support :(attr) matching
      Indent code with TABs
      style: the opening '{' of a function is in a separate line
      parse-options: fix SunCC compiler warning
      worktree: allow to (re)move worktrees with uninitialized submodules
      grep: use grep_opt->repo instead of explict repo argument
      notes-utils.c: remove the_repository references
      repository.c: replace hold_locked_index() with repo_hold_locked_index()
      checkout: avoid the_index when possible
      read-cache.c: kill read_index()
      read-cache.c: replace update_index_if_able with repo_&
      sha1-name.c: remove implicit dependency on the_index
      merge-recursive.c: remove implicit dependency on the_index
      merge-recursive.c: remove implicit dependency on the_repository
      read-cache.c: remove the_* from index_has_changes()
      cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch
      fetch: prefer suffix substitution in compact fetch.output
      help: align the longest command in the command listing
      git-commit.txt: better description what it does

Olga Telezhnaya (6):
      ref-filter: add objectsize:disk option
      ref-filter: add check for negative file size
      ref-filter: add tests for objectsize:disk
      ref-filter: add deltabase option
      ref-filter: add tests for deltabase
      ref-filter: add docs for new options

Orgad Shaneh (2):
      t5403: simplify by using a single repository
      rebase: run post-checkout hook on checkout

Patrick Hogg (2):
      pack-objects: move read mutex to packing_data struct
      pack-objects: merge read_lock and lock in packing_data struct

Peter Osterlund (1):
      git-p4: fix problem when p4 login is not necessary

Phillip Wood (11):
      diff: document --no-color-moved
      Use "whitespace" consistently
      diff: allow --no-color-moved-ws
      diff --color-moved-ws: demonstrate false positives
      diff --color-moved-ws: fix false positives
      diff --color-moved=zebra: be stricter with color alternation
      diff --color-moved-ws: optimize allow-indentation-change
      diff --color-moved-ws: modify allow-indentation-change
      diff --color-moved-ws: handle blank lines
      implicit interactive rebase: don't run sequence editor
      rebase -x: sanity check command

Pranit Bauva (7):
      bisect--helper: `bisect_reset` shell function in C
      bisect--helper: `bisect_write` shell function in C
      wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()
      bisect--helper: `check_and_set_terms` shell function in C
      bisect--helper: `bisect_next_check` shell function in C
      bisect--helper: `get_terms` & `bisect_terms` shell function in C
      bisect--helper: `bisect_start` shell function partially in C

Ramsay Jones (2):
      config.mak.uname: remove obsolete SPARSE_FLAGS setting
      Makefile: improve SPARSE_FLAGS customisation

Randall S. Becker (4):
      transport-helper: use xread instead of read
      config.mak.uname: support for modern HPE NonStop config.
      git-compat-util.h: add FLOSS headers for HPE NonStop
      compat/regex/regcomp.c: define intptr_t and uintptr_t on NonStop

René Scharfe (5):
      sha1-file: close fd of empty file in map_sha1_file_1()
      object-store: factor out odb_loose_cache()
      object-store: factor out odb_clear_loose_cache()
      object-store: use one oid_array per subdirectory for loose cache
      object-store: retire odb_load_loose_cache()

SZEDER Gábor (22):
      clone: use a more appropriate variable name for the default refspec
      clone: respect additional configured fetch refspecs during initial fetch
      Documentation/clone: document ignored configuration variables
      test-lib: check Bash version for '-x' without using shell arrays
      test-lib: translate SIGTERM and SIGHUP to an exit
      test-lib: extract Bash version check for '-x' tracing
      test-lib: parse options in a for loop to keep $@ intact
      test-lib: parse command line options earlier
      test-lib: consolidate naming of test-results paths
      test-lib: set $TRASH_DIRECTORY earlier
      test-lib-functions: introduce the 'test_set_port' helper function
      test-lib: add the '--stress' option to run a test repeatedly under load
      compat/obstack: fix -Wcast-function-type warnings
      .gitignore: ignore external debug symbols from GCC on macOS
      travis-ci: don't be '--quiet' when running the tests
      travis-ci: switch to Xcode 10.1 macOS image
      travis-ci: build with the right compiler
      commit-graph: rename "large edges" to "extra edges"
      commit-graph: don't call write_graph_chunk_extra_edges() unnecessarily
      strbuf.cocci: suggest strbuf_addbuf() to add one strbuf to an other
      object_as_type: initialize commit-graph-related fields of 'struct commit'
      travis-ci: make the OSX build jobs' 'brew update' more quiet

Sebastian Staudt (2):
      describe: setup working tree for --dirty
      t6120: test for describe with a bare repository

Sergey Organov (4):
      t3510: stop using '-m 1' to force failure mid-sequence of cherry-picks
      cherry-pick: do not error on non-merge commits when '-m 1' is specified
      t3502: validate '-m 1' argument is now accepted for non-merge commits
      t3506: validate '-m 1 -ff' is now accepted for non-merge commits

Shahzad Lone (1):
      various: tighten constness of some local variables

Slavica Djukic (1):
      stash: tolerate missing user identity

Stefan Beller (39):
      sha1_file: allow read_object to read objects in arbitrary repositories
      packfile: allow has_packed_and_bad to handle arbitrary repositories
      diff: align move detection error handling with other options
      object-store: allow read_object_file_extended to read from any repo
      object-store: prepare read_object_file to deal with any repo
      object-store: prepare has_{sha1, object}_file to handle any repo
      object: parse_object to honor its repository argument
      commit: allow parse_commit* to handle any repo
      commit-reach.c: allow paint_down_to_common to handle any repo
      commit-reach.c: allow merge_bases_many to handle any repo
      commit-reach.c: allow remove_redundant to handle any repo
      commit-reach.c: allow get_merge_bases_many_0 to handle any repo
      commit-reach: prepare get_merge_bases to handle any repo
      commit-reach: prepare in_merge_bases[_many] to handle any repo
      commit: prepare get_commit_buffer to handle any repo
      commit: prepare repo_unuse_commit_buffer to handle any repo
      commit: prepare logmsg_reencode to handle arbitrary repositories
      pretty: prepare format_commit_message to handle arbitrary repositories
      sideband: color lines with keyword only
      sha1-array: provide oid_array_filter
      submodule.c: fix indentation
      submodule.c: sort changed_submodule_names before searching it
      submodule.c: tighten scope of changed_submodule_names struct
      submodule: store OIDs in changed_submodule_names
      repository: repo_submodule_init to take a submodule struct
      submodule: migrate get_next_submodule to use repository structs
      submodule.c: fetch in submodules git directory instead of in worktree
      fetch: ensure submodule objects fetched
      submodule update: add regression test with old style setups
      submodule: unset core.worktree if no working tree is present
      submodule--helper: fix BUG message in ensure_core_worktree
      submodule deinit: unset core.worktree
      submodule: use submodule repos for object lookup
      submodule: don't add submodule as odb for push
      commit-graph: convert remaining functions to handle any repo
      commit: prepare free_commit_buffer and release_commit_memory for any repo
      path.h: make REPO_GIT_PATH_FUNC repository agnostic
      t/helper/test-repository: celebrate independence from the_repository
      git-submodule: abort if core.worktree could not be set correctly

Stephen P. Smith (4):
      Replace the proposed 'auto' mode with 'auto:'
      Add 'human' date format documentation
      Add `human` format to test-tool
      Add `human` date format tests.

Sven van Haastregt (1):
      git-submodule.sh: shorten submodule SHA-1s using rev-parse

Thomas Braun (1):
      log -G: ignore binary files

Thomas Gummerer (3):
      t5570: drop racy test
      Revert "t/lib-git-daemon: record daemon log"
      config.mak.dev: add -Wall, primarily for -Wformat, to help autoconf users

Torsten Bögershausen (3):
      git clone <url> C:\cygwin\home\USER\repo' is working (again)
      test-lint: only use only sed [-n] [-e command] [-f command_file]
      Support working-tree-encoding "UTF-16LE-BOM"

brian m. carlson (19):
      sha1-file: rename algorithm to "sha1"
      sha1-file: provide functions to look up hash algorithms
      hex: introduce functions to print arbitrary hashes
      cache: make hashcmp and hasheq work with larger hashes
      t: add basic tests for our SHA-1 implementation
      t: make the sha1 test-tool helper generic
      sha1-file: add a constant for hash block size
      t/helper: add a test helper to compute hash speed
      commit-graph: convert to using the_hash_algo
      Add a base implementation of SHA-256 support
      sha256: add an SHA-256 implementation using libgcrypt
      hash: add an SHA-256 implementation using OpenSSL
      tree-walk: copy object ID before use
      match-trees: compute buffer offset correctly when splicing
      match-trees: use hashcpy to splice trees
      tree-walk: store object_id in a separate member
      cache: make oidcpy always copy GIT_MAX_RAWSZ bytes
      fetch-pack: clear alternate shallow when complete
      fetch-pack: clear alternate shallow in one more place

Ævar Arnfjörð Bjarmason (17):
      remote.c: add braces in anticipation of a follow-up change
      i18n: remote.c: mark error(...) messages for translation
      push: improve the error shown on unqualified <dst> push
      push: move unqualified refname error into a function
      push: add an advice on unqualified <dst> push
      push: test that <src> doesn't DWYM if <dst> is unqualified
      push doc: document the DWYM behavior pushing to unqualified <dst>
      commit-graph: split up close_reachable() progress output
      commit-graph write: use pack order when finding commits
      commit-graph write: add "Writing out" progress output
      commit-graph write: more descriptive "writing out" output
      commit-graph write: show progress for object search
      commit-graph write: add more descriptive progress output
      commit-graph write: remove empty line for readability
      commit-graph write: add itermediate progress
      commit-graph write: emit a percentage for all progress
      diff-tree doc: correct & remove wrong documentation


^ permalink raw reply	[relevance 3%]

* Git Test Coverage Report (Wednesday, Feb. 6)
@ 2019-02-06 14:41  1% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2019-02-06 14:41 UTC (permalink / raw)
  To: git@vger.kernel.org

Here is today's test coverage report.

Thanks,
-Stolee

[1] https://derrickstolee.github.io/git-test-coverage/reports/2019-02-06.htm
[2] https://derrickstolee.github.io/git-test-coverage/reports/2019-02-06.txt
[3] https://dev.azure.com/git/git/_build/results?buildId=335

---

pu	6e9ee141a1008e2fa8374f008861cd8100bbf922
jch	0dcb92d596127ce52eb144229b8a848ea28433b6
next	b4d0f1c61aafd6cb5c3d9e6ee6bd99a036e3f21d
master	8feddda32cc50e928404788d7b9377c0b5f73f50
master@{1}	16a465bc018d09e9d7bbbdc5f40a7fb99c21f8ef


Uncovered code in 'pu' not in 'jch'
--------------------------------------------------------

builtin/commit.c
8e7e6c05 1668) return 1;

builtin/config.c
a12c1ff3 110) die(_("$HOME not set"));
a12c1ff3 122) given_config_source.file = git_etc_gitconfig();
6f11fd5e 489) BUG("action %d cannot get here", actions);
6f11fd5e 503) die(_("unknown config source"));
6f11fd5e 509) die(_("invalid key pattern: %s"), key);

builtin/gc.c
8e7e6c05 670) return 1;

builtin/rebase.c
34fed676 1224) if (is_interactive(&options))
34fed676 1225) trace2_cmd_mode("interactive");
34fed676 1226) else if (exec.nr)
34fed676 1227) trace2_cmd_mode("interactive-exec");
34fed676 1229) trace2_cmd_mode(action_names[action]);

commit-graph.c
b1beb050 877) error(_("unsupported commit-graph version %d"),
b1beb050 879) return 1;
8e7e6c05 929) error(_("error adding pack %s"), packname.buf);
8e7e6c05 930) res = 1;
8e7e6c05 931) goto cleanup;
8e7e6c05 934) error(_("error opening index for %s"), packname.buf);
8e7e6c05 935) res = 1;
8e7e6c05 936) goto cleanup;
8e7e6c05 1009) error(_("the commit graph format cannot write %d commits"), count_distinct);
8e7e6c05 1010) res = 1;
8e7e6c05 1011) goto cleanup;
8e7e6c05 1045) error(_("too many commits to write graph"));
8e7e6c05 1046) res = 1;
8e7e6c05 1047) goto cleanup;
8e7e6c05 1055) error(_("unable to create leading directories of %s"),
8e7e6c05 1057) res = errno;
8e7e6c05 1058) goto cleanup;

config.c
8f7c7f55 2143) int repo_config_set_gently(struct repository *r,
8f7c7f55 2146) char *path = repo_git_path(r, "config");
8f7c7f55 2147) int ret = git_config_set_multivar_in_file_gently(path, key, value, NULL, 0);
8f7c7f55 2148) free(path);
8f7c7f55 2149) return ret;
8f7c7f55 2152) void repo_config_set(struct repository *r, const char *key, const char *value)
8f7c7f55 2154) if (!repo_config_set_gently(r, key, value))
8f7c7f55 2155) return;
8f7c7f55 2156) if (value)
8f7c7f55 2157) die(_("could not set '%s' to '%s'"), key, value);
8f7c7f55 2159) die(_("could not unset '%s'"), key);
8f7c7f55 2162) int repo_config_set_worktree_gently(struct repository *r,
8f7c7f55 2168) path = get_worktree_config(r);
8f7c7f55 2169) if (!path)
8f7c7f55 2170) return CONFIG_INVALID_FILE;
8f7c7f55 2171) ret = git_config_set_multivar_in_file_gently(path, key, value, NULL, 0);
8f7c7f55 2172) free(path);
8f7c7f55 2173) return ret;

git.c
3c543ab3 155) trace2_cmd_name("_query_");
3c543ab3 159) trace2_cmd_name("_query_");
3c543ab3 163) trace2_cmd_name("_query_");

http.c
ba81921a 1999) if (fflush((FILE *)result)) {
ba81921a 2003) rewind((FILE *)result);
ba81921a 2004) if (ftruncate(fileno((FILE *)result), 0) < 0) {

pager.c
3507f837 103) pager_process->trace2_child_class = "pager";

protocol.c
6da1f1a9 37) die(_("Unrecognized protocol version"));
6da1f1a9 39) die(_("Unrecognized protocol_version"));
6da1f1a9 61) BUG("late attempt to register an allowed protocol version");

ref-filter.c
358c9418 93) keydata_aka_refname ? keydata_aka_refname : k->wt->head_ref);

remote-curl.c
6da1f1a9 404) return 0;

run-command.c
3c543ab3 239) int ec = errno;
3c543ab3 240) trace2_exec_result(exec_id, ec);
3c543ab3 241) errno = ec;
3c543ab3 997) int ret = wait_or_whine(cmd->pid, cmd->argv[0], 1);
3c543ab3 998) trace2_child_exit(cmd, ret);
3c543ab3 999) return ret;
3c543ab3 1021) int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class)
3c543ab3 1023) return run_command_v_opt_cd_env_tr2(argv, opt, NULL, NULL, tr2_class);

t/helper/test-trace2.c
7bc0969b 24) return MyError;
7bc0969b 28) return MyError;
7bc0969b 52) die("expect <exit_code>");
7bc0969b 72) die("expect <exit_code>");
7bc0969b 92) die("expect <error_message>");
7bc0969b 142) return 0;
7bc0969b 169) static int ut_005exec(int argc, const char **argv)
7bc0969b 173) if (!argc)
7bc0969b 174) return 0;
7bc0969b 176) result = execv_git_cmd(argv);
7bc0969b 177) return result;
7bc0969b 186) die("%s", usage_error);
7bc0969b 191) die("%s", usage_error);
7bc0969b 227) static int print_usage(void)
7bc0969b 232) fprintf(stderr, "usage:\n");
7bc0969b 233) for_each_ut (k, ut_k)
7bc0969b 234) fprintf(stderr, "\t%s %s %s\n", USAGE_PREFIX, ut_k->ut_name,
7bc0969b 237) return 129;
7bc0969b 272) return print_usage();

trace2.c
3c543ab3 127) static void tr2main_signal_handler(int signo)
3c543ab3 134) us_now = getnanotime() / 1000;
3c543ab3 135) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 137) for_each_wanted_builtin (j, tgt_j)
3c543ab3 138) if (tgt_j->pfn_signal)
3c543ab3 139) tgt_j->pfn_signal(us_elapsed_absolute, signo);
3c543ab3 141) sigchain_pop(signo);
3c543ab3 142) raise(signo);
3c543ab3 143) }
3c543ab3 151) return;
3c543ab3 232) void trace2_cmd_path_fl(const char *file, int line, const char *pathname)
3c543ab3 237) if (!trace2_enabled)
3c543ab3 238) return;
3c543ab3 240) for_each_wanted_builtin (j, tgt_j)
3c543ab3 241) if (tgt_j->pfn_command_path_fl)
3c543ab3 242) tgt_j->pfn_command_path_fl(file, line, pathname);
3c543ab3 271) for_each_wanted_builtin (j, tgt_j)
3c543ab3 272) if (tgt_j->pfn_command_mode_fl)
3c543ab3 273) tgt_j->pfn_command_mode_fl(file, line, mode);
3c543ab3 285) for_each_wanted_builtin (j, tgt_j)
3c543ab3 286) if (tgt_j->pfn_alias_fl)
3c543ab3 287) tgt_j->pfn_alias_fl(file, line, alias, argv);
3c543ab3 304) tr2_cfg_set_fl(file, line, key, value);
3c543ab3 348) us_elapsed_child = 0;
3c543ab3 371) us_now = getnanotime() / 1000;
3c543ab3 372) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 374) exec_id = tr2tls_locked_increment(&tr2_next_exec_id);
3c543ab3 376) for_each_wanted_builtin (j, tgt_j)
3c543ab3 377) if (tgt_j->pfn_exec_fl)
3c543ab3 378) tgt_j->pfn_exec_fl(file, line, us_elapsed_absolute,
3c543ab3 381) return exec_id;
3c543ab3 384) void trace2_exec_result_fl(const char *file, int line, int exec_id, int code)
3c543ab3 391) if (!trace2_enabled)
3c543ab3 392) return;
3c543ab3 394) us_now = getnanotime() / 1000;
3c543ab3 395) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 397) for_each_wanted_builtin (j, tgt_j)
3c543ab3 398) if (tgt_j->pfn_exec_result_fl)
3c543ab3 399) tgt_j->pfn_exec_result_fl(
3c543ab3 403) void trace2_thread_start_fl(const char *file, int line, const char *thread_name)
3c543ab3 410) if (!trace2_enabled)
3c543ab3 411) return;
3c543ab3 413) if (tr2tls_is_main_thread()) {
3c543ab3 423) trace2_region_enter_printf_fl(file, line, NULL, NULL, NULL,
3c543ab3 426) return;
3c543ab3 429) us_now = getnanotime() / 1000;
3c543ab3 430) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 432) tr2tls_create_self(thread_name);
3c543ab3 434) for_each_wanted_builtin (j, tgt_j)
3c543ab3 435) if (tgt_j->pfn_thread_start_fl)
3c543ab3 436) tgt_j->pfn_thread_start_fl(file, line,
3c543ab3 440) void trace2_thread_exit_fl(const char *file, int line)
3c543ab3 448) if (!trace2_enabled)
3c543ab3 449) return;
3c543ab3 451) if (tr2tls_is_main_thread()) {
3c543ab3 462) trace2_region_leave_printf_fl(file, line, NULL, NULL, NULL,
3c543ab3 464) return;
3c543ab3 467) us_now = getnanotime() / 1000;
3c543ab3 468) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 475) tr2tls_pop_unwind_self();
3c543ab3 476) us_elapsed_thread = tr2tls_region_elasped_self(us_now);
3c543ab3 478) for_each_wanted_builtin (j, tgt_j)
3c543ab3 479) if (tgt_j->pfn_thread_exit_fl)
3c543ab3 480) tgt_j->pfn_thread_exit_fl(file, line,
3c543ab3 484) tr2tls_unset_self();
3c543ab3 494) return;
3c543ab3 509) if (repo->trace2_repo_id)
3c543ab3 510) return;
3c543ab3 512) repo->trace2_repo_id = tr2tls_locked_increment(&tr2_next_repo_id);
3c543ab3 514) for_each_wanted_builtin (j, tgt_j)
3c543ab3 515) if (tgt_j->pfn_repo_fl)
3c543ab3 516) tgt_j->pfn_repo_fl(file, line, repo);
3c543ab3 532) us_now = getnanotime() / 1000;
3c543ab3 533) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 542) for_each_wanted_builtin (j, tgt_j)
3c543ab3 543) if (tgt_j->pfn_region_enter_printf_va_fl)
3c543ab3 544) tgt_j->pfn_region_enter_printf_va_fl(
3c543ab3 548) tr2tls_push_self(us_now);
3c543ab3 599) us_now = getnanotime() / 1000;
3c543ab3 600) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 608) us_elapsed_region = tr2tls_region_elasped_self(us_now);
3c543ab3 610) tr2tls_pop_self();
3c543ab3 616) for_each_wanted_builtin (j, tgt_j)
3c543ab3 617) if (tgt_j->pfn_region_leave_printf_va_fl)
3c543ab3 618) tgt_j->pfn_region_leave_printf_va_fl(
3c543ab3 669) return;
3c543ab3 691) strbuf_addf(&buf_string, "%" PRIdMAX, value);
3c543ab3 692) trace2_data_string_fl(file, line, category, repo, key, buf_string.buf);
3c543ab3 693) strbuf_release(&buf_string);
3c543ab3 696) void trace2_data_json_fl(const char *file, int line, const char *category,
3c543ab3 706) if (!trace2_enabled)
3c543ab3 707) return;
3c543ab3 709) us_now = getnanotime() / 1000;
3c543ab3 710) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 711) us_elapsed_region = tr2tls_region_elasped_self(us_now);
3c543ab3 713) for_each_wanted_builtin (j, tgt_j)
3c543ab3 714) if (tgt_j->pfn_data_fl)
3c543ab3 715) tgt_j->pfn_data_json_fl(file, line, us_elapsed_absolute,
3c543ab3 720) void trace2_printf_va_fl(const char *file, int line, const char *fmt,
3c543ab3 728) if (!trace2_enabled)
3c543ab3 729) return;
3c543ab3 731) us_now = getnanotime() / 1000;
3c543ab3 732) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
3c543ab3 738) for_each_wanted_builtin (j, tgt_j)
3c543ab3 739) if (tgt_j->pfn_printf_va_fl)
3c543ab3 740) tgt_j->pfn_printf_va_fl(file, line, us_elapsed_absolute,
3c543ab3 744) void trace2_printf_fl(const char *file, int line, const char *fmt, ...)
3c543ab3 748) va_start(ap, fmt);
3c543ab3 749) trace2_printf_va_fl(file, line, fmt, ap);
3c543ab3 750) va_end(ap);
3c543ab3 751) }

trace2/tr2_cfg.c
3c543ab3 21) return tr2_cfg_count_patterns;
3c543ab3 33) strbuf_setlen(buf, buf->len - 1);
3c543ab3 83) void tr2_cfg_set_fl(const char *file, int line, const char *key,
3c543ab3 86) struct tr2_cfg_data data = { file, line };
3c543ab3 88) if (tr2_cfg_load_patterns() > 0)
3c543ab3 89) tr2_cfg_cb(key, value, &data);
3c543ab3 90) }

trace2/tr2_dst.c
3c543ab3 15) static int tr2_dst_want_warning(void)
3c543ab3 19) if (tr2env_dst_debug == -1) {
3c543ab3 20) const char *env_value = getenv(TR2_ENVVAR_DST_DEBUG);
3c543ab3 21) if (!env_value || !*env_value)
3c543ab3 22) tr2env_dst_debug = 0;
3c543ab3 24) tr2env_dst_debug = atoi(env_value) > 0;
3c543ab3 27) return tr2env_dst_debug;
3c543ab3 43) if (tr2_dst_want_warning())
3c543ab3 44) warning("trace2: could not open '%s' for '%s' tracing: %s",
3c543ab3 45) tgt_value, dst->env_var_name, strerror(errno));
3c543ab3 47) tr2_dst_trace_disable(dst);
3c543ab3 48) return 0;
3c543ab3 62) static int tr2_dst_try_unix_domain_socket(struct tr2_dst *dst,
3c543ab3 67) const char *path = tgt_value + PREFIX_AF_UNIX_LEN;
3c543ab3 68) int path_len = strlen(path);
3c543ab3 70) if (!is_absolute_path(path) || path_len >= sizeof(sa.sun_path)) {
3c543ab3 71) if (tr2_dst_want_warning())
3c543ab3 72) warning("trace2: invalid AF_UNIX path '%s' for '%s' tracing",
3c543ab3 75) tr2_dst_trace_disable(dst);
3c543ab3 76) return 0;
3c543ab3 79) sa.sun_family = AF_UNIX;
3c543ab3 80) strlcpy(sa.sun_path, path, sizeof(sa.sun_path));
3c543ab3 81) if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ||
3c543ab3 82)     connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
3c543ab3 83) if (tr2_dst_want_warning())
3c543ab3 84) warning("trace2: could not connect to socket '%s' for '%s' tracing: %s",
3c543ab3 85) path, dst->env_var_name, strerror(errno));
3c543ab3 87) tr2_dst_trace_disable(dst);
3c543ab3 88) return 0;
3c543ab3 91) dst->fd = fd;
3c543ab3 92) dst->need_close = 1;
3c543ab3 93) dst->initialized = 1;
3c543ab3 95) return dst->fd;
3c543ab3 99) static void tr2_dst_malformed_warning(struct tr2_dst *dst,
3c543ab3 102) struct strbuf buf = STRBUF_INIT;
3c543ab3 104) strbuf_addf(&buf, "trace2: unknown trace value for '%s': '%s'",
3c543ab3 106) strbuf_addstr(
3c543ab3 111) strbuf_addstr(
3c543ab3 117) warning("%s", buf.buf);
3c543ab3 119) strbuf_release(&buf);
3c543ab3 120) }
3c543ab3 141) dst->fd = STDERR_FILENO;
3c543ab3 142) return dst->fd;
3c543ab3 146) dst->fd = atoi(tgt_value);
3c543ab3 147) return dst->fd;
3c543ab3 154) if (!strncmp(tgt_value, PREFIX_AF_UNIX, PREFIX_AF_UNIX_LEN))
3c543ab3 155) return tr2_dst_try_unix_domain_socket(dst, tgt_value);
3c543ab3 159) tr2_dst_malformed_warning(dst, tgt_value);
3c543ab3 160) tr2_dst_trace_disable(dst);
3c543ab3 161) return 0;
3c543ab3 193) if (tr2_dst_want_warning())
3c543ab3 194) warning("unable to write trace to '%s': %s", dst->env_var_name,
3c543ab3 195) strerror(errno));
3c543ab3 196) tr2_dst_trace_disable(dst);

trace2/tr2_sid.c
3c543ab3 27) return;
3c543ab3 59) tr2_sid_compute();

trace2/tr2_tgt_event.c
3c543ab3 57) tr2env_event_nesting_wanted = want_nesting;
3c543ab3 61) tr2env_event_brief = want_brief;
3c543ab3 96)     !strcmp(event_name, "atexit")) {
3c543ab3 158) static void fn_signal(uint64_t us_elapsed_absolute, int signo)
3c543ab3 160) const char *event_name = "signal";
3c543ab3 161) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 162) double t_abs = (double)us_elapsed_absolute / 1000000.0;
3c543ab3 164) jw_object_begin(&jw, 0);
3c543ab3 165) event_fmt_prepare(event_name, __FILE__, __LINE__, NULL, &jw);
3c543ab3 166) jw_object_double(&jw, "t_abs", 6, t_abs);
3c543ab3 167) jw_object_intmax(&jw, "signo", signo);
3c543ab3 168) jw_end(&jw);
3c543ab3 170) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 171) jw_release(&jw);
3c543ab3 172) }
3c543ab3 206) if (fmt && *fmt) {
3c543ab3 207) jw_object_string(jw, field_name, fmt);
3c543ab3 208) return;
3c543ab3 235) static void fn_command_path_fl(const char *file, int line, const char *pathname)
3c543ab3 237) const char *event_name = "cmd_path";
3c543ab3 238) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 240) jw_object_begin(&jw, 0);
3c543ab3 241) event_fmt_prepare(event_name, file, line, NULL, &jw);
3c543ab3 242) jw_object_string(&jw, "path", pathname);
3c543ab3 243) jw_end(&jw);
3c543ab3 245) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 246) jw_release(&jw);
3c543ab3 247) }
3c543ab3 267) static void fn_command_mode_fl(const char *file, int line, const char *mode)
3c543ab3 269) const char *event_name = "cmd_mode";
3c543ab3 270) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 272) jw_object_begin(&jw, 0);
3c543ab3 273) event_fmt_prepare(event_name, file, line, NULL, &jw);
3c543ab3 274) jw_object_string(&jw, "name", mode);
3c543ab3 275) jw_end(&jw);
3c543ab3 277) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 278) jw_release(&jw);
3c543ab3 279) }
3c543ab3 281) static void fn_alias_fl(const char *file, int line, const char *alias,
3c543ab3 284) const char *event_name = "alias";
3c543ab3 285) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 287) jw_object_begin(&jw, 0);
3c543ab3 288) event_fmt_prepare(event_name, file, line, NULL, &jw);
3c543ab3 289) jw_object_string(&jw, "alias", alias);
3c543ab3 290) jw_object_inline_begin_array(&jw, "argv");
3c543ab3 291) jw_array_argv(&jw, argv);
3c543ab3 292) jw_end(&jw);
3c543ab3 293) jw_end(&jw);
3c543ab3 295) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 296) jw_release(&jw);
3c543ab3 297) }
3c543ab3 310) jw_object_string(&jw, "child_class", "hook");
3c543ab3 311) jw_object_string(&jw, "hook_name", cmd->trace2_hook_name);
3c543ab3 318) jw_object_string(&jw, "cd", cmd->dir);
3c543ab3 322) jw_array_string(&jw, "git");
3c543ab3 352) static void fn_thread_start_fl(const char *file, int line,
3c543ab3 355) const char *event_name = "thread_start";
3c543ab3 356) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 358) jw_object_begin(&jw, 0);
3c543ab3 359) event_fmt_prepare(event_name, file, line, NULL, &jw);
3c543ab3 360) jw_end(&jw);
3c543ab3 362) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 363) jw_release(&jw);
3c543ab3 364) }
3c543ab3 366) static void fn_thread_exit_fl(const char *file, int line,
3c543ab3 370) const char *event_name = "thread_exit";
3c543ab3 371) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 372) double t_rel = (double)us_elapsed_thread / 1000000.0;
3c543ab3 374) jw_object_begin(&jw, 0);
3c543ab3 375) event_fmt_prepare(event_name, file, line, NULL, &jw);
3c543ab3 376) jw_object_double(&jw, "t_rel", 6, t_rel);
3c543ab3 377) jw_end(&jw);
3c543ab3 379) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 380) jw_release(&jw);
3c543ab3 381) }
3c543ab3 383) static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute,
3c543ab3 386) const char *event_name = "exec";
3c543ab3 387) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 389) jw_object_begin(&jw, 0);
3c543ab3 390) event_fmt_prepare(event_name, file, line, NULL, &jw);
3c543ab3 391) jw_object_intmax(&jw, "exec_id", exec_id);
3c543ab3 392) if (exe)
3c543ab3 393) jw_object_string(&jw, "exe", exe);
3c543ab3 394) jw_object_inline_begin_array(&jw, "argv");
3c543ab3 395) jw_array_argv(&jw, argv);
3c543ab3 396) jw_end(&jw);
3c543ab3 397) jw_end(&jw);
3c543ab3 399) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 400) jw_release(&jw);
3c543ab3 401) }
3c543ab3 403) static void fn_exec_result_fl(const char *file, int line,
3c543ab3 407) const char *event_name = "exec_result";
3c543ab3 408) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 410) jw_object_begin(&jw, 0);
3c543ab3 411) event_fmt_prepare(event_name, file, line, NULL, &jw);
3c543ab3 412) jw_object_intmax(&jw, "exec_id", exec_id);
3c543ab3 413) jw_object_intmax(&jw, "code", code);
3c543ab3 414) jw_end(&jw);
3c543ab3 416) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 417) jw_release(&jw);
3c543ab3 418) }
3c543ab3 436) static void fn_repo_fl(const char *file, int line,
3c543ab3 439) const char *event_name = "def_repo";
3c543ab3 440) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 442) jw_object_begin(&jw, 0);
3c543ab3 443) event_fmt_prepare(event_name, file, line, repo, &jw);
3c543ab3 444) jw_object_string(&jw, "worktree", repo->worktree);
3c543ab3 445) jw_end(&jw);
3c543ab3 447) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 448) jw_release(&jw);
3c543ab3 449) }
3c543ab3 451) static void fn_region_enter_printf_va_fl(const char *file, int line,
3c543ab3 458) const char *event_name = "region_enter";
3c543ab3 459) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
3c543ab3 460) if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) {
3c543ab3 461) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 463) jw_object_begin(&jw, 0);
3c543ab3 464) event_fmt_prepare(event_name, file, line, repo, &jw);
3c543ab3 465) jw_object_intmax(&jw, "nesting", ctx->nr_open_regions);
3c543ab3 466) if (category)
3c543ab3 467) jw_object_string(&jw, "category", category);
3c543ab3 468) if (label)
3c543ab3 469) jw_object_string(&jw, "label", label);
3c543ab3 470) maybe_add_string_va(&jw, "msg", fmt, ap);
3c543ab3 471) jw_end(&jw);
3c543ab3 473) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 474) jw_release(&jw);
3c543ab3 476) }
3c543ab3 478) static void fn_region_leave_printf_va_fl(
3c543ab3 483) const char *event_name = "region_leave";
3c543ab3 484) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
3c543ab3 485) if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) {
3c543ab3 486) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 487) double t_rel = (double)us_elapsed_region / 1000000.0;
3c543ab3 489) jw_object_begin(&jw, 0);
3c543ab3 490) event_fmt_prepare(event_name, file, line, repo, &jw);
3c543ab3 491) jw_object_double(&jw, "t_rel", 6, t_rel);
3c543ab3 492) jw_object_intmax(&jw, "nesting", ctx->nr_open_regions);
3c543ab3 493) if (category)
3c543ab3 494) jw_object_string(&jw, "category", category);
3c543ab3 495) if (label)
3c543ab3 496) jw_object_string(&jw, "label", label);
3c543ab3 497) maybe_add_string_va(&jw, "msg", fmt, ap);
3c543ab3 498) jw_end(&jw);
3c543ab3 500) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 501) jw_release(&jw);
3c543ab3 503) }
3c543ab3 532) static void fn_data_json_fl(const char *file, int line,
3c543ab3 538) const char *event_name = "data_json";
3c543ab3 539) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
3c543ab3 540) if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) {
3c543ab3 541) struct json_writer jw = JSON_WRITER_INIT;
3c543ab3 542) double t_abs = (double)us_elapsed_absolute / 1000000.0;
3c543ab3 543) double t_rel = (double)us_elapsed_region / 1000000.0;
3c543ab3 545) jw_object_begin(&jw, 0);
3c543ab3 546) event_fmt_prepare(event_name, file, line, repo, &jw);
3c543ab3 547) jw_object_double(&jw, "t_abs", 6, t_abs);
3c543ab3 548) jw_object_double(&jw, "t_rel", 6, t_rel);
3c543ab3 549) jw_object_intmax(&jw, "nesting", ctx->nr_open_regions);
3c543ab3 550) jw_object_string(&jw, "category", category);
3c543ab3 551) jw_object_string(&jw, "key", key);
3c543ab3 552) jw_object_sub_jw(&jw, "value", value);
3c543ab3 553) jw_end(&jw);
3c543ab3 555) tr2_dst_write_line(&tr2dst_event, &jw.json);
3c543ab3 556) jw_release(&jw);
3c543ab3 558) }

trace2/tr2_tgt_normal.c
3c543ab3 105) static void fn_signal(uint64_t us_elapsed_absolute, int signo)
3c543ab3 107) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 108) double elapsed = (double)us_elapsed_absolute / 1000000.0;
3c543ab3 110) strbuf_addf(&buf_payload, "signal elapsed:%.6f code:%d", elapsed,
3c543ab3 112) normal_io_write_fl(__FILE__, __LINE__, &buf_payload);
3c543ab3 113) strbuf_release(&buf_payload);
3c543ab3 114) }
3c543ab3 138) if (fmt && *fmt) {
3c543ab3 139) strbuf_addstr(buf, fmt);
3c543ab3 140) return;
3c543ab3 155) static void fn_command_path_fl(const char *file, int line, const char *pathname)
3c543ab3 157) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 159) strbuf_addf(&buf_payload, "cmd_path %s", pathname);
3c543ab3 160) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 161) strbuf_release(&buf_payload);
3c543ab3 162) }
3c543ab3 177) static void fn_command_mode_fl(const char *file, int line, const char *mode)
3c543ab3 179) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 181) strbuf_addf(&buf_payload, "cmd_mode %s", mode);
3c543ab3 182) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 183) strbuf_release(&buf_payload);
3c543ab3 184) }
3c543ab3 186) static void fn_alias_fl(const char *file, int line, const char *alias,
3c543ab3 189) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 191) strbuf_addf(&buf_payload, "alias %s ->", alias);
3c543ab3 192) sq_quote_argv_pretty(&buf_payload, argv);
3c543ab3 193) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 194) strbuf_release(&buf_payload);
3c543ab3 195) }
3c543ab3 197) static void fn_child_start_fl(const char *file, int line,
3c543ab3 201) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 203) strbuf_addf(&buf_payload, "child_start[%d] ", cmd->trace2_child_id);
3c543ab3 205) if (cmd->dir) {
3c543ab3 206) strbuf_addstr(&buf_payload, " cd");
3c543ab3 207) sq_quote_buf_pretty(&buf_payload, cmd->dir);
3c543ab3 208) strbuf_addstr(&buf_payload, "; ");
3c543ab3 216) if (cmd->git_cmd)
3c543ab3 217) strbuf_addstr(&buf_payload, "git");
3c543ab3 218) sq_quote_argv_pretty(&buf_payload, cmd->argv);
3c543ab3 220) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 221) strbuf_release(&buf_payload);
3c543ab3 222) }
3c543ab3 224) static void fn_child_exit_fl(const char *file, int line,
3c543ab3 228) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 229) double elapsed = (double)us_elapsed_child / 1000000.0;
3c543ab3 231) strbuf_addf(&buf_payload, "child_exit[%d] pid:%d code:%d elapsed:%.6f",
3c543ab3 233) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 234) strbuf_release(&buf_payload);
3c543ab3 235) }
3c543ab3 237) static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute,
3c543ab3 240) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 242) strbuf_addf(&buf_payload, "exec[%d] ", exec_id);
3c543ab3 243) if (exe)
3c543ab3 244) strbuf_addstr(&buf_payload, exe);
3c543ab3 245) sq_quote_argv_pretty(&buf_payload, argv);
3c543ab3 246) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 247) strbuf_release(&buf_payload);
3c543ab3 248) }
3c543ab3 250) static void fn_exec_result_fl(const char *file, int line,
3c543ab3 254) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 256) strbuf_addf(&buf_payload, "exec_result[%d] code:%d", exec_id, code);
3c543ab3 257) if (code > 0)
3c543ab3 258) strbuf_addf(&buf_payload, " err:%s", strerror(code));
3c543ab3 259) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 260) strbuf_release(&buf_payload);
3c543ab3 261) }
3c543ab3 263) static void fn_param_fl(const char *file, int line, const char *param,
3c543ab3 266) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 268) strbuf_addf(&buf_payload, "def_param %s=%s", param, value);
3c543ab3 269) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 270) strbuf_release(&buf_payload);
3c543ab3 271) }
3c543ab3 273) static void fn_repo_fl(const char *file, int line,
3c543ab3 276) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 278) strbuf_addstr(&buf_payload, "worktree ");
3c543ab3 279) sq_quote_buf_pretty(&buf_payload, repo->worktree);
3c543ab3 280) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 281) strbuf_release(&buf_payload);
3c543ab3 282) }
3c543ab3 284) static void fn_printf_va_fl(const char *file, int line,
3c543ab3 288) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 290) maybe_append_string_va(&buf_payload, fmt, ap);
3c543ab3 291) normal_io_write_fl(file, line, &buf_payload);
3c543ab3 292) strbuf_release(&buf_payload);
3c543ab3 293) }

trace2/tr2_tgt_perf.c
3c543ab3 102) strbuf_addf(buf, "r%d ", repo->trace2_repo_id);
3c543ab3 125) strbuf_addbuf(buf, &dots);
3c543ab3 126) len_indent -= dots.len;
3c543ab3 187) static void fn_signal(uint64_t us_elapsed_absolute, int signo)
3c543ab3 189) const char *event_name = "signal";
3c543ab3 190) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 192) strbuf_addf(&buf_payload, "signo:%d", signo);
3c543ab3 194) perf_io_write_fl(__FILE__, __LINE__, event_name, NULL,
3c543ab3 196) strbuf_release(&buf_payload);
3c543ab3 197) }
3c543ab3 223) if (fmt && *fmt) {
3c543ab3 224) strbuf_addstr(buf, fmt);
3c543ab3 225) return;
3c543ab3 242) static void fn_command_path_fl(const char *file, int line, const char *pathname)
3c543ab3 244) const char *event_name = "cmd_path";
3c543ab3 245) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 247) strbuf_addstr(&buf_payload, pathname);
3c543ab3 249) perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
3c543ab3 251) strbuf_release(&buf_payload);
3c543ab3 252) }
3c543ab3 270) static void fn_command_mode_fl(const char *file, int line, const char *mode)
3c543ab3 272) const char *event_name = "cmd_mode";
3c543ab3 273) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 275) strbuf_addstr(&buf_payload, mode);
3c543ab3 277) perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
3c543ab3 279) strbuf_release(&buf_payload);
3c543ab3 280) }
3c543ab3 282) static void fn_alias_fl(const char *file, int line, const char *alias,
3c543ab3 285) const char *event_name = "alias";
3c543ab3 286) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 288) strbuf_addf(&buf_payload, "alias:%s argv:", alias);
3c543ab3 289) sq_quote_argv_pretty(&buf_payload, argv);
3c543ab3 291) perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
3c543ab3 293) strbuf_release(&buf_payload);
3c543ab3 294) }
3c543ab3 304) strbuf_addf(&buf_payload, "[ch%d] class:hook hook:%s",
3c543ab3 314) strbuf_addstr(&buf_payload, " cd:");
3c543ab3 315) sq_quote_buf_pretty(&buf_payload, cmd->dir);
3c543ab3 320) strbuf_addstr(&buf_payload, " git");
3c543ab3 342) static void fn_thread_start_fl(const char *file, int line,
3c543ab3 345) const char *event_name = "thread_start";
3c543ab3 346) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 348) perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
3c543ab3 350) strbuf_release(&buf_payload);
3c543ab3 351) }
3c543ab3 353) static void fn_thread_exit_fl(const char *file, int line,
3c543ab3 357) const char *event_name = "thread_exit";
3c543ab3 358) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 360) perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
3c543ab3 362) strbuf_release(&buf_payload);
3c543ab3 363) }
3c543ab3 365) static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute,
3c543ab3 368) const char *event_name = "exec";
3c543ab3 369) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 371) strbuf_addf(&buf_payload, "id:%d ", exec_id);
3c543ab3 372) strbuf_addstr(&buf_payload, "argv:");
3c543ab3 373) if (exe)
3c543ab3 374) strbuf_addf(&buf_payload, " %s", exe);
3c543ab3 375) sq_quote_argv_pretty(&buf_payload, argv);
3c543ab3 377) perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
3c543ab3 379) strbuf_release(&buf_payload);
3c543ab3 380) }
3c543ab3 382) static void fn_exec_result_fl(const char *file, int line,
3c543ab3 386) const char *event_name = "exec_result";
3c543ab3 387) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 389) strbuf_addf(&buf_payload, "id:%d code:%d", exec_id, code);
3c543ab3 390) if (code > 0)
3c543ab3 391) strbuf_addf(&buf_payload, " err:%s", strerror(code));
3c543ab3 393) perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
3c543ab3 395) strbuf_release(&buf_payload);
3c543ab3 396) }
3c543ab3 398) static void fn_param_fl(const char *file, int line, const char *param,
3c543ab3 401) const char *event_name = "def_param";
3c543ab3 402) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 404) strbuf_addf(&buf_payload, "%s:%s", param, value);
3c543ab3 406) perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
3c543ab3 408) strbuf_release(&buf_payload);
3c543ab3 409) }
3c543ab3 411) static void fn_repo_fl(const char *file, int line,
3c543ab3 414) const char *event_name = "def_repo";
3c543ab3 415) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 417) strbuf_addstr(&buf_payload, "worktree:");
3c543ab3 418) sq_quote_buf_pretty(&buf_payload, repo->worktree);
3c543ab3 420) perf_io_write_fl(file, line, event_name, repo, NULL, NULL, NULL,
3c543ab3 422) strbuf_release(&buf_payload);
3c543ab3 423) }
3c543ab3 425) static void fn_region_enter_printf_va_fl(const char *file, int line,
3c543ab3 432) const char *event_name = "region_enter";
3c543ab3 433) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 435) if (label)
3c543ab3 436) strbuf_addf(&buf_payload, "label:%s ", label);
3c543ab3 437) maybe_append_string_va(&buf_payload, fmt, ap);
3c543ab3 439) perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute,
3c543ab3 441) strbuf_release(&buf_payload);
3c543ab3 442) }
3c543ab3 444) static void fn_region_leave_printf_va_fl(
3c543ab3 449) const char *event_name = "region_leave";
3c543ab3 450) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 452) if (label)
3c543ab3 453) strbuf_addf(&buf_payload, "label:%s ", label);
3c543ab3 454) maybe_append_string_va(&buf_payload, fmt, ap);
3c543ab3 456) perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute,
3c543ab3 458) strbuf_release(&buf_payload);
3c543ab3 459) }
3c543ab3 461) static void fn_data_fl(const char *file, int line, uint64_t us_elapsed_absolute,
3c543ab3 466) const char *event_name = "data";
3c543ab3 467) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 469) strbuf_addf(&buf_payload, "%s:%s", key, value);
3c543ab3 471) perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute,
3c543ab3 473) strbuf_release(&buf_payload);
3c543ab3 474) }
3c543ab3 476) static void fn_data_json_fl(const char *file, int line,
3c543ab3 482) const char *event_name = "data_json";
3c543ab3 483) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 485) strbuf_addf(&buf_payload, "%s:%s", key, value->json.buf);
3c543ab3 487) perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute,
3c543ab3 489) strbuf_release(&buf_payload);
3c543ab3 490) }
3c543ab3 492) static void fn_printf_va_fl(const char *file, int line,
3c543ab3 496) const char *event_name = "printf";
3c543ab3 497) struct strbuf buf_payload = STRBUF_INIT;
3c543ab3 499) maybe_append_string_va(&buf_payload, fmt, ap);
3c543ab3 501) perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
3c543ab3 503) strbuf_release(&buf_payload);
3c543ab3 504) }

trace2/tr2_tls.c
3c543ab3 38) strbuf_addf(&ctx->thread_name, "th%02d:", ctx->thread_id);
3c543ab3 41) strbuf_setlen(&ctx->thread_name, TR2_MAX_THREAD_NAME);
3c543ab3 58) ctx = tr2tls_create_self("unknown");
3c543ab3 63) int tr2tls_is_main_thread(void)
3c543ab3 65) struct tr2tls_thread_ctx *ctx = pthread_getspecific(tr2tls_key);
3c543ab3 67) return ctx == tr2tls_thread_main;
3c543ab3 82) void tr2tls_push_self(uint64_t us_now)
3c543ab3 84) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
3c543ab3 86) ALLOC_GROW(ctx->array_us_start, ctx->nr_open_regions + 1, ctx->alloc);
3c543ab3 87) ctx->array_us_start[ctx->nr_open_regions++] = us_now;
3c543ab3 88) }
3c543ab3 90) void tr2tls_pop_self(void)
3c543ab3 92) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
3c543ab3 94) if (!ctx->nr_open_regions)
3c543ab3 95) BUG("no open regions in thread '%s'", ctx->thread_name.buf);
3c543ab3 97) ctx->nr_open_regions--;
3c543ab3 98) }
3c543ab3 105) tr2tls_pop_self();
3c543ab3 115) return 0;
3c543ab3 125) return 0;

wrapper.c
5efde212 70) die("Out of memory, malloc failed (tried to allocate %" PRIuMAX " bytes)",
5efde212 73) error("Out of memory, malloc failed (tried to allocate %" PRIuMAX " bytes)",

Commits introducting uncovered code:
Dan McGregor	ba81921a http: cast result to FILE *
Derrick Stolee	8e7e6c05 commit-graph: return with errors during write
Derrick Stolee	b1beb050 commit-graph: create new version flags
Jeff Hostetler	34fed676 trace2:data: add subverb for rebase
Jeff Hostetler	3c543ab3 trace2: create new combined trace facility
Jeff Hostetler	3507f837 trace2:data: add editor/pager child classification
Jeff Hostetler	7bc0969b trace2: t/helper/test-trace2, t0210.sh, t0211.sh, t0212.sh
Josh Steadmon	6da1f1a9 protocol: advertise multiple supported versions
Martin Koegler	5efde212 zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy	a12c1ff3 config: factor out set_config_source_file()
Nguyễn Thái Ngọc Duy	6f11fd5e config: add --move-to
Nguyễn Thái Ngọc Duy	8f7c7f55 config.c: add repo_config_set_worktree_gently()
Nickolai Belakovski	358c9418 ref-filter: add worktreepath atom


Uncovered code in 'jch' not in 'next'
--------------------------------------------------------

blame.c
07d04b91 483)     ent->s_lno + ent->num_lines == next->s_lno &&
07d04b91 484)     ent->ignored == next->ignored) {
e7973c85 941) blame_origin_decref(e->suspect);
e7973c85 942) e->suspect = blame_origin_incref(parent);
e7973c85 943) e->s_lno += offset;
07d04b91 944) e->ignored = 1;
e7973c85 945) e->next = ignoredp;
e7973c85 946) ignoredp = e;
e7973c85 954) **dstq = reverse_blame(ignoredp, **dstq);
e7973c85 955) *dstq = &ignoredp->next;
e7973c85 1528) for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
e7973c85 1529)      i < num_sg && sg;
e7973c85 1530)      sg = sg->next, i++) {
e7973c85 1531) struct blame_origin *porigin = sg_origin[i];
e7973c85 1533) if (!porigin)
e7973c85 1534) continue;
e7973c85 1535) pass_blame_to_parent(sb, origin, porigin, 1);
e7973c85 1536) if (!origin->suspects)
e7973c85 1537) goto finish;

builtin/blame.c
07d04b91 485) length--;
07d04b91 486) putchar('*');
e7973c85 705) return git_config_pathname(&ignore_revs_file, var, value);
07d04b91 707) mark_ignored_lines = git_config_bool(var, value);
07d04b91 708) return 0;
e7973c85 797) oidset_parse_file(&sb->ignore_list, ignore_revs_file);
e7973c85 799) if (get_oid_committish(i->string, &oid))
e7973c85 800) die(_("Can't find revision '%s' to ignore"), i->string);
e7973c85 801) oidset_insert(&sb->ignore_list, &oid);

builtin/branch.c
0ecb1fc7 452) die(_("could not resolve HEAD"));
0ecb1fc7 458) die(_("HEAD (%s) points outside of refs/heads/"), refname);

builtin/multi-pack-index.c
467ae6f9 49) die(_("--batch-size option is only for 'repack' subcommand"));
467ae6f9 58) die(_("unrecognized subcommand: %s"), argv[0]);

builtin/pull.c
a3b994b7 648) argv_array_push(&args, opt_cleanup);

builtin/rebase--interactive.c
c0108d5c 24) return error_errno(_("could not read '%s'."), todo_file);
c0108d5c 31) return error_errno(_("could not write '%s'"), todo_file);
30faf278 46) return error_errno(_("could not read '%s'."), todo_file);
30faf278 50) todo_list_release(&todo_list);
30faf278 51) return error(_("unusable todo list: '%s'"), todo_file);
30faf278 59) return error_errno(_("could not write '%s'."), todo_file);
1f4d9b1b 157) BUG("unusable todo list");
acabb2aa 313) ret = rearrange_squash_in_todo_file(the_repository);
6d3f180e 316) ret = sequencer_add_exec_commands(the_repository, &commands);

builtin/remote.c
f39a9c65 1551) die(_("--save-to-push cannot be used with other options"));
f39a9c65 1575) die(_("--save-to-push can only be used when only one url is defined"));

builtin/stash.c
f6bbd781 128) die(_("'%s' is not a stash-like commit"), revision);
f6bbd781 161) free_stash_info(info);
f6bbd781 162) fprintf_ln(stderr, _("No stash entries found."));
f6bbd781 163) return -1;
f6bbd781 198) free_stash_info(info);
cdca49bc 225) return error(_("git stash clear with parameters is "
f6bbd781 241) return -1;
f6bbd781 249) return -1;
f6bbd781 265) return error(_("unable to write new index file"));
f6bbd781 377) remove_path(stash_index_path.buf);
f6bbd781 378) return -1;
f6bbd781 405) return -1;
f6bbd781 408) return error(_("cannot apply a stash in the middle of a merge"));
f6bbd781 418) strbuf_release(&out);
f6bbd781 419) return error(_("could not generate diff %s^!."),
f6bbd781 426) return error(_("conflicts in index."
f6bbd781 432) return error(_("could not save index tree"));
f6bbd781 439) return error(_("could not restore untracked files from stash"));
f6bbd781 470) return -1;
f6bbd781 475) strbuf_release(&out);
f6bbd781 480) strbuf_release(&out);
f6bbd781 481) return -1;
cdca49bc 557) return error(_("%s: Could not drop stash entry"),
e1d01876 632) printf_ln(_("The stash entry is kept in case "
b4493f26 766) free_stash_info(&info);
51809c70 767) usage_with_options(git_stash_show_usage, options);
847eb0b0 783) stash_msg = "Created via \"git stash store\".";
847eb0b0 789) if (!quiet) {
847eb0b0 790) fprintf_ln(stderr, _("Cannot update %s with %s"),
847eb0b0 793) return -1;
847eb0b0 817) if (!quiet)
847eb0b0 818) fprintf_ln(stderr, _("\"git stash store\" requires one "
847eb0b0 820) return -1;
1f5a011d 903) return -1;
1f5a011d 963) ret = -1;
1f5a011d 964) goto done;
1f5a011d 969) ret = -1;
1f5a011d 970) goto done;
1f5a011d 975) ret = -1;
1f5a011d 976) goto done;
1f5a011d 1002) ret = -1;
1f5a011d 1003) goto done;
1f5a011d 1014) ret = -1;
1f5a011d 1015) goto done;
1f5a011d 1021) ret = -1;
1f5a011d 1022) goto done;
1f5a011d 1029) ret = -1;
1f5a011d 1030) goto done;
1f5a011d 1068) ret = -1;
1f5a011d 1069) goto done;
1f5a011d 1075) ret = -1;
1f5a011d 1076) goto done;
1f5a011d 1087) ret = -1;
1f5a011d 1088) goto done;
1f5a011d 1093) ret = -1;
1f5a011d 1094) goto done;
9a95010a 1130) fprintf_ln(stderr, _("You do not have "
1f5a011d 1139) ret = 1;
1f5a011d 1140) goto done;
9a95010a 1156) if (!quiet)
9a95010a 1157) fprintf_ln(stderr, _("Cannot save the current "
1f5a011d 1159) ret = -1;
1f5a011d 1160) goto done;
9a95010a 1165) if (!quiet)
9a95010a 1166) fprintf_ln(stderr, _("Cannot save "
1f5a011d 1168) ret = -1;
1f5a011d 1169) goto done;
9a95010a 1176) if (!quiet)
9a95010a 1177) fprintf_ln(stderr, _("Cannot save the current "
1f5a011d 1179) goto done;
9a95010a 1213) if (!quiet)
9a95010a 1214) fprintf_ln(stderr, _("Cannot record "
1f5a011d 1216) ret = -1;
1f5a011d 1217) goto done;
fa38428f 1286) ret = -1;
fa38428f 1287) goto done;
fa38428f 1297) ret = -1;
9a95010a 1298) if (!quiet)
9a95010a 1299) fprintf_ln(stderr, _("Cannot initialize stash"));
fa38428f 1300) goto done;
fa38428f 1312) ret = -1;
9a95010a 1313) if (!quiet)
9a95010a 1314) fprintf_ln(stderr, _("Cannot save the current status"));
fa38428f 1315) goto done;
fa38428f 1332) ret = -1;
fa38428f 1351) ret = -1;
fa38428f 1352) goto done;
fa38428f 1361) ret = -1;
fa38428f 1362) goto done;
fa38428f 1370) ret = -1;
fa38428f 1379) ret = -1;
fa38428f 1390) ret = -1;
fa38428f 1391) goto done;
fa38428f 1400) ret = -1;
fa38428f 1401) goto done;
fa38428f 1409) ret = -1;
fa38428f 1435) ret = -1;
bec65d5b 1527) return env;
26799a20 1555) const char *path = mkpath("%s/git-legacy-stash",
26799a20 1558) if (sane_execvp(path, (char **)argv) < 0)
26799a20 1559) die_errno(_("could not exec %s"), path);
26799a20 1561) BUG("sane_execvp() returned???");
51809c70 1602) usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
51809c70 1630) continue;

combine-diff.c
26c64cee 89)     filename_changed(p->parent[j].status))
26c64cee 90) strbuf_release(&p->parent[j].path);
26c64cee 992) dump_quoted_path("--- ", "", "/dev/null",
26c64cee 1000) dump_quoted_path("--- ", "", "/dev/null",
26c64cee 1273) write_name_quoted(p->path, stdout,

ident.c
39ab4d09 452) break;
39ab4d09 454) name = getenv("GIT_AUTHOR_NAME");
39ab4d09 455) email = getenv("GIT_AUTHOR_EMAIL");
39ab4d09 456) break;
39ab4d09 515) return config_error_nonbool(var);
39ab4d09 525) return config_error_nonbool(var);
39ab4d09 535) return config_error_nonbool(var);
39ab4d09 545) return config_error_nonbool(var);

midx.c
5bf52fbc 428) close_pack(packs->info[packs->nr].p);
5bf52fbc 429) FREE_AND_NULL(packs->info[packs->nr].p);
3c9e7185 688) BUG("object %s is in an expired pack with int-id %d",
3c9e7185 815) error(_("did not see pack-file %s to drop"),
3c9e7185 817) drop_index++;
3c9e7185 818) missing_drops++;
3c9e7185 819) i--;
3c9e7185 826) result = 1;
3c9e7185 827) goto cleanup;
3c9e7185 1079) return 0;
3c9e7185 1094) continue;
467ae6f9 1133) return 0;
19c239d4 1148) return 0;
19c239d4 1157) continue;
19c239d4 1170) continue;
19c239d4 1193) error(_("could not start pack-objects"));
19c239d4 1194) result = 1;
19c239d4 1195) goto cleanup;
19c239d4 1212) error(_("could not finish pack-objects"));
19c239d4 1213) result = 1;
19c239d4 1214) goto cleanup;

oidset.c
ef644c41 69) die_errno("Could not read '%s'", path);

packfile.c
91336887 369) strbuf_release(&buf);
91336887 370) return;

pretty.c
4f732e0f 1075) return 0;
4f732e0f 1112) return 0;

read-cache.c
ee70c128 1734) if (advice_unknown_index_extension) {
ee70c128 1735) warning(_("ignoring optional %.4s index extension"), ext);
ee70c128 1736) advise(_("This is likely due to the file having been written by a newer\n"

rebase-interactive.c
6ca89c6f 26) warning(_("unrecognized setting %s for option "
c0108d5c 102) return error(_("could not copy '%s' to '%s'."), todo_file,
6ca89c6f 164) goto leave_check;

remote-curl.c
34a9469d 360) die("invalid server response; expected service, got flush packet");

revision.c
26c64cee 2654) die("--combined-all-names makes no sense without -c or --cc");

sequencer.c
6d3f180e 4606) int sequencer_add_exec_commands(struct repository *r,
6d3f180e 4614) return error_errno(_("could not read '%s'."), todo_file);
6d3f180e 4616) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, &todo_list)) {
6d3f180e 4621) todo_list_add_exec_commands(&todo_list, commands);
6d3f180e 4622) res = todo_list_write_to_file(r, &todo_list, todo_file, NULL, NULL, -1, 0);
0cce4a27 4623) todo_list_release(&todo_list);
6d3f180e 4625) if (res)
6d3f180e 4626) return error_errno(_("could not write '%s'."), todo_file);
6d3f180e 4627) return 0;
616d7740 4661) strbuf_addstr(buf, " -c");
87805600 4708) res = -1;
6ca89c6f 4709) goto out;
6ca89c6f 4714) goto out;
6ca89c6f 4723) fprintf(stderr, _(edit_todo_list_advice));
ce193960 4841) todo_list_release(&new_todo);
1f4d9b1b 4847) todo_list_release(&new_todo);
1f4d9b1b 4848) return error_errno(_("could not write '%s'"), todo_file);
acabb2aa 5025) int rearrange_squash_in_todo_file(struct repository *r)
acabb2aa 5027) const char *todo_file = rebase_path_todo();
acabb2aa 5028) struct todo_list todo_list = TODO_LIST_INIT;
acabb2aa 5029) int res = 0;
acabb2aa 5031) if (strbuf_read_file_or_whine(&todo_list.buf, todo_file) < 0)
acabb2aa 5032) return -1;
acabb2aa 5033) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, &todo_list) < 0) {
acabb2aa 5034) todo_list_release(&todo_list);
acabb2aa 5035) return -1;
acabb2aa 5038) res = todo_list_rearrange_squash(&todo_list);
acabb2aa 5039) if (!res)
acabb2aa 5040) res = todo_list_write_to_file(r, &todo_list, todo_file, NULL, NULL, -1, 0);
acabb2aa 5042) todo_list_release(&todo_list);
acabb2aa 5044) if (res)
acabb2aa 5045) return error_errno(_("could not write '%s'."), todo_file);
acabb2aa 5046) return 0;

strbuf.c
bfc3fe33 259) die("`pos' is too far after the end of the buffer");
bfc3fe33 264) BUG("your vsnprintf is broken (returned %d)", len);
bfc3fe33 266) return; /* nothing to do */
bfc3fe33 268) die("you want to use way too much memory");
bfc3fe33 276) BUG("your vsnprintf is broken (returns inconsistent lengths)");
fd2015b3 448) return 0;

worktree.c
e0c4a731 465) clear_repository_format(&format);

Commits introducting uncovered code:
Alban Gruin	ce193960 sequencer: refactor skip_unnecessary_picks() to work on a todo_list
Alban Gruin	6ca89c6f sequencer: refactor check_todo_list() to work on a todo_list
Alban Gruin	616d7740 sequencer: introduce todo_list_write_to_file()
Alban Gruin	6d3f180e sequencer: refactor sequencer_add_exec_commands() to work on a todo_list
Alban Gruin	c0108d5c rebase-interactive: rewrite edit_todo_list() to handle the initial edit
Alban Gruin	30faf278 rebase--interactive: move transform_todo_file() to rebase--interactive.c
Alban Gruin	1f4d9b1b sequencer: change complete_action() to use the refactored functions
Alban Gruin	acabb2aa sequencer: refactor rearrange_squash() to work on a todo_list
Anders Waldenborg	fd2015b3 strbuf: separate callback for strbuf_expand:ing literals
Anders Waldenborg	4f732e0f pretty: allow %(trailers) options with explicit value
Barret Rhoden	e7973c85 blame: add the ability to ignore commits and their changes
Barret Rhoden	ef644c41 Move init_skiplist() outside of fsck
Barret Rhoden	07d04b91 blame: add a config option to mark ignored lines
Daniels Umanovskis	0ecb1fc7 branch: introduce --show-current display option
Denton Liu	f39a9c65 remote: add --save-to-push option to git remote set-url
Denton Liu	a3b994b7 merge: cleanup messages like commit
Derrick Stolee	91336887 repack: refactor pack deletion for future use
Derrick Stolee	467ae6f9 multi-pack-index: prepare 'repack' subcommand
Derrick Stolee	19c239d4 midx: implement midx_repack()
Derrick Stolee	3c9e7185 multi-pack-index: implement 'expire' subcommand
Derrick Stolee	5bf52fbc midx: refactor permutation logic and pack sorting
Elijah Newren	26c64cee log,diff-tree: add --combined-all-names option
Jeff King	34a9469d remote-curl: refactor smart-http discovery
Joel Teichroeb	f6bbd781 stash: convert apply to builtin
Joel Teichroeb	e1d01876 stash: convert pop to builtin
Joel Teichroeb	cdca49bc stash: convert drop and clear to builtin
Johannes Schindelin	bec65d5b tests: add a special setup where stash.useBuiltin is off
Johannes Schindelin	26799a20 stash: optionally use the scripted version again
Jonathan Nieder	ee70c128 index: offer advice for unknown index extensions
Liam Beguin	0cce4a27 rebase -i -x: add exec commands via the rebase--helper
Martin Ågren	e0c4a731 setup: fix memory leaks with `struct repository_format`
Paul-Sebastian Ungureanu	9a95010a stash: make push -q quiet
Paul-Sebastian Ungureanu	1f5a011d stash: convert create to builtin
Paul-Sebastian Ungureanu	847eb0b0 stash: convert store to builtin
Paul-Sebastian Ungureanu	51809c70 stash: convert `stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu	b4493f26 stash: convert show to builtin
Paul-Sebastian Ungureanu	bfc3fe33 strbuf.c: add `strbuf_insertf()` and `strbuf_vinsertf()`
Paul-Sebastian Ungureanu	fa38428f stash: convert push to builtin
René Scharfe	87805600 sequencer: factor out strbuf_read_file_or_whine()
William Hubbs	39ab4d09 config: allow giving separate author and committer idents


Uncovered code in 'next' not in 'master'
--------------------------------------------------------

bisect.c
4f6d26b1 661) mark_edges_uninteresting(revs, NULL, 0);

builtin/bisect--helper.c
5e82c3dd 162) if (get_oid_commit(commit, &oid))
5e82c3dd 163) return error(_("'%s' is not a valid commit"), commit);
5e82c3dd 164) strbuf_addstr(&branch, commit);
5e82c3dd 172) strbuf_release(&branch);
5e82c3dd 173) argv_array_clear(&argv);
5e82c3dd 174) return error(_("could not check out original"
0f30233a 215) retval = error(_("Bad bisect_write argument: %s"), state);
0f30233a 216) goto finish;
0f30233a 220) retval = error(_("couldn't get the oid of the rev '%s'"), rev);
0f30233a 221) goto finish;
0f30233a 226) retval = -1;
0f30233a 227) goto finish;
0f30233a 232) retval = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
0f30233a 233) goto finish;
129a6cf3 329) yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
129a6cf3 330) if (starts_with(yesno, "N") || starts_with(yesno, "n"))
129a6cf3 331) retval = -1;
129a6cf3 332) goto finish;
129a6cf3 338) retval = error(_(need_bisect_start_warning),
450ebb73 389) return error(_("invalid argument %s for 'git bisect terms'.\n"
06f5608c 404) return -1;
06f5608c 407) retval = -1;
06f5608c 408) goto finish;
06f5608c 413) retval = -1;
06f5608c 452) no_checkout = 1;
06f5608c 474)  !one_of(arg, "--term-good", "--term-bad", NULL)) {
06f5608c 475) return error(_("unrecognized option: '%s'"), arg);
06f5608c 510) if (get_oid("HEAD", &head_oid))
06f5608c 511) return error(_("bad HEAD - I need a HEAD"));
06f5608c 526) retval = error(_("checking out '%s' failed."
06f5608c 547) return error(_("won't bisect on cg-seek'ed tree"));
06f5608c 550) return error(_("bad HEAD - strange symbolic ref"));
06f5608c 558) return -1;
06f5608c 576) retval = -1;
06f5608c 577) goto finish;
06f5608c 588) retval = -1;
06f5608c 589) goto finish;
06f5608c 600) retval = -1;
5e82c3dd 677) return error(_("--bisect-reset requires either no argument or a commit"));
0f30233a 681) return error(_("--bisect-write requires either 4 or 5 arguments"));
4fbdbd5b 687) return error(_("--check-and-set-terms requires 3 arguments"));
129a6cf3 693) return error(_("--bisect-next-check requires 2 or 3 arguments"));

builtin/blame.c
acdd3776 930) blame_date_width = sizeof("Thu Oct 19 16:00");
acdd3776 931) break;

builtin/checkout.c
091e04bc 303) return;
091e04bc 1271) die(_("'%s' cannot be used with switching branches"),

builtin/diff-tree.c
e1ff0a32 169) repo_read_index(the_repository);

builtin/pack-objects.c
33de80b1 2225) const uint32_t tail = (idx + window - count) % window;

builtin/pack-redundant.c
33de80b1 169) const int cmp = oidcmp(l->oid, oid);
33de80b1 267) const int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);

builtin/rebase.c
21853626 259) write_file(state_dir_path("verbose", opts), "%s", "");
21853626 261) write_file(state_dir_path("strategy", opts), "%s",
21853626 264) write_file(state_dir_path("strategy_opts", opts), "%s",
21853626 271) write_file(state_dir_path("gpg_sign_opt", opts), "%s",
21853626 274) write_file(state_dir_path("strategy", opts), "--signoff");
c5233708 394) BUG("Not a fully qualified branch: '%s'", switch_to_branch);
c5233708 397) ret = -1;
c5233708 398) goto leave_reset_head;
c5233708 402) ret = error(_("could not determine HEAD revision"));
c5233708 403) goto leave_reset_head;
c5233708 424) ret = error(_("could not read index"));
c5233708 425) goto leave_reset_head;
c5233708 429) ret = error(_("failed to find tree of %s"),
c5233708 431) goto leave_reset_head;
c5233708 435) ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
c5233708 436) goto leave_reset_head;
c5233708 448) ret = error(_("could not write index"));
c5233708 449) goto leave_reset_head;
c5233708 467) } else if (old_orig)
c5233708 468) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
21853626 507) BUG("move_to_original_branch without onto");
21853626 543) argv_array_push(&am.args, opts->gpg_sign_opt);
21853626 575) status = error_errno(_("could not open '%s' for writing"),
21853626 577) free(rebased_patches);
21853626 578) argv_array_clear(&am.args);
21853626 579) return status;
21853626 588) argv_array_split(&format_patch.args,
21853626 589)  opts->git_format_patch_opt.buf);
21853626 597) unlink(rebased_patches);
21853626 598) free(rebased_patches);
21853626 599) argv_array_clear(&am.args);
21853626 601) reset_head(&opts->orig_head, "checkout", opts->head_name, 0,
21853626 603) error(_("\ngit encountered an error while preparing the "
21853626 610) strbuf_release(&revisions);
21853626 611) return status;
21853626 617) status = error_errno(_("could not open '%s' for reading"),
21853626 619) free(rebased_patches);
21853626 620) argv_array_clear(&am.args);
21853626 621) return status;

date.c
acdd3776 113) die("Timestamp too large for this system: %"PRItime, time);
acdd3776 236) hide.date = 1;
acdd3776 917) return DATE_HUMAN;
2fd7c229 934) if (isatty(1) || pager_in_use())
2fd7c229 935) format = p;
2fd7c229 937) format = "default";

diff.c
d473e2e0 4946) return error(_("%s expects a numerical value"), "--unified");

entry.c
536ec183 450) BUG("Can't remove entry to a path");

http-walker.c
514c5fdd 550) loose_object_path(the_repository, &buf, &req->oid);

list-objects.c
4f6d26b1 241) continue;
4f6d26b1 250) parent->object.flags |= SHOWN;
4f6d26b1 251) show_edge(parent);
4f6d26b1 272) tree->object.flags |= UNINTERESTING;
4f6d26b1 287) commit->object.flags |= SHOWN;
4f6d26b1 288) show_edge(commit);

merge-recursive.c
0d6caa2d 433) for (i = 0; i < istate->cache_nr; i++) {
0d6caa2d 434) const struct cache_entry *ce = istate->cache[i];
0d6caa2d 443) istate->cache_tree = cache_tree();
0d6caa2d 733) ce = index_file_exists(o->repo->index, path, strlen(path),
0d6caa2d 3193) remove_file_from_index(o->repo->index, path);

object.c
01f8d594 278) error(_("hash mismatch %s"), oid_to_hex(repl));

parse-options.c
f62470c6 116) BUG("BITOP can't have unset form");
3ebbe289 183) return (*opt->ll_callback)(p, opt, p_arg, p_unset);
3ebbe289 255) rc = (*numopt->ll_callback)(p, numopt, arg, 0);
3ebbe289 432) BUG("OPTION_CALLBACK needs one callback");
3ebbe289 434) BUG("OPTION_CALLBACK can't have two callbacks");
bf3ff338 438) BUG("OPTION_LOWLEVEL_CALLBACK needs a callback");
bf3ff338 440) BUG("OPTION_LOWLEVEL_CALLBACK needs no high level callback");
202fbb33 475) BUG("Can't keep argv0 if you don't have it");
f41179f1 622) BUG("parse_short_opt() cannot return these");
f41179f1 647) BUG("parse_short_opt() cannot return these");
f41179f1 676) BUG("parse_long_opt() cannot return these");

repository.c
3a95f31d 272) BUG("the repo hasn't been setup");

revision.c
d5d2e935 169) return;
d5d2e935 172) return;
d5d2e935 195) break;
f1f5de44 218) continue;

sequencer.c
899b49c4 2395) opts->quiet = 1;
e1ff0a32 3991) res = error_dirty_index(r, opts);

sha1-file.c
514c5fdd 1291) status = error(_("unable to parse %s header"), oid_to_hex(oid));
2c319886 1595) return error_errno(_("unable to write file %s"), filename);
76011357 1626) fsync_or_die(fd, "loose object file");
76011357 1628) die_errno(_("error when closing loose object file"));
76011357 1719) die(_("unable to write loose object file"));
2c319886 1818) return error(_("cannot read object for %s"), oid_to_hex(oid));
00a7760e 2297) the_hash_algo->final_fn(real_oid.hash, &c);
00a7760e 2298) if (!oideq(expected_oid, &real_oid)) {
01f8d594 2299) error(_("hash mismatch for %s (expected %s)"), path,

sha1-name.c
d1dd94b3 926) return MISSING_OBJECT;

t/helper/test-date.c
4419de91 95) static void getnanos(const char **argv, struct timeval *now)
4419de91 97) double seconds = getnanotime() / 1.0e9;
4419de91 99) if (*argv)
4419de91 100) seconds -= strtod(*argv, NULL);
4419de91 101) printf("%lf\n", seconds);
4419de91 102) }
4419de91 133) getnanos(argv+1, &now);

t/helper/test-path-utils.c
b819f1d2 180) static int cmp_by_st_size(const void *a, const void *b)
b819f1d2 182) intptr_t x = (intptr_t)((struct string_list_item *)a)->util;
b819f1d2 183) intptr_t y = (intptr_t)((struct string_list_item *)b)->util;
b819f1d2 185) return x > y ? -1 : (x < y ? +1 : 0);
5868bd86 308) res = error_errno("Cannot stat '%s'", argv[i]);
af9912ef 314) if (argc == 4 && !strcmp(argv[1], "skip-n-bytes")) {
af9912ef 315) int fd = open(argv[2], O_RDONLY), offset = atoi(argv[3]);
af9912ef 318) if (fd < 0)
af9912ef 319) die_errno("could not open '%s'", argv[2]);
af9912ef 320) if (lseek(fd, offset, SEEK_SET) < 0)
af9912ef 321) die_errno("could not skip %d bytes", offset);
af9912ef 323) ssize_t count = read(fd, buffer, sizeof(buffer));
af9912ef 324) if (count < 0)
af9912ef 325) die_errno("could not read '%s'", argv[2]);
af9912ef 326) if (!count)
af9912ef 327) break;
af9912ef 328) if (write(1, buffer, count) < 0)
af9912ef 329) die_errno("could not write to stdout");
af9912ef 330) }
af9912ef 331) close(fd);
af9912ef 332) return 0;
b819f1d2 335) if (argc > 5 && !strcmp(argv[1], "slice-tests")) {
b819f1d2 336) int res = 0;
b819f1d2 338) struct string_list list = STRING_LIST_INIT_NODUP;
b819f1d2 341) offset = strtol(argv[2], NULL, 10);
b819f1d2 342) stride = strtol(argv[3], NULL, 10);
b819f1d2 343) if (stride < 1)
b819f1d2 344) stride = 1;
b819f1d2 345) for (i = 4; i < argc; i++)
b819f1d2 346) if (stat(argv[i], &st))
b819f1d2 347) res = error_errno("Cannot stat '%s'", argv[i]);
b819f1d2 349) string_list_append(&list, argv[i])->util =
b819f1d2 350) (void *)(intptr_t)st.st_size;
b819f1d2 351) QSORT(list.items, list.nr, cmp_by_st_size);
b819f1d2 352) for (i = offset; i < list.nr; i+= stride)
b819f1d2 353) printf("%s\n", list.items[i].string);
b819f1d2 355) return !!res;

t/helper/test-xml-encode.c
22231908 9) int cmd__xml_encode(int argc, const char **argv)
22231908 11) unsigned char buf[1024], tmp[4], *tmp2 = NULL;
22231908 12) ssize_t cur = 0, len = 1, remaining = 0;
22231908 16) if (++cur == len) {
22231908 17) len = xread(0, buf, sizeof(buf));
22231908 18) if (!len)
22231908 19) return 0;
22231908 20) if (len < 0)
22231908 21) die_errno("Could not read <stdin>");
22231908 22) cur = 0;
22231908 24) ch = buf[cur];
22231908 26) if (tmp2) {
22231908 27) if ((ch & 0xc0) != 0x80) {
22231908 28) fputs(utf8_replace_character, stdout);
22231908 29) tmp2 = NULL;
22231908 30) cur--;
22231908 31) continue;
22231908 33) *tmp2 = ch;
22231908 34) tmp2++;
22231908 35) if (--remaining == 0) {
22231908 36) fwrite(tmp, tmp2 - tmp, 1, stdout);
22231908 37) tmp2 = NULL;
22231908 39) continue;
22231908 42) if (!(ch & 0x80)) {
22231908 44) if (ch == '&')
22231908 45) fputs("&amp;", stdout);
22231908 46) else if (ch == '\'')
22231908 47) fputs("&apos;", stdout);
22231908 48) else if (ch == '"')
22231908 49) fputs("&quot;", stdout);
22231908 50) else if (ch == '<')
22231908 51) fputs("&lt;", stdout);
22231908 52) else if (ch == '>')
22231908 53) fputs("&gt;", stdout);
22231908 54) else if (ch >= 0x20)
22231908 55) fputc(ch, stdout);
22231908 56) else if (ch == 0x09 || ch == 0x0a || ch == 0x0d)
22231908 57) fprintf(stdout, "&#x%02x;", ch);
22231908 59) fputs(utf8_replace_character, stdout);
22231908 60) } else if ((ch & 0xe0) == 0xc0) {
22231908 62) tmp[0] = ch;
22231908 63) remaining = 1;
22231908 64) tmp2 = tmp + 1;
22231908 65) } else if ((ch & 0xf0) == 0xe0) {
22231908 67) tmp[0] = ch;
22231908 68) remaining = 2;
22231908 69) tmp2 = tmp + 1;
22231908 70) } else if ((ch & 0xf8) == 0xf0) {
22231908 72) tmp[0] = ch;
22231908 73) remaining = 3;
22231908 74) tmp2 = tmp + 1;
22231908 76) fputs(utf8_replace_character, stdout);
22231908 77) }

utf8.c
aab2a1ae 568) bom_str = utf16_be_bom;
aab2a1ae 569) bom_len = sizeof(utf16_be_bom);
aab2a1ae 570) out_encoding = "UTF-16BE";

wrapper.c
e3b1e3bd 701) die_errno(_("could not stat %s"), filename);

Commits introducting uncovered code:
David Turner	d1dd94b3 Do not print 'dangling' for cat-file in case of ambiguity
Derrick Stolee	4f6d26b1 list-objects: consume sparse tree walk
Derrick Stolee	d5d2e935 revision: implement sparse algorithm
Derrick Stolee	f1f5de44 revision: add mark_tree_uninteresting_sparse
Elijah Newren	899b49c4 git-rebase, sequencer: extend --quiet option for the interactive machinery
Jeff King	01f8d594 prefer "hash mismatch" to "sha1 mismatch"
Jeff King	514c5fdd sha1-file: modernize loose object file functions
Jeff King	76011357 sha1-file: prefer "loose object file" to "sha1 file" in messages
Jeff King	2c319886 sha1-file: avoid "sha1 file" for generic use in messages
Jeff King	00a7760e sha1-file: modernize loose header/stream functions
Johannes Schindelin	21853626 built-in rebase: call `git am` directly
Johannes Schindelin	c5233708 rebase: move `reset_head()` into a better spot
Johannes Schindelin	4419de91 test-date: add a subcommand to measure times in shell scripts
Johannes Schindelin	b819f1d2 ci: parallelize testing on Windows
Johannes Schindelin	5868bd86 tests: avoid calling Perl just to determine file sizes
Johannes Schindelin	af9912ef tests: include detailed trace logs with --write-junit-xml upon failure
Johannes Schindelin	22231908 tests: optionally write results as JUnit-style .xml
Linus Torvalds	acdd3776 Add 'human' date format
Nguyễn Thái Ngọc Duy	f41179f1 parse-options: avoid magic return codes
Nguyễn Thái Ngọc Duy	3a95f31d repository.c: replace hold_locked_index() with repo_hold_locked_index()
Nguyễn Thái Ngọc Duy	202fbb33 parse-options: add one-shot mode
Nguyễn Thái Ngọc Duy	f62470c6 parse-options: add OPT_BITOP()
Nguyễn Thái Ngọc Duy	3ebbe289 parse-options: allow ll_callback with OPTION_CALLBACK
Nguyễn Thái Ngọc Duy	0d6caa2d merge-recursive.c: remove implicit dependency on the_index
Nguyễn Thái Ngọc Duy	d473e2e0 diff.c: convert -U|--unified
Nguyễn Thái Ngọc Duy	e1ff0a32 read-cache.c: kill read_index()
Nguyễn Thái Ngọc Duy	bf3ff338 parse-options: stop abusing 'callback' for lowlevel callbacks
Pranit Bauva	5e82c3dd bisect--helper: `bisect_reset` shell function in C
Pranit Bauva	0f30233a bisect--helper: `bisect_write` shell function in C
Pranit Bauva	129a6cf3 bisect--helper: `bisect_next_check` shell function in C
Pranit Bauva	450ebb73 bisect--helper: `get_terms` & `bisect_terms` shell function in C
Pranit Bauva	06f5608c bisect--helper: `bisect_start` shell function partially in C
Pranit Bauva	e3b1e3bd wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()
Pranit Bauva	4fbdbd5b bisect--helper: `check_and_set_terms` shell function in C
Shahzad Lone	33de80b1 various: tighten constness of some local variables
Stephen P. Smith	2fd7c229 Replace the proposed 'auto' mode with 'auto:'
Thomas Gummerer	536ec183 entry: support CE_WT_REMOVE flag in checkout_entry
Thomas Gummerer	091e04bc checkout: introduce --{,no-}overlay option
Torsten Bögershausen	aab2a1ae Support working-tree-encoding "UTF-16LE-BOM"


Uncovered code in 'master' not in 'master@{1}'
--------------------------------------------------------

builtin/archive.c
01f9ec64 63) if (starts_with(reader.line, "NACK "))
01f9ec64 64) die(_("git archive: NACK %s"), reader.line + 5);

builtin/fetch-pack.c
4316ff30 227) get_remote_refs(fd[1], &reader, &ref, 0, NULL, NULL);
4316ff30 228) break;

builtin/fetch.c
e0137875 1483) die(_("--filter can only be used with the remote "
e0137875 1652) die(_("--filter can only be used with the remote "

builtin/pack-objects.c
edb673cf 2335) packing_data_lock(&to_pack);
edb673cf 2337) packing_data_unlock(&to_pack);

builtin/rebase.c
81ef8ee7 774) return -1;
d421afa0 1259) die(_("--reschedule-failed-exec requires an interactive rebase"));
d421afa0 1297) die(_("error: cannot combine '--preserve-merges' with "

builtin/receive-pack.c
01f9ec64 1587)     reader->line + 8);
01f9ec64 1621) die("protocol error: got an unexpected packet");

commit-graph.c
aa658574 127) return NULL;
aa658574 130) return NULL;
aa658574 186) free(graph);
aa658574 187) return NULL;
aa658574 222) free(graph);
aa658574 223) return NULL;
d9b1b309 935) display_progress(oids.progress, approx_nr_objects);

diff.c
b73bcbac 308) ret = 0;
21536d07 812)        (s[off] == '\r' && off < len - 1))
21536d07 813) off++;
b73bcbac 5112) options->color_moved_ws_handling = 0;

fetch-pack.c
01f9ec64 154) die(_("git fetch-pack: expected a flush packet after shallow list"));
01f9ec64 358) die(_("invalid shallow line: %s"), reader.line);
01f9ec64 364) die(_("invalid unshallow line: %s"), reader.line);
01f9ec64 366) die(_("object not found: %s"), reader.line);
01f9ec64 369) die(_("error in object: %s"), reader.line);
01f9ec64 371) die(_("no shallow found: %s"), reader.line);
01f9ec64 374) die(_("expected shallow/unshallow, got %s"), reader.line);
0bbc0bc5 1128) packet_buf_write(&req_buf, "sideband-all");
0bbc0bc5 1350) reader.use_sideband = 1;
0bbc0bc5 1351) reader.me = "fetch-pack";

hex.c
47edb649 93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb649 95) return hash_to_hex_algop_r(buffer, sha1, &hash_algos[GIT_HASH_SHA1]);
47edb649 116) char *hash_to_hex(const unsigned char *hash)
47edb649 118) return hash_to_hex_algop(hash, the_hash_algo);

http-push.c
ea82b2a0 1314) p = process_tree(lookup_tree(the_repository, &entry.oid),

http.c
e6cf87b1 1999) if (fflush(result)) {
e6cf87b1 2000) error_errno("unable to flush a file");
e6cf87b1 2001) return HTTP_START_FAILED;
e6cf87b1 2003) rewind(result);
e6cf87b1 2004) if (ftruncate(fileno(result), 0) < 0) {
e6cf87b1 2005) error_errno("unable to truncate a file");
e6cf87b1 2006) return HTTP_START_FAILED;
e6cf87b1 2008) break;
e6cf87b1 2010) BUG("Unknown http_request target");

list-objects-filter.c
c813a7c3 199) return;

match-trees.c
f55ac431 231) hashcpy(tree_oid.hash, rewrite_here);
f55ac431 232) status = splice_tree(&tree_oid, subpath, oid2, &subtree);

pkt-line.c
0bbc0bc5 505) if (demultiplex_sideband(reader->me, reader->buffer,
0bbc0bc5 508) break;
0bbc0bc5 509) }

pretty.c
ad6f028f 1204) return 0;

remote-curl.c
01f9ec64 427) die("invalid server response; got '%s'", reader.line);
01f9ec64 439) }
b79bdd8c 576) return size;

send-pack.c
01f9ec64 143) return error(_("unable to parse remote unpack status: %s"), reader->line);
01f9ec64 162) error("invalid ref status from remote: %s", reader->line);
01f9ec64 579) receive_unpack_status(&reader);

sha1-file.c
2f90b9d9 172) int hash_algo_by_name(const char *name)
2f90b9d9 175) if (!name)
2f90b9d9 176) return GIT_HASH_UNKNOWN;
2f90b9d9 177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9 178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9 179) return i;
2f90b9d9 180) return GIT_HASH_UNKNOWN;
2f90b9d9 183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9 186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9 187) if (format_id == hash_algos[i].format_id)
2f90b9d9 188) return i;
2f90b9d9 189) return GIT_HASH_UNKNOWN;

sideband.c
fbd76cd4 128) suffix = ANSI_SUFFIX;
fbd76cd4 138) strbuf_addf(scratch,
fbd76cd4 140)     scratch->len ? "\n" : "", me);
fbd76cd4 141) *sideband_type = SIDEBAND_PROTOCOL_ERROR;
fbd76cd4 142) goto cleanup;
0bbc0bc5 150) die("remote error: %s", buf + 1);
fbd76cd4 195) strbuf_addf(scratch, "%s%s: protocol error: bad band #%d",
fbd76cd4 196)     scratch->len ? "\n" : "", me, band);
fbd76cd4 197) *sideband_type = SIDEBAND_PROTOCOL_ERROR;
fbd76cd4 198) break;
0bbc0bc5 203) die("%s", scratch->buf);

submodule.c
26f80ccf 1398) strbuf_release(&gitdir);
be76c212 1521) struct fetch_task *task = task_cb;
be76c212 1525) fetch_task_release(task);
be76c212 1551) BUG("callback cookie bogus");

t/helper/test-hash-speed.c
37649b7f 6) static inline void compute_hash(const struct git_hash_algo *algo, git_hash_ctx *ctx, uint8_t *final, const void *p, size_t len)
37649b7f 8) algo->init_fn(ctx);
37649b7f 9) algo->update_fn(ctx, p, len);
37649b7f 10) algo->final_fn(final, ctx);
37649b7f 11) }
37649b7f 13) int cmd__hash_speed(int ac, const char **av)
37649b7f 18) unsigned bufsizes[] = { 64, 256, 1024, 8192, 16384 };
37649b7f 21) const struct git_hash_algo *algo = NULL;
37649b7f 23) if (ac == 2) {
37649b7f 24) for (i = 1; i < GIT_HASH_NALGOS; i++) {
37649b7f 25) if (!strcmp(av[1], hash_algos[i].name)) {
37649b7f 26) algo = &hash_algos[i];
37649b7f 27) break;
37649b7f 31) if (!algo)
37649b7f 32) die("usage: test-tool hash-speed algo_name");
37649b7f 35) initial = clock();
37649b7f 37) printf("algo: %s\n", algo->name);
37649b7f 39) for (i = 0; i < ARRAY_SIZE(bufsizes); i++) {
37649b7f 42) p = xcalloc(1, bufsizes[i]);
37649b7f 43) start = end = clock() - initial;
37649b7f 44) for (j = 0; ((end - start) / CLOCKS_PER_SEC) < NUM_SECONDS; j++) {
37649b7f 45) compute_hash(algo, &ctx, hash, p, bufsizes[i]);
37649b7f 51) if (!(j & 127))
37649b7f 52) end = clock() - initial;
37649b7f 54) kb = j * bufsizes[i];
37649b7f 55) kb_per_sec = kb / (1024 * ((double)end - start) / CLOCKS_PER_SEC);
37649b7f 56) printf("size %u: %lu iters; %lu KiB; %0.2f KiB/s\n", bufsizes[i], j, kb, kb_per_sec);
37649b7f 57) free(p);
37649b7f 60) exit(0);

t/helper/test-hash.c
50c817e0 17) bufsz = strtoul(av[1], NULL, 10) * 1024 * 1024;
50c817e0 21) bufsz = 8192;
50c817e0 24) fprintf(stderr, "bufsz %u is too big, halving...\n", bufsz);
50c817e0 25) bufsz /= 2;
50c817e0 26) if (bufsz < 1024)
50c817e0 27) die("OOPS");
50c817e0 42) die_errno("test-hash");

tree-walk.c
0a3faa45 530) oidcpy(result, &oid);

tree.c
371820d5 104) commit = lookup_commit(r, &entry.oid);

upload-pack.c
87c2d9d3 149) sq_quote_buf(&buf, expanded_filter_spec.buf);
01f9ec64 432) die("git upload-pack: expected SHA1 list, got '%s'", reader->line);
0bbc0bc5 1066) allow_sideband_all = git_config_bool(var, value);
07c3c2aa 1306)      allow_sideband_all) &&
07c3c2aa 1307)     !strcmp(arg, "sideband-all")) {
0bbc0bc5 1308) data->writer.use_sideband = 1;
0bbc0bc5 1309) continue;
bc2e795c 1441) deepen(&data->writer, INFINITE_DEPTH, data->deepen_relative,
07c3c2aa 1544)    &allow_sideband_all_value) &&

Commits introducting uncovered code:
Ævar Arnfjörð Bjarmason	d9b1b309 commit-graph write: show progress for object search
brian m. carlson	0a3faa45 tree-walk: copy object ID before use
brian m. carlson	37649b7f t/helper: add a test helper to compute hash speed
brian m. carlson	f55ac431 match-trees: use hashcpy to splice trees
brian m. carlson	2f90b9d9 sha1-file: provide functions to look up hash algorithms
brian m. carlson	50c817e0 t: make the sha1 test-tool helper generic
brian m. carlson	47edb649 hex: introduce functions to print arbitrary hashes
brian m. carlson	ea82b2a0 tree-walk: store object_id in a separate member
Christian Couder	e0137875 fetch: fix extensions.partialclone name in error message
Issac Trotts	ad6f028f log: add %S option (like --source) to log --format
Johannes Schindelin	81ef8ee7 rebase: introduce a shortcut for --reschedule-failed-exec
Johannes Schindelin	d421afa0 rebase: introduce --reschedule-failed-exec
Jonathan Tan	07c3c2aa tests: define GIT_TEST_SIDEBAND_ALL
Jonathan Tan	bc2e795c pkt-line: introduce struct packet_writer
Jonathan Tan	4316ff30 fetch-pack: support protocol version 2
Jonathan Tan	0bbc0bc5 {fetch,upload}-pack: sideband v2 fetch response
Jonathan Tan	fbd76cd4 sideband: reverse its dependency on pkt-line
Josh Steadmon	aa658574 commit-graph, fuzz: add fuzzer for commit-graph
Josh Steadmon	87c2d9d3 filter-options: expand scaled numbers
Junio C Hamano	371820d5 Merge branch 'bc/tree-walk-oid'
Masaya Suzuki	01f9ec64 Use packet_reader instead of packet_read_line
Masaya Suzuki	b79bdd8c remote-curl: unset CURLOPT_FAILONERROR
Masaya Suzuki	e6cf87b1 http: enable keep_error for HTTP requests
Matthew DeVore	c813a7c3 list-objects-filter: teach tree:# how to handle >0
Patrick Hogg	edb673cf pack-objects: merge read_lock and lock in packing_data struct
Phillip Wood	21536d07 diff --color-moved-ws: modify allow-indentation-change
Phillip Wood	b73bcbac diff: allow --no-color-moved-ws
Stefan Beller	be76c212 fetch: ensure submodule objects fetched
Stefan Beller	26f80ccf submodule: migrate get_next_submodule to use repository structs



^ permalink raw reply	[relevance 1%]

* Re: [PATCH 7/9] submodule: migrate get_next_submodule to use repository structs
  2018-11-29  0:27 23% ` [PATCH 7/9] submodule: migrate get_next_submodule to use repository structs Stefan Beller
@ 2019-02-02  1:58  4%   ` Jonathan Nieder
  0 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2019-02-02  1:58 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, jonathantanmy

Hi,

Stefan Beller wrote:

> This patch tightens the check upfront, such that we do not need
> to spawn a child process to find out if the submodule is broken.

Sounds sensible.

[...]
> --- a/submodule.c
> +++ b/submodule.c
[...]
> @@ -1319,10 +1338,23 @@ static int get_next_submodule(struct child_process *cp,
>  			argv_array_push(&cp->args, default_argv);
>  			argv_array_push(&cp->args, "--submodule-prefix");
>  			argv_array_push(&cp->args, submodule_prefix.buf);
> +
> +			repo_clear(repo);
> +			free(repo);
>  			ret = 1;
> +		} else {
> +			/*
> +			 * An empty directory is normal,
> +			 * the submodule is not initialized
> +			 */
> +			if (S_ISGITLINK(ce->ce_mode) &&
> +			    !is_empty_dir(ce->name)) {

What if the directory is nonempty (e.g. contains build artifacts)?

> +				spf->result = 1;
> +				strbuf_addf(err,
> +					    _("Could not access submodule '%s'"),
> +					    ce->name);
> +			}

Should this exit the loop?  Otherwise, multiple "Could not access"
messages can go in the same err string a big concatenated line.

Thanks,
Jonathan

^ permalink raw reply	[relevance 4%]

* Git Test Coverage Report (Tue. January 29, 2019)
@ 2019-01-29 17:46  1% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2019-01-29 17:46 UTC (permalink / raw)
  To: Git List

Here is today's test coverage report.

Since the last report, I have overhauled the machinery for generating these
reports. The code is available on GitHub [1], and the reports are available
online in text [2] and HTML [3] form.

In addition to the two output formats, the code also has the ability to
ignore lines that are unimportant for coverage. This allows me to review
the report, and reduce the size of the next one. For this reason, I set
the comparison branch for 'master' to 'maint' so we can see what is
uncovered in that segment. If you wish to add ignored lines, then please
open a pull request against the GitHub repo [1].

One side effect is that some file names may appear with no uncovered code.
The ignored lines are visible by clicking a button on the HTML report [3].

The 'pu' versus 'jch' report looks rather large to me, but I did use prove
to run the tests, so the entire test suite did run (through failures). A
lot of the lines are related to trace2, so I'll add the GIT_TR2* variables
to my build when running with optional variables.

As always, I hope this is useful and I look forward to your feedback.

Thanks,
-Stolee

[1] https://github.com/derrickstolee/git-test-coverage
[2] https://derrickstolee.github.io/git-test-coverage/reports/2019-01-29.txt
[3] https://derrickstolee.github.io/git-test-coverage/reports/2019-01-29.htm

---

pu	c7baf85843ec1dc8272483baa2f84d0ec66ad882
jch	2ea90524518a3dfcb3cda871ef2b1a739075e5d9
next	aa96b0ce6b0fa4fa4cc6870f1a3aff3878967bfa
master	16a465bc018d09e9d7bbbdc5f40a7fb99c21f8ef
maint	0d0ac3826a3bbb9247e39e12623bbcfdd722f24c


Uncovered code in 'pu' not in 'jch'
--------------------------------------------------------

bisect.c
4f6d26b1 661) mark_edges_uninteresting(revs, NULL, 0);

blame.c
07d04b91 482)     ent->s_lno + ent->num_lines == next->s_lno &&
07d04b91 483)     ent->ignored == next->ignored) {
e7973c85 940) blame_origin_decref(e->suspect);
e7973c85 941) e->suspect = blame_origin_incref(parent);
e7973c85 942) e->s_lno += offset;
07d04b91 943) e->ignored = 1;
e7973c85 944) e->next = ignoredp;
b543bb1c 1497) same = 1;
b543bb1c 1503) blame_origin_decref(porigin);

builtin/blame.c
07d04b91 485) length--;
31653c1a 699) if (!value)
31653c1a 700) return config_error_nonbool(var);
a5481a6c 701) parse_date_format(value, &blame_date_mode);
31653c1a 702) return 0;
5817da01 777) return 0;
31653c1a 930) blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700");
31653c1a 931) break;
5817da01 998) usage_with_options(blame_opt_usage, options);

builtin/change.c
49854277 23) static int change_list(int argc, const char **argv, const char* prefix)
49854277 25) struct option options[] = {
49854277 31) struct ref_format format = REF_FORMAT_INIT;
49854277 35) argc = parse_options(argc, argv, prefix, options, builtin_list_usage, 0);
49854277 37) setup_ref_filter_porcelain_msg();
49854277 39) memset(&filter, 0, sizeof(filter));
49854277 40) memset(&array, 0, sizeof(array));
49854277 42) filter.kind = FILTER_REFS_CHANGES;
49854277 43) filter.name_patterns = argv;
49854277 45) filter_refs(&array, &filter, FILTER_REFS_CHANGES);
49854277 52) if (!format.format) {
49854277 53) format.format = "%(refname:lstrip=1)";
49854277 56) if (verify_ref_format(&format))
49854277 57) die(_("unable to parse format string"));
49854277 59) for (i = 0; i < array.nr; i++) {
49854277 60) show_ref_array_item(array.items[i], &format);
49854277 63) ref_array_clear(&array);
49854277 65) return 0;
73f8829d 76) static void init_update_state(struct update_state *state)
73f8829d 78) memset(state, 0, sizeof(*state));
73f8829d 79) state->content = "HEAD";
73f8829d 80) string_list_init(&state->replace, 0);
73f8829d 81) string_list_init(&state->origin, 0);
73f8829d 82) }
73f8829d 84) static void clear_update_state(struct update_state *state)
73f8829d 86) string_list_clear(&state->replace, 0);
73f8829d 87) string_list_clear(&state->origin, 0);
73f8829d 88) }
73f8829d 90) static int update_option_parse_replace(const struct option *opt,
73f8829d 93) struct update_state *state = opt->value;
73f8829d 94) string_list_append(&state->replace, arg);
73f8829d 95) return 0;
73f8829d 98) static int update_option_parse_origin(const struct option *opt,
73f8829d 101) struct update_state *state = opt->value;
73f8829d 102) string_list_append(&state->origin, arg);
73f8829d 103) return 0;
73f8829d 106) static int resolve_commit(const char *committish, struct object_id *result)
73f8829d 109) if (get_oid_committish(committish, result))
73f8829d 110) die(_("Failed to resolve '%s' as a valid revision."), committish);
73f8829d 111) commit = lookup_commit_reference(the_repository, result);
73f8829d 112) if (!commit)
73f8829d 113) die(_("Could not parse object '%s'."), committish);
73f8829d 114) oidcpy(result, &commit->object.oid);
73f8829d 115) return 0;
73f8829d 118) static void resolve_commit_list(const struct string_list *commitsish_list,
73f8829d 122) for (i = 0; i < commitsish_list->nr; i++) {
73f8829d 123) struct string_list_item *item = &commitsish_list->items[i];
73f8829d 125) resolve_commit(item->string, &next);
73f8829d 126) oid_array_append(result, &next);
73f8829d 128) }
73f8829d 134) static void get_metacommit_from_command_line(
73f8829d 137) resolve_commit(commands->content, &(result->content));
73f8829d 138) resolve_commit_list(&(commands->replace), &(result->replace));
73f8829d 139) resolve_commit_list(&(commands->origin), &(result->origin));
73f8829d 140) }
73f8829d 142) static int perform_update(
73f8829d 150) init_metacommit_data(&metacommit);
73f8829d 152) get_metacommit_from_command_line(state, &metacommit);
73f8829d 154) ret = record_metacommit(repo, &metacommit, state->change, state->options, err);
73f8829d 156) clear_metacommit_data(&metacommit);
73f8829d 158) return ret;
73f8829d 161) static int change_update(int argc, const char **argv, const char* prefix)
73f8829d 164) int force = 0;
73f8829d 165) int newchange = 0;
73f8829d 166) struct strbuf err = STRBUF_INIT;
73f8829d 168) struct option options[] = {
73f8829d 186) init_update_state(&state);
73f8829d 188) argc = parse_options(argc, argv, prefix, options, builtin_update_usage, 0);
73f8829d 190) if (force) state.options |= UPDATE_OPTION_FORCE;
73f8829d 191) if (newchange) state.options |= UPDATE_OPTION_NOAPPEND;
73f8829d 193) result = perform_update(the_repository, &state, &err);
73f8829d 195) if (result < 0) {
73f8829d 196) error("%s", err.buf);
73f8829d 197) strbuf_release(&err);
73f8829d 200) clear_update_state(&state);
73f8829d 202) return result;
73f8829d 216) if (argc < 1)
73f8829d 217) usage_with_options(builtin_change_usage, options);
49854277 218) else if (!strcmp(argv[0], "list"))
49854277 219) result = change_list(argc, argv, prefix);
73f8829d 220) else if (!strcmp(argv[0], "update"))
73f8829d 221) result = change_update(argc, argv, prefix);
73f8829d 223) error(_("Unknown subcommand: %s"), argv[0]);
73f8829d 224) usage_with_options(builtin_change_usage, options);
73f8829d 227) return result ? 1 : 0;

builtin/config.c
a12c1ff3 110) die(_("$HOME not set"));
a12c1ff3 122) given_config_source.file = git_etc_gitconfig();
1d28ff4c 401) error(_("invalid key pattern: %s"), key_);
6a83d902 402) FREE_AND_NULL(key_regexp);
9409c7a5 403) ret = CONFIG_INVALID_PATTERN;
1d28ff4c 421) error(_("invalid pattern: %s"), regex_);
6a83d902 422) FREE_AND_NULL(regexp);
9409c7a5 423) ret = CONFIG_INVALID_PATTERN;
5f1a63e0 424) goto free_strings;

builtin/pack-redundant.c
cb7e0336 461) llist_sorted_difference_inplace(all_objects, pl->remaining_objects);
1c3039e8 462) pl = pl->next;
bd22c904 478) static void scan_alt_odb_packs(void)
eeefa7c9 572) if (!strcmp(arg, "--verbose")) {
6390fe20 606) if (get_oid_hex(buf, oid))

builtin/rebase--interactive.c
e5b1c9d9 24) return error_errno(_("could not read '%s'."), todo_file);
e5b1c9d9 31) return error_errno(_("could not write '%s'"), todo_file);
4d55dfd7 46) return error_errno(_("could not read '%s'."), todo_file);
4d55dfd7 50) todo_list_release(&todo_list);
4d55dfd7 51) return error(_("unusable todo list: '%s'"), todo_file);
4d55dfd7 59) return error_errno(_("could not write '%s'."), todo_file);

builtin/rebase.c
c54dacb5 1351) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb5 1352) const char *state_dir_base =
c54dacb5 1353) last_slash ? last_slash + 1 : options.state_dir;
c54dacb5 1354) const char *cmd_live_rebase =

builtin/stash.c
f6bbd781 128) die(_("'%s' is not a stash-like commit"), revision);
f6bbd781 161) free_stash_info(info);
f6bbd781 162) fprintf_ln(stderr, _("No stash entries found."));
f6bbd781 163) return -1;
f6bbd781 198) free_stash_info(info);
cdca49bc 225) return error(_("git stash clear with parameters is "
f6bbd781 241) return -1;
f6bbd781 249) return -1;
f6bbd781 265) return error(_("unable to write new index file"));
f6bbd781 377) remove_path(stash_index_path.buf);
f6bbd781 378) return -1;
f6bbd781 405) return -1;
f6bbd781 408) return error(_("cannot apply a stash in the middle of a merge"));
f6bbd781 418) strbuf_release(&out);
f6bbd781 419) return error(_("could not generate diff %s^!."),
f6bbd781 426) return error(_("conflicts in index."
f6bbd781 432) return error(_("could not save index tree"));
f6bbd781 439) return error(_("could not restore untracked files from stash"));
f6bbd781 470) return -1;
f6bbd781 475) strbuf_release(&out);
f6bbd781 480) strbuf_release(&out);
f6bbd781 481) return -1;
cdca49bc 557) return error(_("%s: Could not drop stash entry"),
e1d01876 632) printf_ln(_("The stash entry is kept in case "
b4493f26 766) free_stash_info(&info);
51809c70 767) usage_with_options(git_stash_show_usage, options);
847eb0b0 783) stash_msg = "Created via \"git stash store\".";
847eb0b0 789) if (!quiet) {
847eb0b0 790) fprintf_ln(stderr, _("Cannot update %s with %s"),
847eb0b0 793) return -1;
847eb0b0 817) if (!quiet)
847eb0b0 818) fprintf_ln(stderr, _("\"git stash store\" requires one "
847eb0b0 820) return -1;
1f5a011d 903) return -1;
1f5a011d 963) ret = -1;
1f5a011d 964) goto done;
1f5a011d 969) ret = -1;
1f5a011d 970) goto done;
1f5a011d 975) ret = -1;
1f5a011d 976) goto done;
1f5a011d 1002) ret = -1;
1f5a011d 1003) goto done;
1f5a011d 1014) ret = -1;
1f5a011d 1015) goto done;
1f5a011d 1021) ret = -1;
1f5a011d 1022) goto done;
1f5a011d 1029) ret = -1;
1f5a011d 1030) goto done;
1f5a011d 1068) ret = -1;
1f5a011d 1069) goto done;
1f5a011d 1075) ret = -1;
1f5a011d 1076) goto done;
1f5a011d 1087) ret = -1;
1f5a011d 1088) goto done;
1f5a011d 1093) ret = -1;
1f5a011d 1094) goto done;
9a95010a 1130) fprintf_ln(stderr, _("You do not have "
1f5a011d 1139) ret = 1;
1f5a011d 1140) goto done;
9a95010a 1156) if (!quiet)
9a95010a 1157) fprintf_ln(stderr, _("Cannot save the current "
1f5a011d 1159) ret = -1;
1f5a011d 1160) goto done;
9a95010a 1165) if (!quiet)
9a95010a 1166) fprintf_ln(stderr, _("Cannot save "
1f5a011d 1168) ret = -1;
1f5a011d 1169) goto done;
9a95010a 1176) if (!quiet)
9a95010a 1177) fprintf_ln(stderr, _("Cannot save the current "
1f5a011d 1179) goto done;
9a95010a 1213) if (!quiet)
9a95010a 1214) fprintf_ln(stderr, _("Cannot record "
1f5a011d 1216) ret = -1;
1f5a011d 1217) goto done;
fa38428f 1286) ret = -1;
fa38428f 1287) goto done;
fa38428f 1297) ret = -1;
9a95010a 1298) if (!quiet)
9a95010a 1299) fprintf_ln(stderr, _("Cannot initialize stash"));
fa38428f 1300) goto done;
fa38428f 1312) ret = -1;
9a95010a 1313) if (!quiet)
9a95010a 1314) fprintf_ln(stderr, _("Cannot save the current status"));
fa38428f 1315) goto done;
fa38428f 1332) ret = -1;
fa38428f 1351) ret = -1;
fa38428f 1352) goto done;
fa38428f 1361) ret = -1;
fa38428f 1362) goto done;
fa38428f 1370) ret = -1;
fa38428f 1379) ret = -1;
fa38428f 1390) ret = -1;
fa38428f 1391) goto done;
fa38428f 1400) ret = -1;
fa38428f 1401) goto done;
fa38428f 1409) ret = -1;
fa38428f 1435) ret = -1;
bec65d5b 1527) return env;
26799a20 1555) const char *path = mkpath("%s/git-legacy-stash",
26799a20 1558) if (sane_execvp(path, (char **)argv) < 0)
26799a20 1559) die_errno(_("could not exec %s"), path);
26799a20 1561) BUG("sane_execvp() returned???");
51809c70 1602) usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
51809c70 1630) continue;

builtin/update-index.c
309be813 905) return error("option '%s' must be the last argument", opt->long_name);
309be813 924) active_cache_changed = 0;

change-table.c
287a8679 7) void change_table_init(struct change_table *to_initialize)
287a8679 9) memset(to_initialize, 0, sizeof(*to_initialize));
287a8679 10) mem_pool_init(&(to_initialize->memory_pool), 0);
287a8679 11) to_initialize->memory_pool->block_alloc = 4*1024 - sizeof(struct mp_block);
287a8679 12) oidmap_init(&(to_initialize->oid_to_metadata_index), 0);
287a8679 13) string_list_init(&(to_initialize->refname_to_change_head), 1);
287a8679 14) }
287a8679 16) static void change_list_clear(struct change_list *to_clear) {
287a8679 17) string_list_clear(&to_clear->additional_refnames, 0);
287a8679 18) }
287a8679 20) static void commit_change_list_entry_clear(
287a8679 22) change_list_clear(&(to_clear->changes));
287a8679 23) }
287a8679 25) static void change_head_array_clear(struct change_head_array *to_clear)
287a8679 27) FREE_AND_NULL(to_clear->array);
287a8679 28) }
287a8679 30) void change_table_clear(struct change_table *to_clear)
287a8679 34) for (next = oidmap_iter_first(&to_clear->oid_to_metadata_index, &iter);
287a8679 36) next = oidmap_iter_next(&iter)) {
287a8679 38) commit_change_list_entry_clear(next);
287a8679 41) oidmap_free(&to_clear->oid_to_metadata_index, 0);
287a8679 42) string_list_clear(&(to_clear->refname_to_change_head), 0);
287a8679 43) change_head_array_clear(&to_clear->heads);
287a8679 44) mem_pool_discard(to_clear->memory_pool, 0);
287a8679 45) }
287a8679 51) static int change_head_array_append(struct change_head_array *to_add)
287a8679 53) int index = to_add->nr++;
287a8679 55) ALLOC_GROW(to_add->array, to_add->nr, to_add->alloc);
287a8679 56) new_head = &(to_add->array[index]);
287a8679 57) memset(new_head, 0, sizeof(*new_head));
287a8679 58) return index;
287a8679 61) static void add_head_to_commit(struct change_table *to_modify,
287a8679 68) entry = oidmap_get(&(to_modify->oid_to_metadata_index), to_add);
287a8679 69) if (!entry) {
287a8679 70) entry = mem_pool_calloc(to_modify->memory_pool, 1,
287a8679 72) oidcpy(&entry->entry.oid, to_add);
287a8679 73) oidmap_put(&(to_modify->oid_to_metadata_index), entry);
287a8679 74) string_list_init(&(entry->changes.additional_refnames), 0);
287a8679 77) if (entry->changes.first_refname == NULL) {
287a8679 78) entry->changes.first_refname = refname;
287a8679 80) string_list_insert(&entry->changes.additional_refnames, refname);
287a8679 82) }
287a8679 84) void change_table_add(struct change_table *to_modify, const char *refname,
287a8679 92) index = change_head_array_append(&to_modify->heads);
287a8679 93) new_head = &(to_modify->heads.array[index]);
287a8679 95) oidcpy(&new_head->head, &(to_add->object.oid));
287a8679 97) metacommit_type = get_metacommit_content(to_add, &new_head->content);
287a8679 98) if (metacommit_type == METACOMMIT_TYPE_NONE) {
287a8679 99) oidcpy(&new_head->content, &(to_add->object.oid));
287a8679 101) new_head->abandoned = (metacommit_type == METACOMMIT_TYPE_ABANDONED);
287a8679 102) new_head->remote = starts_with(refname, "refs/remote/");
287a8679 103) new_head->hidden = starts_with(refname, "refs/hiddenmetas/");
287a8679 105) new_item = string_list_insert(&to_modify->refname_to_change_head, refname);
287a8679 106) new_item->util = (void*)index;
287a8679 108) refname = new_item->string;
287a8679 110) if (!oideq(&new_head->content, &new_head->head)) {
287a8679 111) add_head_to_commit(to_modify, &(new_head->content), refname);
287a8679 113) add_head_to_commit(to_modify, &(new_head->head), refname);
287a8679 114) }
287a8679 116) void change_table_add_all_visible(struct change_table *to_modify,
287a8679 120) const char *name_patterns[] = {NULL};
287a8679 121) memset(&filter, 0, sizeof(filter));
287a8679 122) filter.kind = FILTER_REFS_CHANGES;
287a8679 123) filter.name_patterns = name_patterns;
287a8679 125) change_table_add_matching_filter(to_modify, repo, &filter);
287a8679 126) }
287a8679 128) void change_table_add_matching_filter(struct change_table *to_modify,
287a8679 134) memset(&matching_refs, 0, sizeof(matching_refs));
287a8679 135) filter_refs(&matching_refs, filter, filter->kind);
287a8679 142) for (i = 0; i < matching_refs.nr; i++) {
287a8679 143) struct ref_array_item *item = matching_refs.items[i];
287a8679 144) struct commit *commit = item->commit;
287a8679 146) commit = lookup_commit_reference_gently(repo, &(item->objectname), 1);
287a8679 148) if (commit != NULL) {
287a8679 149) change_table_add(to_modify, item->refname, commit);
287a8679 153) ref_array_clear(&matching_refs);
287a8679 154) }
287a8679 156) static int return_true_callback(const char *refname, void *cb_data)
287a8679 158) return 1;
287a8679 161) int change_table_has_change_referencing(struct change_table *changes,
287a8679 164) return for_each_change_referencing(changes, referenced_commit_id,
287a8679 168) int for_each_change_referencing(struct change_table *table,
287a8679 176) entry = oidmap_get(&table->oid_to_metadata_index,
287a8679 179) if (!entry) {
287a8679 180) return 0;
287a8679 182) changes = &(entry->changes);
287a8679 183) if (changes->first_refname == NULL) {
287a8679 184) return 0;
287a8679 186) retvalue = fn(changes->first_refname, cb_data);
287a8679 187) for (i = 0; retvalue == 0 && i < changes->additional_refnames.nr; i++) {
287a8679 188) retvalue = fn(changes->additional_refnames.items[i].string, cb_data);
287a8679 190) return retvalue;
287a8679 193) struct change_head* get_change_head(struct change_table *heads,
287a8679 196) struct string_list_item *item = string_list_lookup(
287a8679 200) if (!item) {
287a8679 201) return NULL;
287a8679 204) index = (long)item->util;
287a8679 205) return &(heads->heads.array[index]);

config.c
8f7c7f55 2147) int repo_config_set_gently(struct repository *r,
8f7c7f55 2150) char *path = repo_git_path(r, "config");
8f7c7f55 2151) int ret = git_config_set_multivar_in_file_gently(path, key, value, NULL, 0);
8f7c7f55 2152) free(path);
8f7c7f55 2153) return ret;
8f7c7f55 2156) void repo_config_set(struct repository *r, const char *key, const char *value)
8f7c7f55 2158) if (!repo_config_set_gently(r, key, value))
8f7c7f55 2159) return;
8f7c7f55 2160) if (value)
8f7c7f55 2161) die(_("could not set '%s' to '%s'"), key, value);
8f7c7f55 2163) die(_("could not unset '%s'"), key);
8f7c7f55 2166) int repo_config_set_worktree_gently(struct repository *r,
8f7c7f55 2172) path = get_worktree_config(r);
8f7c7f55 2173) if (!path)
8f7c7f55 2174) return CONFIG_INVALID_FILE;
8f7c7f55 2175) ret = git_config_set_multivar_in_file_gently(path, key, value, NULL, 0);
8f7c7f55 2176) free(path);
93c1e079 2920) goto write_err_out;
93c1e079 2923) goto write_err_out;

connect.c
aad6fddb 1299) die(_("unable to fork"));

date.c
acdd3776 113) die("Timestamp too large for this system: %"PRItime, time);
7d29afd4 138) return;
033abf97 209) BUG("cannot create anonymous strftime date_mode struct");
acdd3776 236) hide.date = 1;

diff.c
dd63f169 4639) die(_("--follow requires exactly one pathspec"));
d473e2e0 4946) return error(_("%s expects a numerical value"), "--unified");

git.c
63ab7419 155) trace2_cmd_verb("_query_");
63ab7419 159) trace2_cmd_verb("_query_");
63ab7419 163) trace2_cmd_verb("_query_");
8aa8c140 372) die(_("recursive alias: %s"), alias_command);
8aa8c140 456) die_errno(_("close failed on standard output"));
8aa8c140 680) die(_("%s doesn't support --super-prefix"), argv[0]);
246f0ede 717) exit(128);

list-objects.c
4f6d26b1 241) continue;
4f6d26b1 250) parent->object.flags |= SHOWN;
4f6d26b1 251) show_edge(parent);
4f6d26b1 272) tree->object.flags |= UNINTERESTING;
4f6d26b1 287) commit->object.flags |= SHOWN;
4f6d26b1 288) show_edge(commit);

metacommit-parser.c
6930f34d 9) static const char *find_key(const char *msg, const char *key, size_t *out_len)
6930f34d 11) int key_len = strlen(key);
6930f34d 12) const char *line = msg;
6930f34d 14) while (line) {
6930f34d 15) const char *eol = strchrnul(line, '\n');
6930f34d 17) if (eol - line > key_len &&
6930f34d 18) !strncmp(line, key, key_len) &&
6930f34d 19) line[key_len] == ' ') {
6930f34d 20) *out_len = eol - line - key_len - 1;
6930f34d 21) return line + key_len + 1;
6930f34d 23) line = *eol ? eol + 1 : NULL;
6930f34d 25) return NULL;
6930f34d 28) static struct commit *get_commit_by_index(struct commit_list *to_search, int index)
6930f34d 30) while (to_search && index) {
6930f34d 31) to_search = to_search->next;
6930f34d 32) --index;
6930f34d 35) return to_search->item;
6930f34d 42) int get_metacommit_content(
6930f34d 45) const char *buffer = get_commit_buffer(commit, NULL);
6930f34d 47) const char *parent_types = find_key(buffer, "parent-type",
6930f34d 50) int index = 0;
6930f34d 54) if (!parent_types) {
6930f34d 55) return METACOMMIT_TYPE_NONE;
6930f34d 58) end = &(parent_types[parent_types_size]);
6930f34d 61) char next = *parent_types;
6930f34d 62) if (next == ' ') {
6930f34d 63) index++;
6930f34d 65) if (next == 'c') {
6930f34d 66) ret = METACOMMIT_TYPE_NORMAL;
6930f34d 67) break;
6930f34d 69) if (next == 'a') {
6930f34d 70) ret = METACOMMIT_TYPE_ABANDONED;
6930f34d 71) break;
6930f34d 73) parent_types++;
6930f34d 74) if (parent_types >= end) {
6930f34d 75) return METACOMMIT_TYPE_NONE;
6930f34d 77) }
6930f34d 79) content_parent = get_commit_by_index(commit->parents, index);
6930f34d 81) if (!content_parent) {
6930f34d 82) return METACOMMIT_TYPE_NONE;
6930f34d 85) oidcpy(content, &(content_parent->object.oid));
6930f34d 86) return ret;

metacommit.c
6b8678e5 7) void init_metacommit_data(struct metacommit_data *state)
6b8678e5 9) memset(state, 0, sizeof(*state));
6b8678e5 10) }
6b8678e5 12) void clear_metacommit_data(struct metacommit_data *state)
6b8678e5 14) oid_array_clear(&state->replace);
6b8678e5 15) oid_array_clear(&state->origin);
6b8678e5 16) }
6b8678e5 18) static void compute_default_change_name(struct commit *initial_commit,
6b8678e5 21) const char *buffer = get_commit_buffer(initial_commit, NULL);
6b8678e5 25) find_commit_subject(buffer, &subject);
6b8678e5 26) eol = strchrnul(subject, '\n');
6b8678e5 27) for (len = 0;subject < eol && len < 10; ++subject, ++len) {
6b8678e5 28) char next = *subject;
6b8678e5 29) if (isspace(next)) {
6b8678e5 30) continue;
6b8678e5 33) strbuf_addch(result, next);
6b8678e5 35) }
6b8678e5 42) static void compute_change_name(struct commit *initial_commit, struct strbuf* result)
6b8678e5 47) strbuf_init(&default_name, 0);
6b8678e5 48) if (initial_commit) {
6b8678e5 49) compute_default_change_name(initial_commit, &default_name);
6b8678e5 51) strbuf_addstr(&default_name, "change");
6b8678e5 53) strbuf_addstr(result, "refs/metas/");
6b8678e5 54) strbuf_addstr(result, default_name.buf);
6b8678e5 57) if (!read_ref(result->buf, &unused)) {
6b8678e5 58) int suffix = 2;
6b8678e5 59) int original_length = result->len;
6b8678e5 62) strbuf_addf(result, "%d", suffix);
6b8678e5 63) if (read_ref(result->buf, &unused)) {
6b8678e5 64) break;
6b8678e5 66) strbuf_remove(result, original_length, result->len - original_length);
6b8678e5 67) ++suffix;
6b8678e5 68) }
6b8678e5 71) strbuf_release(&default_name);
6b8678e5 72) }
6b8678e5 81) static int resolve_metacommit_callback(const char *refname, void *cb_data)
6b8678e5 83) struct resolve_metacommit_callback_data *data = (struct resolve_metacommit_callback_data *)cb_data;
6b8678e5 86) chhead = get_change_head(data->active_changes, refname);
6b8678e5 88) if (data->changes) {
6b8678e5 89) string_list_append(data->changes, refname)->util = &(chhead->head);
6b8678e5 91) if (data->heads) {
6b8678e5 92) oid_array_append(data->heads, &(chhead->head));
6b8678e5 95) return 0;
6b8678e5 101) static void resolve_metacommit(
6b8678e5 110) int len = to_resolve->replace.nr;
6b8678e5 112) int old_change_list_length = to_advance->nr;
6b8678e5 115) oidcpy(&resolved_output->content, &to_resolve->content);
6b8678e5 119) resolved_output->abandoned = to_resolve->abandoned;
6b8678e5 120) cbdata.active_changes = active_changes;
6b8678e5 121) cbdata.changes = to_advance;
6b8678e5 122) cbdata.heads = &(resolved_output->replace);
6b8678e5 124) if (allow_append) {
6b8678e5 125) for (i = 0; i < len; i++) {
6b8678e5 126) int old_number = resolved_output->replace.nr;
6b8678e5 127) for_each_change_referencing(active_changes, &(to_resolve->replace.oid[i]),
6b8678e5 130) if (old_number == resolved_output->replace.nr) {
6b8678e5 131) oid_array_append(&(resolved_output->replace), &(to_resolve->replace.oid[i]));
6b8678e5 136) cbdata.changes = NULL;
6b8678e5 137) cbdata.heads = &(resolved_output->origin);
6b8678e5 139) len = to_resolve->origin.nr;
6b8678e5 140) for (i = 0; i < len; i++) {
6b8678e5 141) int old_number = resolved_output->origin.nr;
6b8678e5 142) for_each_change_referencing(active_changes, &(to_resolve->origin.oid[i]),
6b8678e5 144) if (old_number == resolved_output->origin.nr) {
6b8678e5 145) oid_array_append(&(resolved_output->origin), &(to_resolve->origin.oid[i]));
6b8678e5 151) if (to_advance->nr == old_change_list_length) {
6b8678e5 154) strbuf_init(&change_name, 80);
6b8678e5 155) content = lookup_commit_reference_gently(repo, &(to_resolve->content), 1);
6b8678e5 157) compute_change_name(content, &change_name);
6b8678e5 158) string_list_append(to_advance, change_name.buf);
6b8678e5 159) strbuf_release(&change_name);
6b8678e5 161) }
6b8678e5 163) static void lookup_commits(
6b8678e5 168) int i = to_lookup->nr;
6b8678e5 170) while (--i >= 0) {
6b8678e5 171) struct object_id *next = &(to_lookup->oid[i]);
6b8678e5 172) struct commit *commit = lookup_commit_reference_gently(repo, next, 1);
6b8678e5 173) commit_list_insert(commit, result);
6b8678e5 175) }
6b8678e5 183) int write_metacommit(struct repository *repo, struct metacommit_data *state,
6b8678e5 186) struct commit_list *parents = NULL;
6b8678e5 191) strbuf_init(&comment, strlen(PARENT_TYPE_PREFIX)
6b8678e5 192) + 1 + 2 * (state->origin.nr + state->replace.nr));
6b8678e5 193) lookup_commits(repo, &state->origin, &parents);
6b8678e5 194) lookup_commits(repo, &state->replace, &parents);
6b8678e5 195) content = lookup_commit_reference_gently(repo, &state->content, 1);
6b8678e5 196) if (!content) {
6b8678e5 197) strbuf_release(&comment);
6b8678e5 198) free_commit_list(parents);
6b8678e5 199) return -1;
6b8678e5 201) commit_list_insert(content, &parents);
6b8678e5 203) strbuf_addstr(&comment, PARENT_TYPE_PREFIX);
6b8678e5 204) strbuf_addstr(&comment, state->abandoned ? "a" : "c");
6b8678e5 205) for (i = 0; i < state->replace.nr; i++) {
6b8678e5 206) strbuf_addstr(&comment, " r");
6b8678e5 209) for (i = 0; i < state->origin.nr; i++) {
6b8678e5 210) strbuf_addstr(&comment, " o");
6b8678e5 214) commit_tree(comment.buf, comment.len, repo->hash_algo->empty_tree, parents,
6b8678e5 217) strbuf_release(&comment);
6b8678e5 218) return 0;
6b8678e5 225) static int is_nontrivial_metacommit(struct metacommit_data *state)
6b8678e5 227) return state->replace.nr || state->origin.nr || state->abandoned;
6b8678e5 240) int record_metacommit(struct repository *repo,
6b8678e5 248) struct ref_transaction *transaction = NULL;
6b8678e5 253) int ret = 0;
6b8678e5 254) int force = (options & UPDATE_OPTION_FORCE);
6b8678e5 256) init_metacommit_data(&resolved_metacommit);
6b8678e5 257) string_list_init(&changes, 1);
6b8678e5 259) change_table_init(&chtable);
6b8678e5 261) change_table_add_all_visible(&chtable, repo);
6b8678e5 263) resolve_metacommit(repo, &chtable, metacommit, &resolved_metacommit, &changes,
6b8678e5 264) (options & UPDATE_OPTION_NOAPPEND) == 0);
6b8678e5 266) if (override_change) {
6b8678e5 267) old_head = &old_head_working;
6b8678e5 268) string_list_clear(&changes, 0);
6b8678e5 269) if (get_oid_committish(override_change, &old_head_working)) {
6b8678e5 271) old_head = &null_oid;
6b8678e5 272) } else if (!force) {
6b8678e5 273) if (!oid_array_readonly_contains(&(resolved_metacommit.replace),
6b8678e5 276) strbuf_addf(err, _("non-fast-forward update to '%s'"),
6b8678e5 278) ret = -1;
6b8678e5 279) goto cleanup;
6b8678e5 283) string_list_append(&changes, override_change)->util = (void*)old_head;
6b8678e5 286) if (is_nontrivial_metacommit(&resolved_metacommit)) {
6b8678e5 289) if (write_metacommit(repo, &resolved_metacommit, &commit_target) < 0) {
6b8678e5 290) ret = -1;
6b8678e5 291) goto cleanup;
6b8678e5 296) oidcpy(&commit_target, &(resolved_metacommit.content));
6b8678e5 301) if (!override_change &&
6b8678e5 302) change_table_has_change_referencing(&chtable, &commit_target)) {
6b8678e5 304) goto cleanup;
6b8678e5 307) transaction = ref_transaction_begin(err);
6b8678e5 310) if (!transaction) {
6b8678e5 311) ret = -1;
6b8678e5 313) for (i = 0; i < changes.nr; i++) {
6b8678e5 314) struct string_list_item *it = &(changes.items[i]);
6b8678e5 318) if (it->util) {
6b8678e5 319) if (ref_transaction_update(transaction, it->string, &commit_target,
6b8678e5 322) ret = -1;
6b8678e5 325) if (ref_transaction_create(transaction, it->string,
6b8678e5 328) ret = -1;
6b8678e5 333) if (!ret) {
6b8678e5 334) if (ref_transaction_commit(transaction, err)) {
6b8678e5 335) ret = -1;
6b8678e5 341) ref_transaction_free(transaction);
6b8678e5 342) string_list_clear(&changes, 0);
6b8678e5 343) clear_metacommit_data(&resolved_metacommit);
6b8678e5 344) change_table_clear(&chtable);
6b8678e5 345) return ret;
6b8678e5 355) void modify_change(
6b8678e5 363) init_metacommit_data(&metacommit);
6b8678e5 364) oidcpy(&(metacommit.content), new_commit);
6b8678e5 365) oid_array_append(&(metacommit.replace), old_commit);
6b8678e5 367) record_metacommit(repo, &metacommit, NULL, 0, err);
6b8678e5 369) clear_metacommit_data(&metacommit);

object.c
01f8d594 278) error(_("hash mismatch %s"), oid_to_hex(repl));

oidset.c
ef644c41 69) die_errno("Could not read '%s'", path);

pager.c
603036d9 103) pager_process->trace2_child_class = "pager";

parse-options.c
f62470c6 116) BUG("BITOP can't have unset form");
df217ed6 155) *(const char **)opt->value = (const char *)opt->defval;
2a514ed8 204) *(unsigned long *)opt->value = 0;
2a514ed8 205) return 0;
1e5ce570 405) err |= optbug(opts, "uses incompatible flags "
af465af8 409) err |= optbug(opts, "invalid short name");
af465af8 411) err |= optbug(opts, "short name already used");
3ebbe289 432) BUG("OPTION_CALLBACK needs one callback");
3ebbe289 434) BUG("OPTION_CALLBACK can't have two callbacks");
b9d7f4b4 540) switch (opts->type) {
b9d7f4b4 542) continue;
ebc4a04e 559) if (opts->flags & PARSE_OPT_COMP_ARG)
b221b5ab 561) if (starts_with(opts->long_name, "no-"))
b9d7f4b4 567) fputc('\n', stdout);
a92ec7ef 568) return PARSE_OPT_COMPLETE;
b9d7f4b4 606) return show_gitcomp(ctx, options);

pretty.c
4681fe38 1069) return 0;
b755bf6f 1107)     match_placeholder_arg(p, "=on", end) ||
b755bf6f 1108)     match_placeholder_arg(p, "=true", end)) {

protocol.c
6da1f1a9 37) die(_("Unrecognized protocol version"));
6da1f1a9 39) die(_("Unrecognized protocol_version"));
373d70ef 49) die("unknown value for config 'protocol.version': %s",
6da1f1a9 61) BUG("late attempt to register an allowed protocol version");

read-cache.c
78bde923 3099) return error_errno(_("could not stat '%s'"), shared_index_path);

rebase-interactive.c
c27b32f0 26) warning(_("unrecognized setting %s for option "

remote-curl.c
6da1f1a9 344) return 0;
34a9469d 373) die("invalid server response; expected service, got flush packet");
34a9469d 397) d->proto_git = 1;
0f1dc53f 1375) break;

revision.c
d5d2e935 169) return;
d5d2e935 172) return;
d5d2e935 195) break;
f1f5de44 218) continue;

run-command.c
63ab7419 239) int ec = errno;
63ab7419 240) trace2_exec_result(exec_id, ec);
63ab7419 241) errno = ec;
0ac77ec3 715) failed_errno = errno;
507d7804 995) int finish_command_in_signal(struct child_process *cmd)
63ab7419 997) int ret = wait_or_whine(cmd->pid, cmd->argv[0], 1);
63ab7419 998) trace2_child_exit(cmd, ret);
63ab7419 999) return ret;
c553c72e 1829) pp.shutdown = 1;
c553c72e 1830) kill_children(&pp, -code);

sequencer.c
8414c890 4610) return error_errno(_("could not read '%s'."), todo_file);
8414c890 4612) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, &todo_list)) {
3546c8d9 4613) todo_list_release(&todo_list);
3546c8d9 4614) return error(_("unusable todo list: '%s'"), todo_file);
0cce4a27 4619) todo_list_release(&todo_list);
8414c890 4621) if (res)
8414c890 4622) return error_errno(_("could not write '%s'."), todo_file);
c27b32f0 4705) goto out;
c27b32f0 4710) goto out;
c27b32f0 4719) fprintf(stderr, _(edit_todo_list_advice));
cdac2b01 4743) return error(_("could not parse commit '%s'"),
cdac2b01 4759) error_errno(_("could not write to '%s'"), done_path);
cdac2b01 4760) return -1;
febebd99 5027) if (strbuf_read_file_or_whine(&todo_list.buf, todo_file) < 0)
febebd99 5030) todo_list_release(&todo_list);

sha1-array.c
9e98e9b6 34) return sha1_pos(oid->hash, array->oid, array->nr, sha1_access) >= 0;

sha1-file.c
2c319886 1595) return error_errno(_("unable to write file %s"), filename);
76011357 1626) fsync_or_die(fd, "loose object file");
76011357 1628) die_errno(_("error when closing loose object file"));
76011357 1719) die(_("unable to write loose object file"));
2c319886 1818) return error(_("cannot read object for %s"), oid_to_hex(oid));

sha1-name.c
d1dd94b3 926) return MISSING_OBJECT;

strbuf.c
bfc3fe33 259) die("`pos' is too far after the end of the buffer");
bfc3fe33 264) BUG("your vsnprintf is broken (returned %d)", len);
bfc3fe33 266) return; /* nothing to do */
bfc3fe33 268) die("you want to use way too much memory");
bfc3fe33 276) BUG("your vsnprintf is broken (returns inconsistent lengths)");
033abf97 397) BUG("your vsnprintf is broken (returned %d)", len);
033abf97 402) BUG("your vsnprintf is broken (insatiable)");

t/helper/test-path-utils.c
d04fa788 180) static int cmp_by_st_size(const void *a, const void *b)
d04fa788 182) intptr_t x = (intptr_t)((struct string_list_item *)a)->util;
d04fa788 183) intptr_t y = (intptr_t)((struct string_list_item *)b)->util;
d04fa788 185) return x > y ? -1 : (x < y ? +1 : 0);
dc2d9ba3 294) res = error("'%s' is %s.gitmodules", argv[i],
a5c09131 308) res = error_errno("Cannot stat '%s'", argv[i]);
2987e8cd 314) if (argc == 4 && !strcmp(argv[1], "skip-n-bytes")) {
2987e8cd 315) int fd = open(argv[2], O_RDONLY), offset = atoi(argv[3]);
2987e8cd 318) if (fd < 0)
2987e8cd 319) die_errno("could not open '%s'", argv[2]);
2987e8cd 320) if (lseek(fd, offset, SEEK_SET) < 0)
2987e8cd 321) die_errno("could not skip %d bytes", offset);
2987e8cd 323) ssize_t count = read(fd, buffer, sizeof(buffer));
2987e8cd 324) if (count < 0)
2987e8cd 325) die_errno("could not read '%s'", argv[2]);
2987e8cd 326) if (!count)
2987e8cd 327) break;
2987e8cd 328) if (write(1, buffer, count) < 0)
2987e8cd 329) die_errno("could not write to stdout");
2987e8cd 330) }
2987e8cd 331) close(fd);
2987e8cd 332) return 0;
d04fa788 335) if (argc > 5 && !strcmp(argv[1], "slice-tests")) {
d04fa788 336) int res = 0;
d04fa788 338) struct string_list list = STRING_LIST_INIT_NODUP;
d04fa788 341) offset = strtol(argv[2], NULL, 10);
d04fa788 342) stride = strtol(argv[3], NULL, 10);
d04fa788 343) if (stride < 1)
d04fa788 344) stride = 1;
d04fa788 345) for (i = 4; i < argc; i++)
d04fa788 346) if (stat(argv[i], &st))
d04fa788 347) res = error_errno("Cannot stat '%s'", argv[i]);
d04fa788 349) string_list_append(&list, argv[i])->util =

t/helper/test-sha1-array.c
9e98e9b6 30) die("not a hexadecimal SHA1: %s", arg);

t/helper/test-trace2.c
3e56cbd8 25) return MyError;
3e56cbd8 29) return MyError;
3e56cbd8 52) die("expect <exit_code>");
3e56cbd8 71) die("expect <exit_code>");
3e56cbd8 91) die("expect <error_message>");
3e56cbd8 141) return 0;
3e56cbd8 168) static int ut_005exec(int argc, const char **argv)
3e56cbd8 172) if (!argc)
3e56cbd8 173) return 0;
3e56cbd8 175) result = execv_git_cmd(argv);
3e56cbd8 176) return result;
3e56cbd8 185) die("%s", usage_error);
3e56cbd8 191) die("%s", usage_error);
3e56cbd8 223) static int print_usage(void)
3e56cbd8 228) fprintf(stderr, "usage:\n");
3e56cbd8 229) for_each_ut(k, ut_k) {
3e56cbd8 230) fprintf(stderr, "\t%s %s %s\n",
3e56cbd8 234) return 129;
3e56cbd8 271) return print_usage();

t/helper/test-xml-encode.c
b6fc0026 9) int cmd__xml_encode(int argc, const char **argv)
b6fc0026 11) unsigned char buf[1024], tmp[4], *tmp2 = NULL;
b6fc0026 12) ssize_t cur = 0, len = 1, remaining = 0;
b6fc0026 16) if (++cur == len) {
b6fc0026 17) len = xread(0, buf, sizeof(buf));
b6fc0026 18) if (!len)
b6fc0026 19) return 0;
b6fc0026 20) if (len < 0)
b6fc0026 21) die_errno("Could not read <stdin>");
b6fc0026 22) cur = 0;
b6fc0026 24) ch = buf[cur];
b6fc0026 26) if (tmp2) {
b6fc0026 27) if ((ch & 0xc0) != 0x80) {
b6fc0026 28) fputs(utf8_replace_character, stdout);
b6fc0026 29) tmp2 = 0;
b6fc0026 30) cur--;
b6fc0026 31) continue;
b6fc0026 33) *tmp2 = ch;
b6fc0026 34) tmp2++;
b6fc0026 35) if (--remaining == 0) {
b6fc0026 36) fwrite(tmp, tmp2 - tmp, 1, stdout);
b6fc0026 37) tmp2 = 0;
b6fc0026 39) continue;
b6fc0026 42) if (!(ch & 0x80)) {
b6fc0026 44) if (ch == '&')
b6fc0026 45) fputs("&amp;", stdout);
b6fc0026 46) else if (ch == '\'')
b6fc0026 47) fputs("&apos;", stdout);
b6fc0026 48) else if (ch == '"')
b6fc0026 49) fputs("&quot;", stdout);
b6fc0026 50) else if (ch == '<')
b6fc0026 51) fputs("&lt;", stdout);
b6fc0026 52) else if (ch == '>')
b6fc0026 53) fputs("&gt;", stdout);
b6fc0026 54) else if (ch >= 0x20)
b6fc0026 55) fputc(ch, stdout);
b6fc0026 56) else if (ch == 0x09 || ch == 0x0a || ch == 0x0d)
b6fc0026 57) fprintf(stdout, "&#x%02x;", ch);
b6fc0026 59) fputs(utf8_replace_character, stdout);
b6fc0026 60) } else if ((ch & 0xe0) == 0xc0) {
b6fc0026 62) tmp[0] = ch;
b6fc0026 63) remaining = 1;
b6fc0026 64) tmp2 = tmp + 1;
b6fc0026 65) } else if ((ch & 0xf0) == 0xe0) {
b6fc0026 67) tmp[0] = ch;
b6fc0026 68) remaining = 2;
b6fc0026 69) tmp2 = tmp + 1;
b6fc0026 70) } else if ((ch & 0xf8) == 0xf0) {
b6fc0026 72) tmp[0] = ch;
b6fc0026 73) remaining = 3;
b6fc0026 74) tmp2 = tmp + 1;
b6fc0026 76) fputs(utf8_replace_character, stdout);
b6fc0026 77) }

trace2.c
63ab7419 124) static void tr2main_signal_handler(int signo)
63ab7419 131) us_now = getnanotime() / 1000;
63ab7419 132) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 134) for_each_wanted_builtin(j, tgt_j) {
63ab7419 135) if (tgt_j->pfn_signal)
63ab7419 136) tgt_j->pfn_signal(us_elapsed_absolute, signo);
63ab7419 139) sigchain_pop(signo);
63ab7419 140) raise(signo);
63ab7419 141) }
63ab7419 149) return;
63ab7419 233) void trace2_cmd_path_fl(const char *file, int line, const char *pathname)
63ab7419 238) if (!trace2_enabled)
63ab7419 239) return;
63ab7419 241) for_each_wanted_builtin(j, tgt_j) {
63ab7419 242) if (tgt_j->pfn_command_path_fl)
63ab7419 243) tgt_j->pfn_command_path_fl(file, line, pathname);
63ab7419 275) for_each_wanted_builtin(j, tgt_j) {
63ab7419 276) if (tgt_j->pfn_command_subverb_fl)
63ab7419 277) tgt_j->pfn_command_subverb_fl(file, line,
63ab7419 291) for_each_wanted_builtin(j, tgt_j) {
63ab7419 292) if (tgt_j->pfn_alias_fl)
63ab7419 293) tgt_j->pfn_alias_fl(file, line, alias, argv);
63ab7419 311) tr2_cfg_set_fl(file, line, key, value);
63ab7419 357) us_elapsed_child = 0;
63ab7419 381) us_now = getnanotime() / 1000;
63ab7419 382) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 384) exec_id = tr2tls_locked_increment(&tr2_next_exec_id);
63ab7419 386) for_each_wanted_builtin(j, tgt_j) {
63ab7419 387) if (tgt_j->pfn_exec_fl)
63ab7419 388) tgt_j->pfn_exec_fl(file, line, us_elapsed_absolute,
63ab7419 392) return exec_id;
63ab7419 395) void trace2_exec_result_fl(const char *file, int line, int exec_id, int code)
63ab7419 402) if (!trace2_enabled)
63ab7419 403) return;
63ab7419 405) us_now = getnanotime() / 1000;
63ab7419 406) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 408) for_each_wanted_builtin(j, tgt_j) {
63ab7419 409) if (tgt_j->pfn_exec_result_fl)
63ab7419 410) tgt_j->pfn_exec_result_fl(file, line,
63ab7419 416) void trace2_thread_start_fl(const char *file, int line,
63ab7419 424) if (!trace2_enabled)
63ab7419 425) return;
63ab7419 427) if (tr2tls_is_main_thread())
63ab7419 438) trace2_region_enter_printf_fl(file, line, NULL, NULL, NULL,
63ab7419 441) return;
63ab7419 444) us_now = getnanotime() / 1000;
63ab7419 445) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 447) tr2tls_create_self(thread_name);
63ab7419 449) for_each_wanted_builtin(j, tgt_j) {
63ab7419 450) if (tgt_j->pfn_thread_start_fl)
63ab7419 451) tgt_j->pfn_thread_start_fl(file, line,
63ab7419 456) void trace2_thread_exit_fl(const char *file, int line)
63ab7419 464) if (!trace2_enabled)
63ab7419 465) return;
63ab7419 467) if (tr2tls_is_main_thread())
63ab7419 478) trace2_region_leave_printf_fl(file, line, NULL, NULL, NULL,
63ab7419 480) return;
63ab7419 483) us_now = getnanotime() / 1000;
63ab7419 484) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 491) tr2tls_pop_unwind_self();
63ab7419 492) us_elapsed_thread = tr2tls_region_elasped_self(us_now);
63ab7419 494) for_each_wanted_builtin(j, tgt_j) {
63ab7419 495) if (tgt_j->pfn_thread_exit_fl)
63ab7419 496) tgt_j->pfn_thread_exit_fl(file, line,
63ab7419 501) tr2tls_unset_self();
63ab7419 511) return;
63ab7419 529) return;
63ab7419 553) us_now = getnanotime() / 1000;
63ab7419 554) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 563) for_each_wanted_builtin(j, tgt_j) {
63ab7419 564) if (tgt_j->pfn_region_enter_printf_va_fl)
63ab7419 565) tgt_j->pfn_region_enter_printf_va_fl(
63ab7419 570) tr2tls_push_self(us_now);
63ab7419 628) us_now = getnanotime() / 1000;
63ab7419 629) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 637) us_elapsed_region = tr2tls_region_elasped_self(us_now);
63ab7419 639) tr2tls_pop_self();
63ab7419 645) for_each_wanted_builtin(j, tgt_j) {
63ab7419 646) if (tgt_j->pfn_region_leave_printf_va_fl)
63ab7419 647) tgt_j->pfn_region_leave_printf_va_fl(
63ab7419 708) return;
63ab7419 733) strbuf_addf(&buf_string, "%"PRIdMAX, value);
63ab7419 734) trace2_data_string_fl(file, line, category, repo, key, buf_string.buf);
63ab7419 735) strbuf_release(&buf_string);
63ab7419 738) void trace2_data_json_fl(const char *file, int line,
63ab7419 750) if (!trace2_enabled)
63ab7419 751) return;
63ab7419 753) us_now = getnanotime() / 1000;
63ab7419 754) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 755) us_elapsed_region = tr2tls_region_elasped_self(us_now);
63ab7419 757) for_each_wanted_builtin(j, tgt_j) {
63ab7419 758) if (tgt_j->pfn_data_fl)
63ab7419 759) tgt_j->pfn_data_json_fl(file, line, us_elapsed_absolute,
63ab7419 765) void trace2_printf_va_fl(const char *file, int line,
63ab7419 773) if (!trace2_enabled)
63ab7419 774) return;
63ab7419 776) us_now = getnanotime() / 1000;
63ab7419 777) us_elapsed_absolute = tr2tls_absolute_elapsed(us_now);
63ab7419 783) for_each_wanted_builtin(j, tgt_j) {
63ab7419 784) if (tgt_j->pfn_printf_va_fl)
63ab7419 785) tgt_j->pfn_printf_va_fl(file, line, us_elapsed_absolute,
63ab7419 790) void trace2_printf_fl(const char *file, int line,
63ab7419 795) va_start(ap, fmt);
63ab7419 796) trace2_printf_va_fl(file, line, fmt, ap);
63ab7419 797) va_end(ap);
63ab7419 798) }

trace2/tr2_cfg.c
63ab7419 21) return tr2_cfg_count_patterns;
63ab7419 33) strbuf_setlen(buf, buf->len - 1);
63ab7419 84) void tr2_cfg_set_fl(const char *file, int line,
63ab7419 87) struct tr2_cfg_data data = { file, line };
63ab7419 89) if (tr2_cfg_load_patterns() > 0)
63ab7419 90) tr2_cfg_cb(key, value, &data);

trace2/tr2_dst.c
63ab7419 27) dst->fd = STDERR_FILENO;
63ab7419 29) dst->fd = atoi(trace);
63ab7419 42) tr2_dst_trace_disable(dst);
63ab7419 48) warning("unknown trace value for '%s': %s\n"
63ab7419 52) tr2_dst_trace_disable(dst);
63ab7419 86) warning("unable to write trace for '%s': %s",
63ab7419 87) dst->env_var_name, strerror(errno));
63ab7419 88) tr2_dst_trace_disable(dst);

trace2/tr2_sid.c
63ab7419 27) return;
63ab7419 59) tr2_sid_compute();

trace2/tr2_tbuf.c
63ab7419 4) void tr2_tbuf_local_time(struct tr2_tbuf *tb)
63ab7419 10) gettimeofday(&tv, NULL);
63ab7419 11) secs = tv.tv_sec;
63ab7419 12) localtime_r(&secs, &tm);
63ab7419 14) xsnprintf(tb->buf, sizeof(tb->buf), "%02d:%02d:%02d.%06ld",
63ab7419 15)   tm.tm_hour, tm.tm_min, tm.tm_sec, (long)tv.tv_usec);
63ab7419 16) }

trace2/tr2_tgt_event.c
63ab7419 57) tr2env_event_nesting_wanted = want_nesting;
63ab7419 61) tr2env_event_brief = want_brief;
63ab7419 97)     !strcmp(event_name, "version") ||
63ab7419 98)     !strcmp(event_name, "atexit")) {
63ab7419 160) static void fn_signal(uint64_t us_elapsed_absolute, int signo)
63ab7419 162) const char *event_name = "signal";
63ab7419 163) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 164) double t_abs = (double)us_elapsed_absolute / 1000000.0;
63ab7419 166) jw_object_begin(&jw, 0);
63ab7419 167) event_fmt_prepare(event_name, __FILE__, __LINE__, NULL, &jw);
63ab7419 168) jw_object_double(&jw, "t_abs", 6, t_abs);
63ab7419 169) jw_object_intmax(&jw, "signo", signo);
63ab7419 170) jw_end(&jw);
63ab7419 172) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 173) jw_release(&jw);
63ab7419 174) }
63ab7419 209) if (fmt && *fmt) {
63ab7419 210) jw_object_string(jw, field_name, fmt);
63ab7419 211) return;
63ab7419 238) static void fn_command_path_fl(const char *file, int line,
63ab7419 241) const char *event_name = "cmd_path";
63ab7419 242) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 244) jw_object_begin(&jw, 0);
63ab7419 245) event_fmt_prepare(event_name, file, line, NULL, &jw);
63ab7419 246) jw_object_string(&jw, "path", pathname);
63ab7419 247) jw_end(&jw);
63ab7419 249) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 250) jw_release(&jw);
63ab7419 251) }
63ab7419 271) static void fn_command_subverb_fl(const char *file, int line,
63ab7419 274) const char *event_name = "cmd_subverb";
63ab7419 275) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 277) jw_object_begin(&jw, 0);
63ab7419 278) event_fmt_prepare(event_name, file, line, NULL, &jw);
63ab7419 279) jw_object_string(&jw, "name", command_subverb);
63ab7419 280) jw_end(&jw);
63ab7419 282) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 283) jw_release(&jw);
63ab7419 284) }
63ab7419 286) static void fn_alias_fl(const char *file, int line,
63ab7419 289) const char *event_name = "alias";
63ab7419 290) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 292) jw_object_begin(&jw, 0);
63ab7419 293) event_fmt_prepare(event_name, file, line, NULL, &jw);
63ab7419 294) jw_object_string(&jw, "alias", alias);
63ab7419 295) jw_object_inline_begin_array(&jw, "argv");
63ab7419 296) jw_array_argv(&jw, argv);
63ab7419 297) jw_end(&jw);
63ab7419 298) jw_end(&jw);
63ab7419 300) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 301) jw_release(&jw);
63ab7419 302) }
63ab7419 315) jw_object_string(&jw, "child_class", "hook");
63ab7419 316) jw_object_string(&jw, "hook_name", cmd->trace2_hook_name);
63ab7419 323) jw_object_string(&jw, "cd", cmd->dir);
63ab7419 327) jw_array_string(&jw, "git");
63ab7419 358) static void fn_thread_start_fl(const char *file, int line,
63ab7419 361) const char *event_name = "thread_start";
63ab7419 362) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 364) jw_object_begin(&jw, 0);
63ab7419 365) event_fmt_prepare(event_name, file, line, NULL, &jw);
63ab7419 366) jw_end(&jw);
63ab7419 368) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 369) jw_release(&jw);
63ab7419 370) }
63ab7419 372) static void fn_thread_exit_fl(const char *file, int line,
63ab7419 376) const char *event_name = "thread_exit";
63ab7419 377) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 378) double t_rel = (double)us_elapsed_thread / 1000000.0;
63ab7419 380) jw_object_begin(&jw, 0);
63ab7419 381) event_fmt_prepare(event_name, file, line, NULL, &jw);
63ab7419 382) jw_object_double(&jw, "t_rel", 6, t_rel);
63ab7419 383) jw_end(&jw);
63ab7419 385) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 386) jw_release(&jw);
63ab7419 387) }
63ab7419 389) static void fn_exec_fl(const char *file, int line,
63ab7419 393) const char *event_name = "exec";
63ab7419 394) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 396) jw_object_begin(&jw, 0);
63ab7419 397) event_fmt_prepare(event_name, file, line, NULL, &jw);
63ab7419 398) jw_object_intmax(&jw, "exec_id", exec_id);
63ab7419 399) if (exe)
63ab7419 400) jw_object_string(&jw, "exe", exe);
63ab7419 401) jw_object_inline_begin_array(&jw, "argv");
63ab7419 402) jw_array_argv(&jw, argv);
63ab7419 403) jw_end(&jw);
63ab7419 404) jw_end(&jw);
63ab7419 406) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 407) jw_release(&jw);
63ab7419 408) }
63ab7419 410) static void fn_exec_result_fl(const char *file, int line,
63ab7419 414) const char *event_name = "exec_result";
63ab7419 415) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 417) jw_object_begin(&jw, 0);
63ab7419 418) event_fmt_prepare(event_name, file, line, NULL, &jw);
63ab7419 419) jw_object_intmax(&jw, "exec_id", exec_id);
63ab7419 420) jw_object_intmax(&jw, "code", code);
63ab7419 421) jw_end(&jw);
63ab7419 423) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 424) jw_release(&jw);
63ab7419 425) }
63ab7419 458) static void fn_region_enter_printf_va_fl(const char *file, int line,
63ab7419 465) const char *event_name = "region_enter";
63ab7419 466) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
63ab7419 467) if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) {
63ab7419 468) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 470) jw_object_begin(&jw, 0);
63ab7419 471) event_fmt_prepare(
63ab7419 473) jw_object_intmax(&jw, "nesting", ctx->nr_open_regions);
63ab7419 474) if (category)
63ab7419 475) jw_object_string(&jw, "category", category);
63ab7419 476) if (label)
63ab7419 477) jw_object_string(&jw, "label", label);
63ab7419 478) maybe_add_string_va(&jw, "msg", fmt, ap);
63ab7419 479) jw_end(&jw);
63ab7419 481) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 482) jw_release(&jw);
63ab7419 484) }
63ab7419 486) static void fn_region_leave_printf_va_fl(const char *file, int line,
63ab7419 494) const char *event_name = "region_leave";
63ab7419 495) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
63ab7419 496) if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) {
63ab7419 497) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 498) double t_rel = (double)us_elapsed_region / 1000000.0;
63ab7419 500) jw_object_begin(&jw, 0);
63ab7419 501) event_fmt_prepare(event_name, file, line, repo, &jw);
63ab7419 502) jw_object_double(&jw, "t_rel", 6, t_rel);
63ab7419 503) jw_object_intmax(&jw, "nesting", ctx->nr_open_regions);
63ab7419 504) if (category)
63ab7419 505) jw_object_string(&jw, "category", category);
63ab7419 506) if (label)
63ab7419 507) jw_object_string(&jw, "label", label);
63ab7419 508) maybe_add_string_va(&jw, "msg", fmt, ap);
63ab7419 509) jw_end(&jw);
63ab7419 511) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 512) jw_release(&jw);
63ab7419 514) }
63ab7419 546) static void fn_data_json_fl(const char *file, int line,
63ab7419 554) const char *event_name = "data_json";
63ab7419 555) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
63ab7419 556) if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) {
63ab7419 557) struct json_writer jw = JSON_WRITER_INIT;
63ab7419 558) double t_abs = (double)us_elapsed_absolute / 1000000.0;
63ab7419 559) double t_rel = (double)us_elapsed_region / 1000000.0;
63ab7419 561) jw_object_begin(&jw, 0);
63ab7419 562) event_fmt_prepare(event_name, file, line, repo, &jw);
63ab7419 563) jw_object_double(&jw, "t_abs", 6, t_abs);
63ab7419 564) jw_object_double(&jw, "t_rel", 6, t_rel);
63ab7419 565) jw_object_intmax(&jw, "nesting", ctx->nr_open_regions);
63ab7419 566) jw_object_string(&jw, "category", category);
63ab7419 567) jw_object_string(&jw, "key", key);
63ab7419 568) jw_object_sub_jw(&jw, "value", value);
63ab7419 569) jw_end(&jw);
63ab7419 571) tr2_dst_write_line(&tr2dst_event, &jw.json);
63ab7419 572) jw_release(&jw);
63ab7419 574) }

trace2/tr2_tgt_normal.c
63ab7419 53) tr2_tbuf_local_time(&tb_now);
63ab7419 54) strbuf_addstr(buf, tb_now.buf);
63ab7419 55) strbuf_addch(buf, ' ');
63ab7419 57) if (file && *file)
63ab7419 58) strbuf_addf(buf, "%s:%d ", file, line);
63ab7419 59) while (buf->len < TR2FMT_NORMAL_FL_WIDTH)
63ab7419 60) strbuf_addch(buf, ' ');
63ab7419 106) static void fn_signal(uint64_t us_elapsed_absolute, int signo)
63ab7419 108) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 109) double elapsed = (double)us_elapsed_absolute / 1000000.0;
63ab7419 111) strbuf_addf(&buf_payload, "signal elapsed:%.6f code:%d",
63ab7419 113) normal_io_write_fl(__FILE__, __LINE__, &buf_payload);
63ab7419 114) strbuf_release(&buf_payload);
63ab7419 115) }
63ab7419 140) if (fmt && *fmt) {
63ab7419 141) strbuf_addstr(buf, fmt);
63ab7419 142) return;
63ab7419 157) static void fn_command_path_fl(const char *file, int line,
63ab7419 160) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 162) strbuf_addf(&buf_payload, "cmd_path %s", pathname);
63ab7419 163) normal_io_write_fl(file, line, &buf_payload);
63ab7419 164) strbuf_release(&buf_payload);
63ab7419 165) }
63ab7419 180) static void fn_command_subverb_fl(const char *file, int line,
63ab7419 183) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 185) strbuf_addf(&buf_payload, "cmd_subverb %s", command_subverb);
63ab7419 186) normal_io_write_fl(file, line, &buf_payload);
63ab7419 187) strbuf_release(&buf_payload);
63ab7419 188) }
63ab7419 190) static void fn_alias_fl(const char *file, int line, const char *alias,
63ab7419 193) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 195) strbuf_addf(&buf_payload, "alias %s ->", alias);
63ab7419 196) sq_quote_argv_pretty(&buf_payload, argv);
63ab7419 197) normal_io_write_fl(file, line, &buf_payload);
63ab7419 198) strbuf_release(&buf_payload);
63ab7419 199) }
63ab7419 201) static void fn_child_start_fl(const char *file, int line,
63ab7419 205) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 207) strbuf_addf(&buf_payload, "child_start[%d] ", cmd->trace2_child_id);
63ab7419 209) if (cmd->dir) {
63ab7419 210) strbuf_addstr(&buf_payload, " cd");
63ab7419 211) sq_quote_buf_pretty(&buf_payload, cmd->dir);
63ab7419 212) strbuf_addstr(&buf_payload, "; ");
63ab7419 220) if (cmd->git_cmd)
63ab7419 221) strbuf_addstr(&buf_payload, "git");
63ab7419 222) sq_quote_argv_pretty(&buf_payload, cmd->argv);
63ab7419 224) normal_io_write_fl(file, line, &buf_payload);
63ab7419 225) strbuf_release(&buf_payload);
63ab7419 226) }
63ab7419 228) static void fn_child_exit_fl(const char *file, int line,
63ab7419 233) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 234) double elapsed = (double)us_elapsed_child / 1000000.0;
63ab7419 236) strbuf_addf(&buf_payload, "child_exit[%d] pid:%d code:%d elapsed:%.6f",
63ab7419 238) normal_io_write_fl(file, line, &buf_payload);
63ab7419 239) strbuf_release(&buf_payload);
63ab7419 240) }
63ab7419 242) static void fn_exec_fl(const char *file, int line,
63ab7419 246) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 248) strbuf_addf(&buf_payload, "exec[%d] ", exec_id);
63ab7419 249) if (exe)
63ab7419 250) strbuf_addstr(&buf_payload, exe);
63ab7419 251) sq_quote_argv_pretty(&buf_payload, argv);
63ab7419 252) normal_io_write_fl(file, line, &buf_payload);
63ab7419 253) strbuf_release(&buf_payload);
63ab7419 254) }
63ab7419 256) static void fn_exec_result_fl(const char *file, int line,
63ab7419 260) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 262) strbuf_addf(&buf_payload, "exec_result[%d] code:%d", exec_id, code);
63ab7419 263) if (code > 0)
63ab7419 264) strbuf_addf(&buf_payload, " err:%s", strerror(code));
63ab7419 265) normal_io_write_fl(file, line, &buf_payload);
63ab7419 266) strbuf_release(&buf_payload);
63ab7419 267) }
63ab7419 269) static void fn_param_fl(const char *file, int line, const char *param,
63ab7419 272) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 274) strbuf_addf(&buf_payload, "def_param %s=%s", param, value);
63ab7419 275) normal_io_write_fl(file, line, &buf_payload);
63ab7419 276) strbuf_release(&buf_payload);
63ab7419 277) }
63ab7419 279) static void fn_repo_fl(const char *file, int line,
63ab7419 282) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 284) strbuf_addstr(&buf_payload, "worktree ");
63ab7419 285) sq_quote_buf_pretty(&buf_payload, repo->worktree);
63ab7419 286) normal_io_write_fl(file, line, &buf_payload);
63ab7419 287) strbuf_release(&buf_payload);
63ab7419 288) }
63ab7419 290) static void fn_printf_va_fl(const char *file, int line,
63ab7419 294) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 296) maybe_append_string_va(&buf_payload, fmt, ap);
63ab7419 297) normal_io_write_fl(file, line, &buf_payload);
63ab7419 298) strbuf_release(&buf_payload);
63ab7419 299) }

trace2/tr2_tgt_perf.c
63ab7419 83) tr2_tbuf_local_time(&tb_now);
63ab7419 84) strbuf_addstr(buf, tb_now.buf);
63ab7419 85) strbuf_addch(buf, ' ');
63ab7419 87) if (file && *file)
63ab7419 88) strbuf_addf(buf, "%s:%d ", file, line);
63ab7419 89) while (buf->len < TR2FMT_PERF_FL_WIDTH)
63ab7419 90) strbuf_addch(buf, ' ');
63ab7419 92) strbuf_addstr(buf, "| ");
63ab7419 102) strbuf_addf(buf, "r%d ", repo->trace2_repo_id);
63ab7419 125) strbuf_addf(buf, "%s", dots.buf);
63ab7419 126) len_indent -= dots.len;
63ab7419 192) static void fn_signal(uint64_t us_elapsed_absolute, int signo)
63ab7419 194) const char *event_name = "signal";
63ab7419 195) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 197) strbuf_addf(&buf_payload, "signo:%d", signo);
63ab7419 199) perf_io_write_fl(__FILE__, __LINE__, event_name, NULL,
63ab7419 202) strbuf_release(&buf_payload);
63ab7419 203) }
63ab7419 230) if (fmt && *fmt) {
63ab7419 231) strbuf_addstr(buf, fmt);
63ab7419 232) return;
63ab7419 250) static void fn_command_path_fl(const char *file, int line,
63ab7419 253) const char *event_name = "cmd_path";
63ab7419 254) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 256) strbuf_addstr(&buf_payload, pathname);
63ab7419 258) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 261) strbuf_release(&buf_payload);
63ab7419 262) }
63ab7419 281) static void fn_command_subverb_fl(const char *file, int line,
63ab7419 284) const char *event_name = "cmd_subverb";
63ab7419 285) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 287) strbuf_addstr(&buf_payload, command_subverb);
63ab7419 289) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 292) strbuf_release(&buf_payload);
63ab7419 293) }
63ab7419 295) static void fn_alias_fl(const char *file, int line, const char *alias,
63ab7419 298) const char *event_name = "alias";
63ab7419 299) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 301) strbuf_addf(&buf_payload, "alias:%s argv:", alias);
63ab7419 302) sq_quote_argv_pretty(&buf_payload, argv);
63ab7419 304) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 307) strbuf_release(&buf_payload);
63ab7419 308) }
63ab7419 318) strbuf_addf(&buf_payload, "[ch%d] class:hook hook:%s",
63ab7419 328) strbuf_addstr(&buf_payload, " cd:");
63ab7419 329) sq_quote_buf_pretty(&buf_payload, cmd->dir);
63ab7419 334) strbuf_addstr(&buf_payload, " git");
63ab7419 359) static void fn_thread_start_fl(const char *file, int line,
63ab7419 362) const char *event_name = "thread_start";
63ab7419 363) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 365) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 368) strbuf_release(&buf_payload);
63ab7419 369) }
63ab7419 371) static void fn_thread_exit_fl(const char *file, int line,
63ab7419 375) const char *event_name = "thread_exit";
63ab7419 376) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 378) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 381) strbuf_release(&buf_payload);
63ab7419 382) }
63ab7419 384) static void fn_exec_fl(const char *file, int line,
63ab7419 388) const char *event_name = "exec";
63ab7419 389) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 391) strbuf_addf(&buf_payload, "id:%d ", exec_id);
63ab7419 392) strbuf_addstr(&buf_payload, "argv:");
63ab7419 393) if (exe)
63ab7419 394) strbuf_addf(&buf_payload, " %s", exe);
63ab7419 395) sq_quote_argv_pretty(&buf_payload, argv);
63ab7419 397) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 400) strbuf_release(&buf_payload);
63ab7419 401) }
63ab7419 403) static void fn_exec_result_fl(const char *file, int line,
63ab7419 407) const char *event_name = "exec_result";
63ab7419 408) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 410) strbuf_addf(&buf_payload, "id:%d code:%d", exec_id, code);
63ab7419 411) if (code > 0)
63ab7419 412) strbuf_addf(&buf_payload, " err:%s", strerror(code));
63ab7419 414) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 417) strbuf_release(&buf_payload);
63ab7419 418) }
63ab7419 420) static void fn_param_fl(const char *file, int line,
63ab7419 423) const char *event_name = "def_param";
63ab7419 424) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 426) strbuf_addf(&buf_payload, "%s:%s", param, value);
63ab7419 428) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 431) strbuf_release(&buf_payload);
63ab7419 432) }
63ab7419 434) static void fn_repo_fl(const char *file, int line,
63ab7419 437) const char *event_name = "def_repo";
63ab7419 438) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 440) strbuf_addstr(&buf_payload, "worktree:");
63ab7419 441) sq_quote_buf_pretty(&buf_payload, repo->worktree);
63ab7419 443) perf_io_write_fl(file, line, event_name, repo,
63ab7419 446) strbuf_release(&buf_payload);
63ab7419 447) }
63ab7419 449) static void fn_region_enter_printf_va_fl(const char *file, int line,
63ab7419 456) const char *event_name = "region_enter";
63ab7419 457) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 459) if (label)
63ab7419 460) strbuf_addf(&buf_payload, "label:%s ", label);
63ab7419 461) maybe_append_string_va(&buf_payload, fmt, ap);
63ab7419 463) perf_io_write_fl(file, line, event_name, repo,
63ab7419 466) strbuf_release(&buf_payload);
63ab7419 467) }
63ab7419 469) static void fn_region_leave_printf_va_fl(const char *file, int line,
63ab7419 477) const char *event_name = "region_leave";
63ab7419 478) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 480) if (label)
63ab7419 481) strbuf_addf(&buf_payload, "label:%s ", label);
63ab7419 482) maybe_append_string_va(&buf_payload, fmt, ap);
63ab7419 484) perf_io_write_fl(file, line, event_name, repo,
63ab7419 487) strbuf_release(&buf_payload);
63ab7419 488) }
63ab7419 490) static void fn_data_fl(const char *file, int line,
63ab7419 498) const char *event_name = "data";
63ab7419 499) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 501) strbuf_addf(&buf_payload, "%s:%s", key, value);
63ab7419 503) perf_io_write_fl(file, line, event_name, repo,
63ab7419 506) strbuf_release(&buf_payload);
63ab7419 507) }
63ab7419 509) static void fn_data_json_fl(const char *file, int line,
63ab7419 517) const char *event_name = "data_json";
63ab7419 518) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 520) strbuf_addf(&buf_payload, "%s:%s", key, value->json.buf);
63ab7419 522) perf_io_write_fl(file, line, event_name, repo,
63ab7419 525) strbuf_release(&buf_payload);
63ab7419 526) }
63ab7419 528) static void fn_printf_va_fl(const char *file, int line,
63ab7419 532) const char *event_name = "printf";
63ab7419 533) struct strbuf buf_payload = STRBUF_INIT;
63ab7419 535) maybe_append_string_va(&buf_payload, fmt, ap);
63ab7419 537) perf_io_write_fl(file, line, event_name, NULL,
63ab7419 540) strbuf_release(&buf_payload);
63ab7419 541) }

trace2/tr2_tls.c
63ab7419 38) strbuf_addf(&ctx->thread_name, "th%02d:", ctx->thread_id);
63ab7419 41) strbuf_setlen(&ctx->thread_name, TR2_MAX_THREAD_NAME);
63ab7419 58) ctx = tr2tls_create_self("unknown");
63ab7419 63) int tr2tls_is_main_thread(void)
63ab7419 65) struct tr2tls_thread_ctx * ctx = pthread_getspecific(tr2tls_key);
63ab7419 67) return ctx == tr2tls_thread_main;
63ab7419 82) void tr2tls_push_self(uint64_t us_now)
63ab7419 84) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
63ab7419 86) ALLOC_GROW(ctx->array_us_start, ctx->nr_open_regions + 1, ctx->alloc);
63ab7419 87) ctx->array_us_start[ctx->nr_open_regions++] = us_now;
63ab7419 88) }
63ab7419 90) void tr2tls_pop_self(void)
63ab7419 92) struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
63ab7419 94) if (!ctx->nr_open_regions)
63ab7419 95) BUG("no open regions in thread '%s'", ctx->thread_name.buf);
63ab7419 97) ctx->nr_open_regions--;
63ab7419 98) }
63ab7419 105) tr2tls_pop_self();
63ab7419 115) return 0;
63ab7419 125) return 0;

utf8.c
76759c7d 553) return NULL;

wrapper.c
5efde212 70) die("Out of memory, malloc failed (tried to allocate %" PRIuMAX " bytes)",
5efde212 73) error("Out of memory, malloc failed (tried to allocate %" PRIuMAX " bytes)",

Commits introducting uncovered code:
Ævar Arnfjörð Bjarmason	6a83d902 coccinelle: make use of the "type" FREE_AND_NULL() rule
Alban Gruin	febebd99 sequencer: refactor rearrange_squash() to work on a todo_list
Alban Gruin	c27b32f0 sequencer: refactor check_todo_list() to work on a todo_list
Alban Gruin	4d55dfd7 rebase-interactive: move transform_todo_file() to rebase--interactive.c
Alban Gruin	8414c890 sequencer: refactor sequencer_add_exec_commands() to work on a todo_list
Alban Gruin	e5b1c9d9 rebase-interactive: rewrite edit_todo_list() to handle the initial edit
Anders Waldenborg	4681fe38 pretty: allow showing specific trailers
Anders Waldenborg	b755bf6f pretty: allow %(trailers) options with explicit value
Barret Rhoden	07d04b91 blame: add a config option to mark ignored lines
Barret Rhoden	e7973c85 blame: add the ability to ignore commits and their changes
Barret Rhoden	ef644c41 Move init_skiplist() outside of fsck
Brandon Williams	373d70ef protocol: introduce protocol extension mechanisms
Brandon Williams	0f1dc53f remote-curl: implement stateless-connect command
Brian Gianforcaro	eeefa7c9 Style fixes, add a space after if/for/while.
brian m. carlson	6390fe20 pack-redundant: convert linked lists to use struct object_id
Charles Bailey	2a514ed8 parse-options: move unsigned long option parsing out of pack-objects.c
David Turner	d1dd94b3 Do not print 'dangling' for cat-file in case of ambiguity
Derrick Stolee	4f6d26b1 list-objects: consume sparse tree walk
Derrick Stolee	d5d2e935 revision: implement sparse algorithm
Derrick Stolee	f1f5de44 revision: add mark_tree_uninteresting_sparse
Eugene Letuchy	31653c1a Make git blame's date output format configurable, like git log
Jeff Hostetler	3e56cbd8 trace2: t/helper/test-trace2, t0210.sh, t0211.sh, t0212.sh
Jeff Hostetler	63ab7419 trace2: create new combined trace facility
Jeff Hostetler	603036d9 trace2:data: add editor/pager child classification
Jeff King	01f8d594 prefer "hash mismatch" to "sha1 mismatch"
Jeff King	34a9469d remote-curl: refactor smart-http discovery
Jeff King	76011357 sha1-file: prefer "loose object file" to "sha1 file" in messages
Jeff King	2c319886 sha1-file: avoid "sha1 file" for generic use in messages
Jeff King	dd63f169 move "--follow needs one pathspec" rule to diff_setup_done
Jeff King	246f0ede execv_dashed_external: stop exiting with negative code
Jeff King	a5481a6c convert "enum date_mode" into a struct
Jeff Smith	b543bb1c blame: move scoreboard-related methods to libgit
Jiang Xin	cb7e0336 pack-redundant: rename pack_list.all_objects
Joel Teichroeb	f6bbd781 stash: convert apply to builtin
Joel Teichroeb	cdca49bc stash: convert drop and clear to builtin
Joel Teichroeb	e1d01876 stash: convert pop to builtin
Johannes Schindelin	5f1a63e0 Read configuration also from $HOME/.gitconfig
Johannes Schindelin	3546c8d9 rebase -i: also expand/collapse the SHA-1s via the rebase--helper
Johannes Schindelin	d04fa788 ci: parallelize testing on Windows
Johannes Schindelin	dc2d9ba3 is_{hfs,ntfs}_dotgitmodules: add tests
Johannes Schindelin	a5c09131 tests: avoid calling Perl just to determine file sizes
Johannes Schindelin	cdac2b01 rebase -i: skip unnecessary picks using the rebase--helper
Johannes Schindelin	2987e8cd tests: include detailed trace logs with --write-junit-xml upon failure
Johannes Schindelin	b6fc0026 tests: optionally write results as JUnit-style .xml
Johannes Schindelin	033abf97 Replace all die("BUG: ...") calls by BUG() ones
Johannes Schindelin	26799a20 stash: optionally use the scripted version again
Johannes Schindelin	bec65d5b tests: add a special setup where stash.useBuiltin is off
Johannes Sixt	0ac77ec3 run_command: report system call errors instead of returning error codes
Jonathan Nieder	7d29afd4 i18n: mark relative dates for translation
Jonathan Nieder	309be813 update-index: migrate to parse-options API
Jonathan Nieder	1e5ce570 parse-options: clearer reporting of API misuse
Josh Steadmon	6da1f1a9 protocol: advertise multiple supported versions
Junio C Hamano	93c1e079 config-set: check write-in-full returns in set_multivar
Junio C Hamano	9409c7a5 config: "git config baa" should exit with status 1
Junio C Hamano	af465af8 parse-options: detect attempt to add a duplicate short option name
Liam Beguin	0cce4a27 rebase -i -x: add exec commands via the rebase--helper
Linus Torvalds	acdd3776 Add 'human' date format
Lukas_Sandström	1c3039e8 Make git-pack-redundant consider alt-odbs
Martin Koegler	5efde212 zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy	a12c1ff3 config: factor out set_config_source_file()
Nguyễn Thái Ngọc Duy	1d28ff4c builtin/config.c: mark more strings for translation
Nguyễn Thái Ngọc Duy	a92ec7ef parse-options: fix SunCC compiler warning
Nguyễn Thái Ngọc Duy	f62470c6 parse-options: add OPT_BITOP()
Nguyễn Thái Ngọc Duy	b221b5ab completion: collapse extra --no-.. options
Nguyễn Thái Ngọc Duy	8f7c7f55 config.c: add repo_config_set_worktree_gently()
Nguyễn Thái Ngọc Duy	ebc4a04e remote: force completing --mirror= instead of --mirror
Nguyễn Thái Ngọc Duy	b9d7f4b4 parse-options: support --git-completion-helper
Nguyễn Thái Ngọc Duy	3ebbe289 parse-options: allow ll_callback with OPTION_CALLBACK
Nguyễn Thái Ngọc Duy	aad6fddb connect.c: mark more strings for translation
Nguyễn Thái Ngọc Duy	8aa8c140 git.c: mark more strings for translation
Nguyễn Thái Ngọc Duy	d473e2e0 diff.c: convert -U|--unified
Paul-Sebastian Ungureanu	bfc3fe33 strbuf.c: add `strbuf_insertf()` and `strbuf_vinsertf()`
Paul-Sebastian Ungureanu	9a95010a stash: make push -q quiet
Paul-Sebastian Ungureanu	847eb0b0 stash: convert store to builtin
Paul-Sebastian Ungureanu	fa38428f stash: convert push to builtin
Paul-Sebastian Ungureanu	1f5a011d stash: convert create to builtin
Paul-Sebastian Ungureanu	b4493f26 stash: convert show to builtin
Paul-Sebastian Ungureanu	51809c70 stash: convert `stash--helper.c` into `stash.c`
Peter Krefting	78bde923 i18n: read-cache: typofix
Pierre Habouzit	5817da01 git-blame: migrate to incremental parse-option [1/2]
Pratik Karki	c54dacb5 builtin rebase: start a new rebase only if none is in progress
Stefan Beller	c553c72e run-command: add an asynchronous parallel child processor
Stefan Xenos	9e98e9b6 sha1-array: implement oid_array_readonly_contains()
Stefan Xenos	73f8829d evolve: implement the 'git change' command
Stefan Xenos	6b8678e5 evolve: add support for writing metacommits
Stefan Xenos	287a8679 evolve: add the change-table structure
Stefan Xenos	49854277 evolve: add the 'git change list' command
Stefan Xenos	6930f34d evolve: add support for parsing metacommits
Stephen Boyd	df217ed6 parse-opts: add OPT_FILENAME and transition builtins
Takashi Iwai	507d7804 pager: don't use unsafe functions in signal handlers
Timo Hirvonen	bd22c904 Fix sparse warnings
Torsten Bögershausen	76759c7d git on Mac OS and precomposed unicode


Uncovered code in 'jch' not in 'next'
--------------------------------------------------------

builtin/add.c
9472935d 140) continue;

builtin/am.c
7ff26832 1834) write_index_patch(state);

builtin/archive.c
01f9ec64 63) if (starts_with(reader.line, "NACK "))
01f9ec64 64) die(_("git archive: NACK %s"), reader.line + 5);

builtin/bisect--helper.c
ecb3f373 111) return error(_("please use two different terms"));
ecb3f373 118) return error_errno(_("could not open the file BISECT_TERMS"));
5e82c3dd 162) if (get_oid_commit(commit, &oid))
5e82c3dd 163) return error(_("'%s' is not a valid commit"), commit);
5e82c3dd 164) strbuf_addstr(&branch, commit);
5e82c3dd 172) strbuf_release(&branch);
5e82c3dd 173) argv_array_clear(&argv);
5e82c3dd 174) return error(_("could not check out original"
0f30233a 215) retval = error(_("Bad bisect_write argument: %s"), state);
0f30233a 216) goto finish;
0f30233a 220) retval = error(_("couldn't get the oid of the rev '%s'"), rev);
0f30233a 221) goto finish;
0f30233a 226) retval = -1;
0f30233a 227) goto finish;
0f30233a 232) retval = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
0f30233a 233) goto finish;
129a6cf3 329) yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
129a6cf3 330) if (starts_with(yesno, "N") || starts_with(yesno, "n"))
129a6cf3 331) retval = -1;
129a6cf3 332) goto finish;
129a6cf3 338) retval = error(_(need_bisect_start_warning),
450ebb73 389) return error(_("invalid argument %s for 'git bisect terms'.\n"
06f5608c 404) return -1;
06f5608c 407) retval = -1;
06f5608c 408) goto finish;
06f5608c 413) retval = -1;
06f5608c 452) no_checkout = 1;
06f5608c 474)  !one_of(arg, "--term-good", "--term-bad", NULL)) {
06f5608c 475) return error(_("unrecognized option: '%s'"), arg);
06f5608c 510) if (get_oid("HEAD", &head_oid))
06f5608c 511) return error(_("bad HEAD - I need a HEAD"));
06f5608c 526) retval = error(_("checking out '%s' failed."
06f5608c 547) return error(_("won't bisect on cg-seek'ed tree"));
06f5608c 550) return error(_("bad HEAD - strange symbolic ref"));
06f5608c 558) return -1;
06f5608c 576) retval = -1;
06f5608c 577) goto finish;

builtin/branch.c
0ecb1fc7 460) die(_("could not resolve HEAD"));

builtin/commit.c
b64c1e07 739) die_errno(_("could not read SQUASH_MSG"));
8a6179bc 746) die_errno(_("could not read MERGE_MSG"));

builtin/diff-tree.c
ff7fe37b 168) if (!the_index.cache)

builtin/merge.c
66f4b98a 797) error("%s", err_msg);
62dc42b9 819) BUG("the control must not reach here under --squash");

builtin/notes.c
033abf97 556) BUG("combine_notes_overwrite failed");

builtin/pack-objects.c
ac77d0c3 2008) die(_("unable to parse object header of %s"),
ca473cef 2081) die(_("object %s inconsistent object length (%"PRIuMAX" vs %"PRIuMAX")"),
f616db6a 2094) warning(_("object %s cannot be read"),

builtin/pull.c
11b6d178 642) argv_array_push(&args, opt_squash);

builtin/rebase.c
21853626 259) write_file(state_dir_path("verbose", opts), "%s", "");
21853626 261) write_file(state_dir_path("strategy", opts), "%s",
21853626 264) write_file(state_dir_path("strategy_opts", opts), "%s",
21853626 271) write_file(state_dir_path("gpg_sign_opt", opts), "%s",
21853626 274) write_file(state_dir_path("strategy", opts), "--signoff");
c5233708 394) BUG("Not a fully qualified branch: '%s'", switch_to_branch);
c5233708 397) ret = -1;
c5233708 398) goto leave_reset_head;
c5233708 402) ret = error(_("could not determine HEAD revision"));
c5233708 403) goto leave_reset_head;
c5233708 424) ret = error(_("could not read index"));
c5233708 425) goto leave_reset_head;
c5233708 429) ret = error(_("failed to find tree of %s"),
c5233708 431) goto leave_reset_head;
c5233708 435) ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
c5233708 436) goto leave_reset_head;
c5233708 448) ret = error(_("could not write index"));
c5233708 449) goto leave_reset_head;
c5233708 467) } else if (old_orig)
c5233708 468) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
122420c2 1268) exit(1);

builtin/receive-pack.c
01f9ec64 1587)     reader->line + 8);
a85b377d 1617) true_flush = 1;
01f9ec64 1621) die("protocol error: got an unexpected packet");

builtin/remote.c
f39a9c65 1575) die(_("--save-to-push can only be used when only one url is defined"));

commit-graph.c
aa658574 127) return NULL;
aa658574 130) return NULL;
cce99cd8 562) BUG("missing parent %s for commit %s",
4f5b532d 882) die(_("error adding pack %s"), packname.buf);
4f5b532d 884) die(_("error opening index for %s"), packname.buf);

config.c
7e43b32b 1488) return git_ident_config(var, value, cb);
7e43b32b 1491) return git_ident_config(var, value, cb);

fetch-pack.c
01f9ec64 154) die(_("git fetch-pack: expected a flush packet after shallow list"));
1dd73e20 256) die(_("--stateless-rpc requires multi_ack_detailed"));
01f9ec64 364) die(_("invalid unshallow line: %s"), reader.line);

http-walker.c
514c5fdd 550) loose_object_path(the_repository, &buf, &req->oid);

ident.c
862e80a4 385) fputs(_(env_hint), stderr);
d6991cee 491) int author_ident_sufficiently_given(void)
d6991cee 493) return ident_is_sufficient(author_ident_explicitly_given);
7e43b32b 504) if (!value)
7e43b32b 505) return config_error_nonbool(var);
7e43b32b 506) strbuf_reset(&git_author_name);
7e43b32b 507) strbuf_addstr(&git_author_name, value);
7e43b32b 508) author_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b 509) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b 510) return 0;
7e43b32b 514) if (!value)
7e43b32b 515) return config_error_nonbool(var);
7e43b32b 516) strbuf_reset(&git_author_email);
7e43b32b 517) strbuf_addstr(&git_author_email, value);
7e43b32b 518) author_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b 519) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b 520) return 0;

merge-recursive.c
c43ba42e 436) fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce),
19c6a4f8 437) (int)ce_namelen(ce), ce->name);
033abf97 439) BUG("unmerged index entries in merge-recursive.c");
9047ebbc 728) return -1;
6003303a 925) if (status == SCLD_EXISTS)
18cfc088 1206) return 0;
73118f89 3632) return NULL;
d90e759f 3655)    oid_to_hex(base_list[i]));

midx.c
3c9e7185 817) drop_index++;
3c9e7185 818) missing_drops++;
3c9e7185 819) i--;
3c9e7185 826) result = 1;
3c9e7185 827) goto cleanup;
cc6af73c 1053) midx_report(_("failed to load pack-index for packfile %s"),
cc6af73c 1054)     e.p->pack_name);
cc6af73c 1055) break;
3c9e7185 1079) return 0;
3c9e7185 1094) continue;
467ae6f9 1133) return 0;
19c239d4 1148) return 0;
19c239d4 1157) continue;
19c239d4 1170) continue;

packfile.c
91336887 369) strbuf_release(&buf);
91336887 370) return;

pkt-line.c
bb643d8b 436) strbuf_setlen(sb_out, orig_len);
0bbc0bc5 505) if (demultiplex_sideband(reader->me, reader->buffer,
0bbc0bc5 508) break;
0bbc0bc5 509) }

read-cache.c
ee70c128 1736) advise(_("This is likely due to the file having been written by a newer\n"
bad68ec9 1745) break;

ref-filter.c
74efea94 448) return strbuf_addf_ret(err, -1, _("unrecognized %%(if) argument: %s"), arg);
6ccd3780 467) return 0;

remote-curl.c
01f9ec64 439) }

repository.c
359efeff 168) goto error;

send-pack.c
01f9ec64 143) return error(_("unable to parse remote unpack status: %s"), reader->line);
01f9ec64 162) error("invalid ref status from remote: %s", reader->line);

sequencer.c
d0aaa46f 1020) eol = sb->len;
66618a50 1409) goto out;
9055e401 2992) error("%s", err.buf);
2b6ad0f4 3291) goto leave_merge;

sha1-file.c
d21f8426 1084) return -1;
514c5fdd 1291) status = error(_("unable to parse %s header"), oid_to_hex(oid));
00a7760e 2305) the_hash_algo->final_fn(real_oid.hash, &c);
f6371f92 2309) return -1;
f6371f92 2344) goto out;

sideband.c
fbd76cd4 128) suffix = ANSI_SUFFIX;
fbd76cd4 138) strbuf_addf(scratch,
fbd76cd4 140)     scratch->len ? "\n" : "", me);
fbd76cd4 141) *sideband_type = SIDEBAND_PROTOCOL_ERROR;
fbd76cd4 142) goto cleanup;
0bbc0bc5 150) die("remote error: %s", buf + 1);
fbd76cd4 195) strbuf_addf(scratch, "%s%s: protocol error: bad band #%d",
fbd76cd4 196)     scratch->len ? "\n" : "", me, band);
fbd76cd4 197) *sideband_type = SIDEBAND_PROTOCOL_ERROR;
fbd76cd4 198) break;
0bbc0bc5 203) die("%s", scratch->buf);

upload-pack.c
10ac85c7 881) die("git upload-pack: filtering capability not negotiated");
05e95155 1059) if (!keepalive)
05e95155 1060) keepalive = -1;
685fbd32 1291) continue;

worktree.c
e0c4a731 465) clear_repository_format(&format);

wrapper.c
e3b1e3bd 701) die_errno(_("could not stat %s"), filename);

Commits introducting uncovered code:
Ævar Arnfjörð Bjarmason	8a6179bc i18n: git-commit basic messages
Brandon Williams	685fbd32 fetch-pack: perform a fetch using v2
Brandon Williams	359efeff repository: introduce the repository object
Daniels Umanovskis	0ecb1fc7 branch: introduce --show-current display option
Denton Liu	f39a9c65 remote: add --save-to-push option to git remote set-url
Derrick Stolee	467ae6f9 multi-pack-index: prepare 'repack' subcommand
Derrick Stolee	cce99cd8 commit-graph: writing missing parents is a BUG
Derrick Stolee	3c9e7185 multi-pack-index: implement 'expire' subcommand
Derrick Stolee	91336887 repack: refactor pack deletion for future use
Derrick Stolee	19c239d4 midx: implement midx_repack()
Derrick Stolee	cc6af73c multi-pack-index: verify object offsets
Elijah Newren	c43ba42e merge-recursive: Make BUG message more legible by adding a newline
Elijah Newren	d90e759f merge-recursive: fix numerous argument alignment issues
Jay Soffian	66f4b98a Teach merge the '[-e|--edit]' option
Jeff Hostetler	10ac85c7 upload-pack: add object filtering for partial clone
Jeff King	d6991cee ident: keep separate "explicit" flags for author and committer
Jeff King	862e80a4 ident: handle NULL email when complaining of empty name
Jeff King	00a7760e sha1-file: modernize loose header/stream functions
Jeff King	f6371f92 sha1_file: add read_loose_object() function
Jeff King	05e95155 upload-pack: send keepalive packets during pack computation
Jeff King	514c5fdd sha1-file: modernize loose object file functions
Johannes Schindelin	2b6ad0f4 rebase --rebase-merges: add support for octopus merges
Johannes Schindelin	21853626 built-in rebase: call `git am` directly
Johannes Schindelin	c5233708 rebase: move `reset_head()` into a better spot
Johannes Schindelin	9055e401 sequencer: introduce new commands to reset the revision
Johannes Schindelin	6003303a merge-recursive: switch to returning errors instead of dying
Johannes Schindelin	033abf97 Replace all die("BUG: ...") calls by BUG() ones
Jonathan Nieder	ee70c128 index: offer advice for unknown index extensions
Jonathan Tan	fbd76cd4 sideband: reverse its dependency on pkt-line
Jonathan Tan	0bbc0bc5 {fetch,upload}-pack: sideband v2 fetch response
Josh Steadmon	aa658574 commit-graph, fuzz: add fuzzer for commit-graph
Junio C Hamano	19c6a4f8 merge-recursive: do not return NULL only to cause segfault
Junio C Hamano	bad68ec9 index: make the index file format extensible.
Junio C Hamano	a85b377d push: the beginning of "git push --signed"
Junio C Hamano	d21f8426 unpack_sha1_header(): detect malformed object header
Lars Schneider	bb643d8b pkt-line: add functions to read/write flush terminated packet streams
Martin Ågren	e0c4a731 setup: fix memory leaks with `struct repository_format`
Masaya Suzuki	01f9ec64 Use packet_reader instead of packet_read_line
Michael J Gruber	62dc42b9 merge: clarify call chain
Miklos Vajna	9047ebbc Split out merge_recursive() to merge-recursive.c
Nguyễn Thái Ngọc Duy	f616db6a builtin/pack-objects.c: mark more strings for translation
Nguyễn Thái Ngọc Duy	4f5b532d commit-graph.c: mark more strings for translation
Nguyễn Thái Ngọc Duy	1dd73e20 fetch-pack.c: mark strings for translating
Nguyễn Thái Ngọc Duy	ac77d0c3 pack-objects: shrink size field in struct object_entry
Nguyễn Thái Ngọc Duy	ff7fe37b diff.c: move read_index() code back to the caller
Nickolai Belakovski	6ccd3780 ref-filter: add worktreepath atom
Olga Telezhnaya	74efea94 ref-filter: add return value to parsers
Paul Tan	7ff26832 builtin-am: implement -i/--interactive
Paul Tan	11b6d178 pull: pass git-merge's options to git-merge
Phillip Wood	d0aaa46f commit: move empty message checks to libgit
Phillip Wood	66618a50 sequencer: run 'prepare-commit-msg' hook
Pranit Bauva	e3b1e3bd wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()
Pranit Bauva	06f5608c bisect--helper: `bisect_start` shell function partially in C
Pranit Bauva	450ebb73 bisect--helper: `get_terms` & `bisect_terms` shell function in C
Pranit Bauva	129a6cf3 bisect--helper: `bisect_next_check` shell function in C
Pranit Bauva	0f30233a bisect--helper: `bisect_write` shell function in C
Pranit Bauva	5e82c3dd bisect--helper: `bisect_reset` shell function in C
Pranit Bauva	ecb3f373 bisect--helper: `write_terms` shell function in C
Pratik Karki	122420c2 builtin rebase: support --skip
Stefan Beller	18cfc088 submodule.c: move submodule merging to merge-recursive.c
Stephan Beyer	73118f89 merge-recursive.c: Add more generic merge_recursive_generic()
Sven Strickroth	b64c1e07 commit: do not lose SQUASH_MSG contents
Torsten Bögershausen	ca473cef Upcast size_t variables to uintmax_t when printing
Torsten Bögershausen	9472935d add: introduce "--renormalize"
William Hubbs	7e43b32b Add author and committer configuration settings


Uncovered code in 'next' not in 'master'
--------------------------------------------------------

builtin/checkout.c

builtin/fetch-pack.c
4316ff30 226) get_remote_refs(fd[1], &reader, &ref, 0, NULL, NULL);

builtin/fetch.c
3390e42a 1200) warning("Ignoring --negotiation-tip because the protocol does not support it.");
aa57b871 1481) return;

builtin/grep.c
f9ee2fcd 428) return 0;

builtin/rebase.c
ba1905a5 1221) die(_("--strategy requires --merge or --interactive"));
d421afa0 1258) die(_("--reschedule-failed-exec requires an interactive rebase"));

commit-reach.c
5227c385 326) return ret;

commit.c

diff.c
b73bcbac 308) ret = 0;
21536d07 812)        (s[off] == '\r' && off < len - 1))
21536d07 813) off++;

entry.c
536ec183 450) BUG("Can't remove entry to a path");
12dccc16 517) return 0;

fetch-pack.c
f7e20501 1125) die(_("Server does not support shallow requests"));
f7e20501 1267) die(_("error in object: %s"), reader->line);
f7e20501 1269) die(_("no shallow found: %s"), reader->line);

hex.c
47edb649 93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb649 95) return hash_to_hex_algop_r(buffer, sha1, &hash_algos[GIT_HASH_SHA1]);
47edb649 116) char *hash_to_hex(const unsigned char *hash)

http-push.c
ea82b2a0 1314) p = process_tree(lookup_tree(the_repository, &entry.oid),

http.c
e6cf87b1 1999) if (fflush(result)) {
e6cf87b1 2000) error_errno("unable to flush a file");
e6cf87b1 2001) return HTTP_START_FAILED;
e6cf87b1 2004) if (ftruncate(fileno(result), 0) < 0) {
e6cf87b1 2005) error_errno("unable to truncate a file");
e6cf87b1 2006) return HTTP_START_FAILED;
e6cf87b1 2008) break;
e6cf87b1 2010) BUG("Unknown http_request target");

list-objects-filter.c
bc5975d2 147) BUG("unknown filter_situation: %d", filter_situation);

pretty.c
ad6f028f 1204) return 0;

remote-curl.c
b79bdd8c 566) return size;

sha1-file.c
ac73cedf 114) static void git_hash_unknown_final(unsigned char *hash, git_hash_ctx *ctx)
1a07e59c 116) BUG("trying to finalize unknown hash");
024aa469 1358) return -1;
ee1c6c34 1766) return 0;

t/helper/test-hash-speed.c
37649b7f 6) static inline void compute_hash(const struct git_hash_algo *algo, git_hash_ctx *ctx, uint8_t *final, const void *p, size_t len)
37649b7f 8) algo->init_fn(ctx);
37649b7f 9) algo->update_fn(ctx, p, len);
37649b7f 10) algo->final_fn(final, ctx);
37649b7f 11) }
37649b7f 13) int cmd__hash_speed(int ac, const char **av)
37649b7f 18) unsigned bufsizes[] = { 64, 256, 1024, 8192, 16384 };
37649b7f 21) const struct git_hash_algo *algo = NULL;
37649b7f 23) if (ac == 2) {
37649b7f 24) for (i = 1; i < GIT_HASH_NALGOS; i++) {
37649b7f 25) if (!strcmp(av[1], hash_algos[i].name)) {
37649b7f 26) algo = &hash_algos[i];
37649b7f 27) break;
37649b7f 31) if (!algo)
37649b7f 32) die("usage: test-tool hash-speed algo_name");
37649b7f 35) initial = clock();
37649b7f 37) printf("algo: %s\n", algo->name);
37649b7f 39) for (i = 0; i < ARRAY_SIZE(bufsizes); i++) {
37649b7f 42) p = xcalloc(1, bufsizes[i]);
37649b7f 43) start = end = clock() - initial;
37649b7f 44) for (j = 0; ((end - start) / CLOCKS_PER_SEC) < NUM_SECONDS; j++) {
37649b7f 45) compute_hash(algo, &ctx, hash, p, bufsizes[i]);
37649b7f 51) if (!(j & 127))
37649b7f 52) end = clock() - initial;
37649b7f 54) kb = j * bufsizes[i];
37649b7f 55) kb_per_sec = kb / (1024 * ((double)end - start) / CLOCKS_PER_SEC);
37649b7f 56) printf("size %u: %lu iters; %lu KiB; %0.2f KiB/s\n", bufsizes[i], j, kb, kb_per_sec);
37649b7f 57) free(p);
37649b7f 60) exit(0);

t/helper/test-hash.c
50c817e0 17) bufsz = strtoul(av[1], NULL, 10) * 1024 * 1024;
50c817e0 21) bufsz = 8192;
50c817e0 24) fprintf(stderr, "bufsz %u is too big, halving...\n", bufsz);
50c817e0 25) bufsz /= 2;
50c817e0 26) if (bufsz < 1024)
50c817e0 27) die("OOPS");
50c817e0 42) die_errno("test-hash");

tree-walk.c
0a3faa45 530) oidcpy(result, &oid);

tree.c
60c38b9e 104) commit = lookup_commit(r, &entry.oid);

upload-pack.c
0b6069fe 148) argv_array_pushf(&pack_objects.args, "--filter=%s", buf.buf);

Commits introducting uncovered code:
Brandon Williams	f9ee2fcd grep: recurse in-process using 'struct repository'
Brandon Williams	f7e20501 fetch-pack: support shallow requests
brian m. carlson	ac73cedf hash: create union for hash context allocation
brian m. carlson	50c817e0 t: make the sha1 test-tool helper generic
brian m. carlson	0a3faa45 tree-walk: copy object ID before use
brian m. carlson	37649b7f t/helper: add a test helper to compute hash speed
brian m. carlson	47edb649 hex: introduce functions to print arbitrary hashes
brian m. carlson	ea82b2a0 tree-walk: store object_id in a separate member
Derrick Stolee	5227c385 commit-reach: move walk methods from commit.c
Issac Trotts	ad6f028f log: add %S option (like --source) to log --format
Jeff Hostetler	aa57b871 fetch: inherit filter-spec from partial clone
Jeff King	ee1c6c34 sha1_file: only freshen packs once per run
Johannes Schindelin	d421afa0 rebase: introduce --reschedule-failed-exec
Jonathan Tan	4316ff30 fetch-pack: support protocol version 2
Jonathan Tan	0b6069fe fetch-pack: test support excluding large blobs
Jonathan Tan	3390e42a fetch-pack: support negotiation tip whitelist
Junio C Hamano	60c38b9e Merge branch 'bc/tree-walk-oid' into next
Linus Torvalds	12dccc16 Make fiel checkout function available to the git library
Masaya Suzuki	b79bdd8c remote-curl: unset CURLOPT_FAILONERROR
Masaya Suzuki	e6cf87b1 http: enable keep_error for HTTP requests
Matthew DeVore	bc5975d2 list-objects-filter: implement filter tree:0
Nguyễn Thái Ngọc Duy	1a07e59c Update messages in preparation for i18n
Phillip Wood	21536d07 diff --color-moved-ws: modify allow-indentation-change
Phillip Wood	b73bcbac diff: allow --no-color-moved-ws
Pratik Karki	ba1905a5 builtin rebase: add support for custom merge strategies
Takuto Ikuta	024aa469 fetch-pack.c: use oidset to check existence of loose object
Thomas Gummerer	536ec183 entry: support CE_WT_REMOVE flag in checkout_entry


Uncovered code in 'master' not in 'maint'
--------------------------------------------------------

apply.c
0f086e6d 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6d 3356)     lstat(ce->name, st))

attr.c
ad8f8f4a 369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
09002f1b 1712) if (revs->pending.nr != 1)
09002f1b 1719) return NULL;

builtin/bundle.c
74ae4b63 64) return !!unbundle(the_repository, &header, bundle_fd, 0) ||

builtin/checkout.c
9f97ab08 182) return error(_("path '%s' does not have their version"), ce->name);

builtin/fast-export.c
f129c427 202) if (!p->parents)
f129c427 203) return NULL;
f129c427 204) p = p->parents->item;
f129c427 205) }
a8722750 257) buf = anonymize_blob(&size);
da14a7ff 258) object = (struct object *)lookup_blob(the_repository, oid);
a8722750 259) eaten = 0;
a8722750 334) struct strbuf out = STRBUF_INIT;
a8722750 335) strbuf_addf(&out, "path%d", counter++);
a8722750 336) return strbuf_detach(&out, len);
b3e8ca89 402) if (!string_list_has_string(changed, ospec->path)) {
b3e8ca89 403) printf("%c ", q->queue[i]->status);
b3e8ca89 404) print_path(ospec->path);
a8722750 630) refname = anonymize_refname(refname);
a8722750 631) anonymize_ident_line(&committer, &committer_end);
a8722750 632) anonymize_ident_line(&author, &author_end);
a8722750 637) reencoded = anonymize_commit_message(message);
02c48cd6 730) return;
1a07e59c 772) die("encountered signed tag %s; use "
1a07e59c 774)     oid_to_hex(&tag->object.oid));
1a07e59c 807)     oid_to_hex(&tag->object.oid),
f2dc849e 871) continue;
debca9d2 886) type_name(e->item->type));
2d07f6d4 887) continue;
273f8ee8 894) export_blob(&commit->object.oid);
3e9b9cb1 895) continue;
3e9b9cb1 897) warning("Tag points to object of unexpected type %s, skipping.",
debca9d2 898) type_name(commit->object.type));
3e9b9cb1 899) continue;
df6a7ff7 1031) die("corrupt mark line: %s", line);

builtin/fsck.c
674ba340 167) objerror(parent, _("wrong object type in link"));
18af29f2 280) return;
674ba340 334) fprintf_ln(stderr, _("Checking %s"), describe_object(obj));
85003492 367) return 0;
674ba340 618) fprintf_ln(stderr, _("Checking object directory"));
3813a89f 636) fprintf_ln(stderr, _("Checking %s link"), head_ref_name);
ae7c0c92 864) continue;

builtin/merge.c
9440b831 131) return error(_("option `%s' requires a value"), opt->long_name);

builtin/reflog.c
4264dc15 588) i++;
3c386aa3 685) i++;
552cecc2 705) continue;
afcb2e7a 740) i++;

builtin/repack.c
c83d950e 200) die(_("could not start pack-objects to repack promisor objects"));
3813a89f 239) die(_("repack: Expecting full hex object ID lines only from pack-objects."));
c83d950e 250) die_errno(_("unable to create '%s'"), promisor_name);
3813a89f 411) die(_("repack: Expecting full hex object ID lines only from pack-objects."));
a1bbc6c0 480) fprintf(stderr,

builtin/worktree.c
00a6d4d1 752) found_submodules = 1;

bundle.c
be042aff 491) argv_index_pack[3] = "-v";

commit-graph.c
cce99cd8 570) BUG("missing parent %s for commit %s",

delta-islands.c
c8d521fa 214) obj = ((struct tag *)obj)->tagged;

fast-import.c
8dc6a373 2869) static struct object_entry *dereference(struct object_entry *oe,

git.c
8aa8c140 342) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c140 351) die(_("alias '%s' changes environment variables.\n"

http-walker.c
b69fb867 550) loose_object_path(the_repository, &buf, req->sha1);

http.c
d73019fe 289) return git_config_string(&curl_http_version, var, value);
d73019fe 797) static int get_curl_http_version_opt(const char *version_string, long *opt)
d73019fe 808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019fe 809) if (!strcmp(version_string, choice[i].name)) {
d73019fe 810) *opt = choice[i].opt_token;
d73019fe 811) return 0;
d73019fe 815) warning("unknown value given to http.version: '%s'", version_string);
d73019fe 816) return -1; /* not found */

merge-recursive.c
37b65ce3 1588) return -1;
37b65ce3 1594) return -1;
37b65ce3 1597) return -1;
37b65ce3 1664) return -1;
37b65ce3 1667) return -1;
7f867165 1703) return -1;
033abf97 2742) BUG("ren1_dst != ren2_dst");
75456f96 3206) free(new_path);
75456f96 3207) return -1;
75456f96 3278) clean_merge = -1;
75456f96 3283) clean_merge = -1;

parse-options-cb.c
9440b831 21) return error(_("option `%s' expects a numerical value"),
9440b831 51) return error(_("option `%s' expects \"always\", \"auto\", or \"never\""),

parse-options.c
9440b831 194) return error(_("%s expects a non-negative integer value"
9440b831 787) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

pathspec.c
22af33be 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
391408e5 319) BUG("unsupported ce_mode: %o", ce->ce_mode);
9d0a9e90 675) die(_("will not add file alias '%s' ('%s' already exists in index)"),
9d0a9e90 676)     ce->name, alias->name);
a849735b 785) discard_cache_entry(ce);
bad68ec9 1727) if (*ext < 'A' || 'Z' < *ext)
8616a2d0 2351) if (!istate) {
8616a2d0 2358) !mem_pool_contains(istate->split_index->base->ce_mem_pool, istate->cache[i])) {
ec36c42a 3498) const char *index = NULL;
ec36c42a 3504) if (!offset)
ec36c42a 3505) return NULL;
ec36c42a 3506) while (offset <= mmap_size - the_hash_algo->rawsz - 8) {
ec36c42a 3507) extsize = get_be32(mmap + offset + 4);
ec36c42a 3508) if (CACHE_EXT((mmap + offset)) == CACHE_EXT_INDEXENTRYOFFSETTABLE) {
ec36c42a 3509) index = mmap + offset + 4 + 4;
ec36c42a 3510) break;
ec36c42a 3512) offset += 8;
ec36c42a 3513) offset += extsize;
ec36c42a 3515) if (!index)
ec36c42a 3516) return NULL;
ec36c42a 3519) ext_version = get_be32(index);
ec36c42a 3520) if (ext_version != IEOT_VERSION) {
ec36c42a 3521) error("invalid IEOT version %d", ext_version);
ec36c42a 3522) return NULL;
ec36c42a 3524) index += sizeof(uint32_t);
ec36c42a 3527) nr = (extsize - sizeof(uint32_t)) / (sizeof(uint32_t) + sizeof(uint32_t));
ec36c42a 3528) if (!nr) {
ec36c42a 3529) error("invalid number of IEOT entries %d", nr);
ec36c42a 3530) return NULL;
ec36c42a 3532) ieot = xmalloc(sizeof(struct index_entry_offset_table)
ec36c42a 3533)        + (nr * sizeof(struct index_entry_offset)));
ec36c42a 3534) ieot->nr = nr;
ec36c42a 3535) for (i = 0; i < nr; i++) {
ec36c42a 3536) ieot->entries[i].offset = get_be32(index);
ec36c42a 3537) index += sizeof(uint32_t);
ec36c42a 3538) ieot->entries[i].nr = get_be32(index);
ec36c42a 3539) index += sizeof(uint32_t);

ref-filter.c
1867ce6c 236) oi_deref.info.sizep = &oi_deref.size;
1867ce6c 245) return strbuf_addf_ret(err, -1, _("unrecognized %%(objectsize) argument: %s"), arg);
33311fa1 253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does not take arguments"));
033abf97 883) BUG("unknown %%(objectname) option");

remote.c
dd8dd300 1035) BUG("'%s' is not a valid object, "

sequencer.c
ba97aea1 598) return NULL;
e47c6caf 1190) free(user_config);
e47c6caf 1191) free(xdg_config);
66618a50 1343) hook_commit = "HEAD";
aee42e1f 1463) return error(_("could not parse parent commit %s"),
6e98de72 1673) return error(_("unknown command: %d"), command);
1e41229d 2559) strbuf_release(&sb);
88d5a271 2698) res |= git_config_set_in_file_gently(opts_file, "options.edit", "true");
56dc3ab0 2756) res |= error_errno(_("could not open '%s'"), buf.buf);
bc9238bb 2795) return -1;
bc9238bb 2798) return error(_("unable to copy '%s' to '%s'"),
56dc3ab0 2803) return -1;
2b6ad0f4 3133) ret = error(_("unable to parse '%.*s'"), k, p);
15ef6931 3925) return error(_("could not remove CHERRY_PICK_HEAD"));
2863584f 3957) return -1;
cdac2b01 4838) return -1;

setup.c
033abf97 1107) BUG("unhandled setup_git_directory_1() result");

sha1-file.c
f0eaf638 2138) return r;
3a2e0824 2162) BUG("subdir_nr out of range");

submodule.c
6e3c1595 1729) ret = -1;
6e3c1595 1730) goto out;

t/helper/test-sigchain.c
3b335762 17) int cmd__sigchain(int argc, const char **argv)

transport-helper.c
3b335762 1029) static int has_attribute(const char *attrs, const char *attr)

tree-walk.c
2842c0f9 377) return still_interesting;

Commits introducting uncovered code:
Ævar Arnfjörð Bjarmason	9f97ab08 i18n: git-checkout: our/their version message
Ævar Arnfjörð Bjarmason	dd8dd300 push: add an advice on unqualified <dst> push
Brandon Casey	3c386aa3 reflog-delete: parse standard reflog options
Brandon Williams	debca9d2 object: rename function 'typename' to 'type_name'
brian m. carlson	273f8ee8 builtin/fast-export: convert to struct object_id
David Barr	8dc6a373 fast-import: add 'ls' command
David Turner	afcb2e7a git-reflog: add exists command
Derrick Stolee	cce99cd8 commit-graph: writing missing parents is a BUG
Elijah Newren	37b65ce3 merge-recursive: new function for better colliding conflict resolutions
Elijah Newren	f129c427 fast-export: move commit rewriting logic into a function for reuse
Elijah Newren	7f867165 merge-recursive: fix rename/add conflict handling
Elijah Newren	02c48cd6 fast-export: Omit tags that tag trees
Erik Faye-Lund	2d07f6d4 builtin-fast-export.c: turn error into warning
Felipe Contreras	3e9b9cb1 fast-export: refactor get_tags_and_duplicates()
Force Charlie	d73019fe http: add support selecting http version
Jameson Miller	a849735b block alloc: add lifecycle APIs for cache_entry structs
Jameson Miller	8616a2d0 block alloc: add validations around cache_entry lifecyle
Jeff King	a8722750 teach fast-export an --anonymize option
Jeff King	b69fb867 sha1_file_name(): overwrite buffer instead of appending
Jeff King	3a2e0824 object-store: provide helpers for loose_objects_cache
Jeff King	c8d521fa Add delta-islands.{c,h}
Jeff King	f0eaf638 sha1-file: use an object_directory for the main object dir
Jeff Smith	09002f1b blame: move scoreboard setup to libgit
Johannes Schindelin	ba97aea1 sequencer: extract helper to update active_cache_tree
Johannes Schindelin	aee42e1f sequencer: strip bogus LF at end of error messages
Johannes Schindelin	6e98de72 sequencer (rebase -i): add support for the 'fixup' and 'squash' commands
Johannes Schindelin	88d5a271 sequencer: lib'ify save_opts()
Johannes Schindelin	2b6ad0f4 rebase --rebase-merges: add support for octopus merges
Johannes Schindelin	552cecc2 Teach "git reflog" a subcommand to delete single entries
Johannes Schindelin	cdac2b01 rebase -i: skip unnecessary picks using the rebase--helper
Johannes Schindelin	2863584f sequencer: get rid of the subcommand field
Johannes Schindelin	033abf97 Replace all die("BUG: ...") calls by BUG() ones
Johannes Schindelin	75456f96 merge-recursive: handle return values indicating errors
Johannes Schindelin	f2dc849e Add 'git fast-export', the sister of 'git fast-import'
Johannes Schindelin	15ef6931 rebase --skip: clean up commit message after a failed fixup/squash
Johannes Schindelin	56dc3ab0 sequencer (rebase -i): implement the 'edit' command
Jonathan Tan	b3e8ca89 fast-export: do not copy from modified file
Junio C Hamano	2842c0f9 traverse_trees(): allow pruning with pathspec
Junio C Hamano	4264dc15 git reflog expire
Junio C Hamano	ae7c0c92 Git-prune-script loses blobs referenced from an uncommitted cache.
Junio C Hamano	3813a89f Merge branch 'nd/i18n'
Junio C Hamano	be042aff Teach progress eye-candy to fetch_refs_from_bundle()
Junio C Hamano	bad68ec9 index: make the index file format extensible.
Linus Torvalds	85003492 Make fsck-cache do better tree checking.
Linus Torvalds	18af29f2 fsck-objects: refactor checking for connectivity
Nguyễn Thái Ngọc Duy	ec36c42a Indent code with TABs
Nguyễn Thái Ngọc Duy	8aa8c140 git.c: mark more strings for translation
Nguyễn Thái Ngọc Duy	391408e5 read-cache.c: turn die("internal error") to BUG()
Nguyễn Thái Ngọc Duy	ad8f8f4a attr.c: mark more string for translation
Nguyễn Thái Ngọc Duy	74ae4b63 bundle.c: remove the_repository references
Nguyễn Thái Ngọc Duy	1a07e59c Update messages in preparation for i18n
Nguyễn Thái Ngọc Duy	674ba340 fsck: mark strings for translation
Nguyễn Thái Ngọc Duy	9440b831 parse-options: replace opterror() with optname()
Nguyễn Thái Ngọc Duy	9d0a9e90 read-cache.c: mark more strings for translation
Nguyễn Thái Ngọc Duy	c83d950e repack: mark more strings for translation
Nguyễn Thái Ngọc Duy	3b335762 style: the opening '{' of a function is in a separate line
Nguyễn Thái Ngọc Duy	22af33be dir.c: move, rename and export match_attrs()
Nguyễn Thái Ngọc Duy	00a6d4d1 worktree: allow to (re)move worktrees with uninitialized submodules
Nguyễn Thái Ngọc Duy	0f086e6d checkout: print something when checking out paths
Olga Telezhnaya	33311fa1 ref-filter: add deltabase option
Olga Telezhnaya	1867ce6c ref-filter: add objectsize:disk option
Phillip Wood	66618a50 sequencer: run 'prepare-commit-msg' hook
Phillip Wood	e47c6caf commit: move print_commit_summary() to libgit
Phillip Wood	bc9238bb rebase -i: fix SIGSEGV when 'merge <branch>' fails
Pieter de Bie	df6a7ff7 builtin-fast-export: Add importing and exporting of revision marks
Stefan Beller	a1bbc6c0 repack: rewrite the shell script in C
Stefan Beller	da14a7ff blob: add repository argument to lookup_blob
Stefan Beller	6e3c1595 update submodules: add submodule_move_head
Stephan Beyer	1e41229d sequencer: make sequencer abort safer



^ permalink raw reply	[relevance 1%]

* Re: Git Test Coverage Report (Sat Jan 19)
  @ 2019-01-24 20:56  1%       ` Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2019-01-24 20:56 UTC (permalink / raw)
  To: Ramsay Jones, Junio C Hamano; +Cc: git@vger.kernel.org

On 1/24/2019 2:39 PM, Ramsay Jones wrote:
> 
> 
> On 24/01/2019 19:18, Derrick Stolee wrote:
>> On 1/24/2019 1:15 PM, Junio C Hamano wrote:
>>> Derrick Stolee <stolee@gmail.com> writes:
>>>
>>>> Here is today's test coverage report.
>>>>
>>>> Also, there has been some feedback that it can be hard to manually
>>>> match up uncovered lines with names at the bottom of the summary. The
>>>> suggestion was to auto-generate an HTML report that could be posted to
>>>> a public page and referenced in this mail for those who prefer
>>>> that.
>>> I wanted to "grep" for lines attributed to certain commits that
>>> appear in the list, by filtering lines that begin with enough number
>>> of hexdigits, except for those object names, but the attempt failed
>>> miserably because of the line wrapping (which probably comes from
>>> the assumption that it is OK because the "text/plain; format=flowed"
>>> would not care).  If you can keep the long lines (due to the object
>>> names and line numbers prefixed to each line) unsplit, it would be
>>> more useful to locate and isolate lines.
>> This is likely more a problem with my workflow (pasting the report into Thunderbird and sending) than with the content itself.
> 
> Have you read Doucmentation/git-format-patch.txt (Thunderbird>
> Approach #2 (configuration) - approx. line 487)?
> 
> ATB,
> Ramsay Jones
> 

Thanks, Ramsay! I adjusted the settings and am re-pasting the latest
report below. Let me know if everything improved.

Thanks,
-Stolee


pu: 32ea0d952e6add9269432e6e2b31fd552e5478c0
jch: bc1fa105c1c1d5870a7e2800526f0a7ebf17d064
next: aa96b0ce6b0fa4fa4cc6870f1a3aff3878967bfa
master: 16a465bc018d09e9d7bbbdc5f40a7fb99c21f8ef
master@{1}: 77556354bb7ac50450e3b28999e3576969869068

Uncovered code in 'pu' not in 'jch'
--------------------------------------

bisect.c
4f6d26b167  661) mark_edges_uninteresting(revs, NULL, 0);

blame.c
e1ff0a32e4  191) repo_read_index(r);
e1ff0a32e4  273) repo_read_index(r);
07d04b919e  482)     ent->s_lno + ent->num_lines == next->s_lno &&
07d04b919e  483)     ent->ignored == next->ignored) {
07d04b919e  735) split[0].ignored = split[1].ignored = split[2].ignored = e->ignored;
e7973c8519  859) struct blame_entry *samep = NULL, *diffp = NULL, *ignoredp = NULL;
07d04b919e  873) n->ignored = e->ignored;
07d04b919e  928) n->ignored = e->ignored;
e7973c8519  938) if (ignore_diffs) {
e7973c8519  940) blame_origin_decref(e->suspect);
e7973c8519  941) e->suspect = blame_origin_incref(parent);
e7973c8519  942) e->s_lno += offset;
07d04b919e  943) e->ignored = 1;
e7973c8519  944) e->next = ignoredp;
e7973c8519  945) ignoredp = e;
e7973c8519  947) e->next = diffp;
e7973c8519  948) diffp = e;
e7973c8519  952) if (ignoredp) {
e7973c8519  953) **dstq = reverse_blame(ignoredp, **dstq);
e7973c8519  954) *dstq = &ignoredp->next;
e7973c8519 1001) d.ignore_diffs = ignore_diffs;
e7973c8519 1013) blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, INT_MAX, parent, 0);
e7973c8519 1518) pass_blame_to_parent(sb, origin, porigin, 0);
e7973c8519 1526) if (oidset_contains(&sb->ignore_list, &commit->object.oid)) {
e7973c8519 1527) for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
e7973c8519 1528)      i < num_sg && sg;
e7973c8519 1529)      sg = sg->next, i++) {
e7973c8519 1530) struct blame_origin *porigin = sg_origin[i];
e7973c8519 1532) if (!porigin)
e7973c8519 1533) continue;
e7973c8519 1534) pass_blame_to_parent(sb, origin, porigin, 1);
e7973c8519 1535) if (!origin->suspects)
e7973c8519 1536) goto finish;

builtin/am.c
1d18d7581c  515) finish_copy_notes_for_rewrite(the_repository, c, msg);
150fe065f7 1765)     !repo_index_has_changes(the_repository, NULL, NULL)) {
150fe065f7 1819) if (!repo_index_has_changes(the_repository, NULL, NULL)) {

builtin/blame.c
07d04b919e builtin/blame.c    484) if (mark_ignored_lines && ent->ignored) {
07d04b919e builtin/blame.c    485) length--;
07d04b919e builtin/blame.c    486) putchar('*');
e7973c8519 builtin/blame.c    704) if (!strcmp(var, "blame.ignorerevsfile"))
e7973c8519 builtin/blame.c    705) return git_config_pathname(&ignore_revs_file, var, value);
07d04b919e builtin/blame.c    706) if (!strcmp(var, "blame.markignoredlines")) {
07d04b919e builtin/blame.c    707) mark_ignored_lines = git_config_bool(var, value);
07d04b919e builtin/blame.c    708) return 0;
e7973c8519 builtin/blame.c    789) static void build_ignorelist(struct blame_scoreboard *sb,
e7973c8519 builtin/blame.c    795) oidset_init(&sb->ignore_list, 0);
e7973c8519 builtin/blame.c    796) if (ignore_revs_file)
e7973c8519 builtin/blame.c    797) oidset_parse_file(&sb->ignore_list, ignore_revs_file);
e7973c8519 builtin/blame.c    798) for_each_string_list_item(i, ignore_rev_list) {
e7973c8519 builtin/blame.c    799) if (get_oid_committish(i->string, &oid))
e7973c8519 builtin/blame.c    800) die(_("Can't find revision '%s' to ignore"), i->string);
e7973c8519 builtin/blame.c    801) oidset_insert(&sb->ignore_list, &oid);
e7973c8519 builtin/blame.c    803) }
acdd37769d builtin/blame.c    961) blame_date_width = sizeof("Thu Oct 19 16:00");
acdd37769d builtin/blame.c    962) break;
e7973c8519 builtin/blame.c   1033) build_ignorelist(&sb, &ignore_rev_list);
e7973c8519 builtin/blame.c   1034) string_list_clear(&ignore_rev_list, 0);
4478671442 builtin/blame.c   1048)     the_repository->index))

builtin/checkout.c
0d6caa2d08 builtin/checkout.c  751) init_merge_options(&o, the_repository);

builtin/commit.c
1d18d7581c builtin/commit.c 1689) commit_post_rewrite(the_repository, current_head, &oid);

builtin/config.c
a12c1ff3a5 builtin/config.c       85) die(_("only one config file at a time"));
a12c1ff3a5 builtin/config.c       88) die(_("--local can only be used inside a git repository"));
a12c1ff3a5 builtin/config.c       91) die(_("--blob can only be used inside a git repository"));
a12c1ff3a5 builtin/config.c       95) given_config_source.file = NULL;
a12c1ff3a5 builtin/config.c       96) given_config_source.use_stdin = 1;
a12c1ff3a5 builtin/config.c      110) die(_("$HOME not set"));
a12c1ff3a5 builtin/config.c      114) given_config_source.file = xdg_config;
a12c1ff3a5 builtin/config.c      115) free(user_config);
a12c1ff3a5 builtin/config.c      122) given_config_source.file = git_etc_gitconfig();
a12c1ff3a5 builtin/config.c      126) given_config_source.file = get_worktree_config(the_repository);
a12c1ff3a5 builtin/config.c      127) if (!given_config_source.file)
a12c1ff3a5 builtin/config.c      128) die(_("--worktree cannot be used with multiple "
6f11fd5edb builtin/config.c      185) static int option_move_cb(const struct option *opt,
6f11fd5edb builtin/config.c      188) BUG_ON_OPT_NEG(unset);
6f11fd5edb builtin/config.c      189) BUG_ON_OPT_ARG(arg);
6f11fd5edb builtin/config.c      191) set_config_source_file();
6f11fd5edb builtin/config.c      192) memcpy(&move_source, &given_config_source, sizeof(move_source));
6f11fd5edb builtin/config.c      194) memset(&given_config_source, 0, sizeof(given_config_source));
6f11fd5edb builtin/config.c      195) use_global_config = 0;
6f11fd5edb builtin/config.c      196) use_system_config = 0;
6f11fd5edb builtin/config.c      197) use_local_config = 0;
6f11fd5edb builtin/config.c      198) use_worktree_config = 0;
6f11fd5edb builtin/config.c      200) actions = opt->defval;
6f11fd5edb builtin/config.c      201) return 0;
6f11fd5edb builtin/config.c      471) static int collect_move_config(const char *key, const char *value, void *cb)
6f11fd5edb builtin/config.c      473) struct move_config_cb *data = cb;
6f11fd5edb builtin/config.c      475) switch (actions) {
6f11fd5edb builtin/config.c      477) if (strcasecmp(data->key, key))
6f11fd5edb builtin/config.c      478) return 0;
6f11fd5edb builtin/config.c      479) break;
6f11fd5edb builtin/config.c      481) if (regexec(&data->key_re, key, 0, NULL, 0))
6f11fd5edb builtin/config.c      482) return 0;
6f11fd5edb builtin/config.c      483) break;
6f11fd5edb builtin/config.c      485) if (wildmatch(data->key, key, WM_CASEFOLD))
6f11fd5edb builtin/config.c      486) return 0;
6f11fd5edb builtin/config.c      487) break;
6f11fd5edb builtin/config.c      492) string_list_append(&data->keys, key)->util = xstrdup(value);
6f11fd5edb builtin/config.c      493) return 0;
6f11fd5edb builtin/config.c      496) static int move_config(const char *key)
6f11fd5edb builtin/config.c      499) int i, ret = 0;
6f11fd5edb builtin/config.c      501) config_options.respect_includes = 0;
6f11fd5edb builtin/config.c      502) if (!move_source.file && !move_source.use_stdin && !move_source.blob)
6f11fd5edb builtin/config.c      503) die(_("unknown config source"));
6f11fd5edb builtin/config.c      505) string_list_init(&cb.keys, 1);
6f11fd5edb builtin/config.c      506) cb.key = key;
6f11fd5edb builtin/config.c      507) if (actions == ACTION_MOVE_REGEXP &&
6f11fd5edb builtin/config.c      508)     regcomp(&cb.key_re, key, REG_EXTENDED | REG_ICASE))
6f11fd5edb builtin/config.c      509) die(_("invalid key pattern: %s"), key);
6f11fd5edb builtin/config.c      511) config_with_options(collect_move_config, &cb,
6f11fd5edb builtin/config.c      514) for (i = 0; i < cb.keys.nr && !ret; i++) {
6f11fd5edb builtin/config.c      515) const char *key = cb.keys.items[i].string;
6f11fd5edb builtin/config.c      516) const char *value = cb.keys.items[i].util;
6f11fd5edb builtin/config.c      517) const char *dest = given_config_source.file;
6f11fd5edb builtin/config.c      519) ret = git_config_set_multivar_in_file_gently(
6f11fd5edb builtin/config.c      527) if (!ret && move_source.file) {
6f11fd5edb builtin/config.c      528) for (i = 0; i < cb.keys.nr; i++) {
6f11fd5edb builtin/config.c      529) const char *key = cb.keys.items[i].string;
6f11fd5edb builtin/config.c      530) const char *src = move_source.file;
6f11fd5edb builtin/config.c      532) git_config_set_multivar_in_file_gently(
6f11fd5edb builtin/config.c      537) string_list_clear(&cb.keys, 1);
6f11fd5edb builtin/config.c      538) if (actions == ACTION_MOVE_REGEXP)
6f11fd5edb builtin/config.c      539) regfree(&cb.key_re);
6f11fd5edb builtin/config.c      540) return ret;
6f11fd5edb builtin/config.c      979) else if (actions == ACTION_MOVE ||
6f11fd5edb builtin/config.c      980)  actions == ACTION_MOVE_REGEXP ||
6f11fd5edb builtin/config.c      981)  actions == ACTION_MOVE_GLOB) {
6f11fd5edb builtin/config.c      982) check_write();
6f11fd5edb builtin/config.c      983) check_argc(argc, 1, 1);
6f11fd5edb builtin/config.c      984) return move_config(argv[0]);

builtin/describe.c
1b0d968b34 builtin/describe.c 638) repo_update_index_if_able(the_repository, &index_lock);

builtin/diff-tree.c
e1ff0a32e4 builtin/diff-tree.c 169) repo_read_index(the_repository);

builtin/grep.c
dba093ddc0 builtin/grep.c  403) static int grep_submodule(struct grep_opt *opt,
dba093ddc0 builtin/grep.c  409) struct repository *superproject = opt->repo;
dba093ddc0 builtin/grep.c  448) memcpy(&subopt, opt, sizeof(subopt));
b6b4172bfb builtin/grep.c  449) subopt.repo = &subrepo;
dba093ddc0 builtin/grep.c  472) hit = grep_tree(&subopt, pathspec, &tree, &base, base.len,
dba093ddc0 builtin/grep.c  473) object->type == OBJ_COMMIT);
dba093ddc0 builtin/grep.c  477) hit = grep_cache(&subopt, pathspec, 1);
dba093ddc0 builtin/grep.c  484) static int grep_cache(struct grep_opt *opt,
dba093ddc0 builtin/grep.c  487) struct repository *repo = opt->repo;
dba093ddc0 builtin/grep.c  525) hit |= grep_submodule(opt, pathspec, NULL, ce->name, ce->name);
dba093ddc0 builtin/grep.c  549) struct repository *repo = opt->repo;
b6b4172bfb builtin/grep.c  599) hit |= grep_submodule(opt, pathspec, &entry.oid,
dba093ddc0 builtin/grep.c  641) obj->type == OBJ_COMMIT);
dba093ddc0 builtin/grep.c  658) real_obj = deref_tag(opt->repo, list->objects[i].item,
dba093ddc0 builtin/grep.c  663) submodule_free(opt->repo);
dba093ddc0 builtin/grep.c  688) fill_directory(&dir, opt->repo->index, pathspec);
dba093ddc0 builtin/grep.c  690) if (!dir_path_match(opt->repo->index, dir.entries[i], pathspec, 0, NULL))
3a7a698e93 builtin/grep.c 1028) if (get_oid_with_context(the_repository, arg,
dba093ddc0 builtin/grep.c 1132) hit = grep_cache(&opt, &pathspec, cached);

builtin/log.c
3a7a698e93 builtin/log.c  513) if (get_oid_with_context(the_repository, obj_name,

builtin/merge-tree.c
4478671442 builtin/merge-tree.c  80) return merge_blobs(the_repository->index, path,

builtin/merge.c
08339886b9 builtin/merge.c  120) static enum parse_opt_result option_read_message(struct parse_opt_ctx_t *ctx,
9b4ae5190a builtin/merge.c  128) BUG_ON_OPT_ARG(arg_not_used);

builtin/notes.c
1d18d7581c builtin/notes.c  333) commit_notes(the_repository, t, msg);
1d18d7581c builtin/notes.c  336) finish_copy_notes_for_rewrite(the_repository, c, msg);
1d18d7581c builtin/notes.c  472) commit_notes(the_repository, t,
1d18d7581c builtin/notes.c  478) commit_notes(the_repository, t,
1d18d7581c builtin/notes.c  557) commit_notes(the_repository, t,
1d18d7581c builtin/notes.c  642) commit_notes(the_repository, t, logmsg);
1d18d7581c builtin/notes.c  943) commit_notes(the_repository, t,
1d18d7581c builtin/notes.c  972) commit_notes(the_repository, t,

builtin/pack-objects.c
3d036eb0d2 builtin/pack-objects.c 2716) sparse = git_config_bool(k, v);
3d036eb0d2 builtin/pack-objects.c 2717) return 0;

builtin/pack-redundant.c
a338d10395 builtin/pack-redundant.c 339) static int cmp_remaining_objects(const void *a, const void *b)
e4e2c2884e builtin/pack-redundant.c 341) struct pack_list *pl_a = *((struct pack_list **)a);
e4e2c2884e builtin/pack-redundant.c 342) struct pack_list *pl_b = *((struct pack_list **)b);
a338d10395 builtin/pack-redundant.c 344) if (pl_a->remaining_objects->size == pl_b->remaining_objects->size) {
a338d10395 builtin/pack-redundant.c 346) if (pl_a->all_objects_size == pl_b->all_objects_size)
a338d10395 builtin/pack-redundant.c 347) return 0;
a338d10395 builtin/pack-redundant.c 348) else if (pl_a->all_objects_size < pl_b->all_objects_size)
a338d10395 builtin/pack-redundant.c 349) return 1;
a338d10395 builtin/pack-redundant.c 351) return -1;
a338d10395 builtin/pack-redundant.c 352) } else if (pl_a->remaining_objects->size < pl_b->remaining_objects->size) {
e4e2c2884e builtin/pack-redundant.c 354) return 1;
e4e2c2884e builtin/pack-redundant.c 356) return -1;
e4e2c2884e builtin/pack-redundant.c 361) static void sort_pack_list(struct pack_list **pl)
e4e2c2884e builtin/pack-redundant.c 365) size_t n = pack_list_size(*pl);
e4e2c2884e builtin/pack-redundant.c 367) if (n < 2)
e4e2c2884e builtin/pack-redundant.c 368) return;
e4e2c2884e builtin/pack-redundant.c 371) ary = xcalloc(n, sizeof(struct pack_list *));
e4e2c2884e builtin/pack-redundant.c 372) for (n = 0, p = *pl; p; p = p->next)
e4e2c2884e builtin/pack-redundant.c 373) ary[n++] = p;
a338d10395 builtin/pack-redundant.c 375) QSORT(ary, n, cmp_remaining_objects);
e4e2c2884e builtin/pack-redundant.c 378) for (i = 0; i < n - 1; i++)
e4e2c2884e builtin/pack-redundant.c 379) ary[i]->next = ary[i + 1];
e4e2c2884e builtin/pack-redundant.c 380) ary[n - 1]->next = NULL;
e4e2c2884e builtin/pack-redundant.c 381) *pl = ary[0];
e4e2c2884e builtin/pack-redundant.c 383) free(ary);
e4e2c2884e builtin/pack-redundant.c 389) struct pack_list *pl, *unique = NULL, *non_unique = NULL;
cb7e0336fc builtin/pack-redundant.c 404) llist_sorted_difference_inplace(missing, pl->remaining_objects);
e4e2c2884e builtin/pack-redundant.c 408) *min = unique;
e4e2c2884e builtin/pack-redundant.c 416) unique_pack_objects = llist_copy(all_objects);
e4e2c2884e builtin/pack-redundant.c 417) llist_sorted_difference_inplace(unique_pack_objects, missing);
e4e2c2884e builtin/pack-redundant.c 420) pl = non_unique;
cb7e0336fc builtin/pack-redundant.c 422) llist_sorted_difference_inplace(pl->remaining_objects, unique_pack_objects);
e4e2c2884e builtin/pack-redundant.c 426) while (non_unique) {
e4e2c2884e builtin/pack-redundant.c 428) sort_pack_list(&non_unique);
cb7e0336fc builtin/pack-redundant.c 429) if (non_unique->remaining_objects->size == 0)
e4e2c2884e builtin/pack-redundant.c 430) break;
e4e2c2884e builtin/pack-redundant.c 432) pack_list_insert(min, non_unique);
cb7e0336fc builtin/pack-redundant.c 434) for (pl = non_unique->next; pl && pl->remaining_objects->size > 0;  pl = pl->next)
cb7e0336fc builtin/pack-redundant.c 435) llist_sorted_difference_inplace(pl->remaining_objects, non_unique->remaining_objects);
e4e2c2884e builtin/pack-redundant.c 437) non_unique = non_unique->next;
cb7e0336fc builtin/pack-redundant.c 450) l = pl->remaining_objects->front;
cb7e0336fc builtin/pack-redundant.c 461) llist_sorted_difference_inplace(all_objects, pl->remaining_objects);
cb7e0336fc builtin/pack-redundant.c 490) llist_sorted_difference_inplace(all_objects, alt->remaining_objects);
cb7e0336fc builtin/pack-redundant.c 505) llist_init(&l.remaining_objects);
cb7e0336fc builtin/pack-redundant.c 514) llist_insert_back(l.remaining_objects, (const struct object_id *)(base + off));
a338d10395 builtin/pack-redundant.c 517) l.all_objects_size = l.remaining_objects->size;
cb7e0336fc builtin/pack-redundant.c 519) l.unique_objects = llist_copy(l.remaining_objects);
cb7e0336fc builtin/pack-redundant.c 615) llist_sorted_difference_inplace(pl->remaining_objects, ignore);

builtin/range-diff.c
26c50430dc 78) FREE_AND_NULL(options);

builtin/rebase--interactive.c
e5b1c9d929 builtin/rebase--interactive.c   17) static int edit_todo_file(unsigned flags)
e5b1c9d929 builtin/rebase--interactive.c   19) const char *todo_file = rebase_path_todo();
e5b1c9d929 builtin/rebase--interactive.c   20) struct todo_list todo_list = TODO_LIST_INIT,
e5b1c9d929 builtin/rebase--interactive.c   21) new_todo = TODO_LIST_INIT;
e5b1c9d929 builtin/rebase--interactive.c   23) if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
e5b1c9d929 builtin/rebase--interactive.c   24) return error_errno(_("could not read '%s'."), todo_file);
e5b1c9d929 builtin/rebase--interactive.c   26) strbuf_stripspace(&todo_list.buf, 1);
e5b1c9d929 builtin/rebase--interactive.c   27) if (!edit_todo_list(the_repository, &todo_list,
e5b1c9d929 builtin/rebase--interactive.c   28)     &new_todo, NULL, NULL, flags) &&
e5b1c9d929 builtin/rebase--interactive.c   29)     todo_list_write_to_file(the_repository, &new_todo, todo_file, NULL, NULL,
e5b1c9d929 builtin/rebase--interactive.c   31) return error_errno(_("could not write '%s'"), todo_file);
e5b1c9d929 builtin/rebase--interactive.c   33) todo_list_release(&todo_list);
e5b1c9d929 builtin/rebase--interactive.c   34) todo_list_release(&new_todo);
e5b1c9d929 builtin/rebase--interactive.c   36) return 0;
4d55dfd767 builtin/rebase--interactive.c   39) static int transform_todo_file(unsigned flags)
4d55dfd767 builtin/rebase--interactive.c   41) const char *todo_file = rebase_path_todo();
4d55dfd767 builtin/rebase--interactive.c   42) struct todo_list todo_list = TODO_LIST_INIT;
4d55dfd767 builtin/rebase--interactive.c   45) if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
4d55dfd767 builtin/rebase--interactive.c   46) return error_errno(_("could not read '%s'."), todo_file);
4d55dfd767 builtin/rebase--interactive.c   48) if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
4d55dfd767 builtin/rebase--interactive.c   50) todo_list_release(&todo_list);
4d55dfd767 builtin/rebase--interactive.c   51) return error(_("unusable todo list: '%s'"), todo_file);
4d55dfd767 builtin/rebase--interactive.c   54) res = todo_list_write_to_file(the_repository, &todo_list, todo_file,
4d55dfd767 builtin/rebase--interactive.c   56) todo_list_release(&todo_list);
4d55dfd767 builtin/rebase--interactive.c   58) if (res)
4d55dfd767 builtin/rebase--interactive.c   59) return error_errno(_("could not write '%s'."), todo_file);
4d55dfd767 builtin/rebase--interactive.c   60) return 0;
0566a4f68e builtin/rebase--interactive.c  121) struct todo_list todo_list = TODO_LIST_INIT;
0566a4f68e builtin/rebase--interactive.c  147) ret = sequencer_make_script(the_repository, &todo_list.buf,
c1c074e0cc builtin/rebase--interactive.c  155) if (todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
c1c074e0cc builtin/rebase--interactive.c  159) ret = complete_action(the_repository, opts, flags, shortrevisions, onto_name,
0566a4f68e builtin/rebase--interactive.c  165) todo_list_release(&todo_list);
8414c890aa builtin/rebase--interactive.c  269) if (cmd && *cmd) {
8414c890aa builtin/rebase--interactive.c  270) string_list_split(&commands, cmd, '\n', -1);
8414c890aa builtin/rebase--interactive.c  271) if (strlen(commands.items[commands.nr - 1].string) == 0)
8414c890aa builtin/rebase--interactive.c  272) --commands.nr;
e5b1c9d929 builtin/rebase--interactive.c  294) ret = edit_todo_file(flags);
4d55dfd767 builtin/rebase--interactive.c  307) ret = transform_todo_file(flags);
c27b32f0ec builtin/rebase--interactive.c  310) ret = check_todo_list_from_file(the_repository);
febebd99b6 builtin/rebase--interactive.c  313) ret = rearrange_squash_in_todo_file(the_repository);
8414c890aa builtin/rebase--interactive.c  316) ret = sequencer_add_exec_commands(the_repository, &commands);

builtin/rebase.c
b6b4172bfb  423) if (repo_read_index_unmerged(the_repository) < 0) {
e1ff0a32e4 1236) if (repo_read_index(the_repository) < 0)
1b0d968b34 1241) repo_update_index_if_able(the_repository, &lock_file);
e1ff0a32e4 1593) if (repo_read_index(the_repository) < 0)
1b0d968b34 1603) repo_update_index_if_able(the_repository, &lock_file);
e1ff0a32e4 1648) repo_read_index(the_repository) < 0)

builtin/replace.c
4478671442 builtin/replace.c 298) if (index_fd(the_repository->index, oid, fd, &st, type, NULL, flags) < 0)

builtin/stash.c
f6bbd78127 builtin/stash--helper.c  117) static void free_stash_info(struct stash_info *info)
f6bbd78127 builtin/stash--helper.c  119) strbuf_release(&info->revision);
f6bbd78127 builtin/stash--helper.c  120) }
f6bbd78127 builtin/stash--helper.c  122) static void assert_stash_like(struct stash_info *info, const char *revision)
f6bbd78127 builtin/stash--helper.c  124) if (get_oidf(&info->b_commit, "%s^1", revision) ||
f6bbd78127 builtin/stash--helper.c  125)     get_oidf(&info->w_tree, "%s:", revision) ||
f6bbd78127 builtin/stash--helper.c  126)     get_oidf(&info->b_tree, "%s^1:", revision) ||
f6bbd78127 builtin/stash--helper.c  127)     get_oidf(&info->i_tree, "%s^2:", revision))
f6bbd78127 builtin/stash--helper.c  128) die(_("'%s' is not a stash-like commit"), revision);
f6bbd78127 builtin/stash--helper.c  129) }
f6bbd78127 builtin/stash--helper.c  131) static int get_stash_info(struct stash_info *info, int argc, const char **argv)
f6bbd78127 builtin/stash--helper.c  137) const char *commit = NULL;
f6bbd78127 builtin/stash--helper.c  139) struct strbuf symbolic = STRBUF_INIT;
f6bbd78127 builtin/stash--helper.c  141) if (argc > 1) {
f6bbd78127 builtin/stash--helper.c  143) struct strbuf refs_msg = STRBUF_INIT;
f6bbd78127 builtin/stash--helper.c  145) for (i = 0; i < argc; i++)
f6bbd78127 builtin/stash--helper.c  146) strbuf_addf(&refs_msg, " '%s'", argv[i]);
f6bbd78127 builtin/stash--helper.c  148) fprintf_ln(stderr, _("Too many revisions specified:%s"),
f6bbd78127 builtin/stash--helper.c  150) strbuf_release(&refs_msg);
f6bbd78127 builtin/stash--helper.c  152) return -1;
f6bbd78127 builtin/stash--helper.c  155) if (argc == 1)
f6bbd78127 builtin/stash--helper.c  156) commit = argv[0];
f6bbd78127 builtin/stash--helper.c  158) strbuf_init(&info->revision, 0);
f6bbd78127 builtin/stash--helper.c  159) if (!commit) {
f6bbd78127 builtin/stash--helper.c  160) if (!ref_exists(ref_stash)) {
f6bbd78127 builtin/stash--helper.c  161) free_stash_info(info);
f6bbd78127 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash entries found."));
f6bbd78127 builtin/stash--helper.c  163) return -1;
f6bbd78127 builtin/stash--helper.c  166) strbuf_addf(&info->revision, "%s@{0}", ref_stash);
f6bbd78127 builtin/stash--helper.c  167) } else if (strspn(commit, "0123456789") == strlen(commit)) {
f6bbd78127 builtin/stash--helper.c  168) strbuf_addf(&info->revision, "%s@{%s}", ref_stash, commit);
f6bbd78127 builtin/stash--helper.c  170) strbuf_addstr(&info->revision, commit);
f6bbd78127 builtin/stash--helper.c  173) revision = info->revision.buf;
f6bbd78127 builtin/stash--helper.c  175) if (get_oid(revision, &info->w_commit)) {
f6bbd78127 builtin/stash--helper.c  176) error(_("%s is not a valid reference"), revision);
f6bbd78127 builtin/stash--helper.c  177) free_stash_info(info);
f6bbd78127 builtin/stash--helper.c  178) return -1;
f6bbd78127 builtin/stash--helper.c  181) assert_stash_like(info, revision);
f6bbd78127 builtin/stash--helper.c  183) info->has_u = !get_oidf(&info->u_tree, "%s^3:", revision);
f6bbd78127 builtin/stash--helper.c  185) end_of_rev = strchrnul(revision, '@');
f6bbd78127 builtin/stash--helper.c  186) strbuf_add(&symbolic, revision, end_of_rev - revision);
f6bbd78127 builtin/stash--helper.c  188) ret = dwim_ref(symbolic.buf, symbolic.len, &dummy, &expanded_ref);
f6bbd78127 builtin/stash--helper.c  189) strbuf_release(&symbolic);
f6bbd78127 builtin/stash--helper.c  190) switch (ret) {
f6bbd78127 builtin/stash--helper.c  192) info->is_stash_ref = 0;
f6bbd78127 builtin/stash--helper.c  193) break;
f6bbd78127 builtin/stash--helper.c  195) info->is_stash_ref = !strcmp(expanded_ref, ref_stash);
f6bbd78127 builtin/stash--helper.c  196) break;
f6bbd78127 builtin/stash--helper.c  198) free_stash_info(info);
f6bbd78127 builtin/stash--helper.c  201) free(expanded_ref);
f6bbd78127 builtin/stash--helper.c  202) return !(ret == 0 || ret == 1);
cdca49bc4c builtin/stash--helper.c  205) static int do_clear_stash(void)
cdca49bc4c builtin/stash--helper.c  208) if (get_oid(ref_stash, &obj))
cdca49bc4c builtin/stash--helper.c  209) return 0;
cdca49bc4c builtin/stash--helper.c  211) return delete_ref(NULL, ref_stash, &obj, 0);
cdca49bc4c builtin/stash--helper.c  214) static int clear_stash(int argc, const char **argv, const char *prefix)
cdca49bc4c builtin/stash--helper.c  216) struct option options[] = {
cdca49bc4c builtin/stash--helper.c  220) argc = parse_options(argc, argv, prefix, options,
cdca49bc4c builtin/stash--helper.c  224) if (argc)
cdca49bc4c builtin/stash--helper.c  225) return error(_("git stash clear with parameters is "
cdca49bc4c builtin/stash--helper.c  228) return do_clear_stash();
f6bbd78127 builtin/stash--helper.c  231) static int reset_tree(struct object_id *i_tree, int update, int reset)
f6bbd78127 builtin/stash--helper.c  233) int nr_trees = 1;
f6bbd78127 builtin/stash--helper.c  237) struct lock_file lock_file = LOCK_INIT;
f6bbd78127 builtin/stash--helper.c  239) read_cache_preload(NULL);
f6bbd78127 builtin/stash--helper.c  240) if (refresh_cache(REFRESH_QUIET))
f6bbd78127 builtin/stash--helper.c  241) return -1;
f6bbd78127 builtin/stash--helper.c  243) hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
f6bbd78127 builtin/stash--helper.c  245) memset(&opts, 0, sizeof(opts));
f6bbd78127 builtin/stash--helper.c  247) tree = parse_tree_indirect(i_tree);
f6bbd78127 builtin/stash--helper.c  248) if (parse_tree(tree))
f6bbd78127 builtin/stash--helper.c  249) return -1;
f6bbd78127 builtin/stash--helper.c  251) init_tree_desc(t, tree->buffer, tree->size);
f6bbd78127 builtin/stash--helper.c  253) opts.head_idx = 1;
f6bbd78127 builtin/stash--helper.c  254) opts.src_index = &the_index;
f6bbd78127 builtin/stash--helper.c  255) opts.dst_index = &the_index;
f6bbd78127 builtin/stash--helper.c  256) opts.merge = 1;
f6bbd78127 builtin/stash--helper.c  257) opts.reset = reset;
f6bbd78127 builtin/stash--helper.c  258) opts.update = update;
f6bbd78127 builtin/stash--helper.c  259) opts.fn = oneway_merge;
f6bbd78127 builtin/stash--helper.c  261) if (unpack_trees(nr_trees, t, &opts))
f6bbd78127 builtin/stash--helper.c  262) return -1;
f6bbd78127 builtin/stash--helper.c  264) if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
f6bbd78127 builtin/stash--helper.c  265) return error(_("unable to write new index file"));
f6bbd78127 builtin/stash--helper.c  267) return 0;
f6bbd78127 builtin/stash--helper.c  270) static int diff_tree_binary(struct strbuf *out, struct object_id *w_commit)
f6bbd78127 builtin/stash--helper.c  272) struct child_process cp = CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  273) const char *w_commit_hex = oid_to_hex(w_commit);
f6bbd78127 builtin/stash--helper.c  279) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  280) argv_array_pushl(&cp.args, "diff-tree", "--binary", NULL);
f6bbd78127 builtin/stash--helper.c  281) argv_array_pushf(&cp.args, "%s^2^..%s^2", w_commit_hex, w_commit_hex);
f6bbd78127 builtin/stash--helper.c  283) return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
f6bbd78127 builtin/stash--helper.c  286) static int apply_cached(struct strbuf *out)
f6bbd78127 builtin/stash--helper.c  288) struct child_process cp = CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  295) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  296) argv_array_pushl(&cp.args, "apply", "--cached", NULL);
f6bbd78127 builtin/stash--helper.c  297) return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0);
f6bbd78127 builtin/stash--helper.c  300) static int reset_head(void)
f6bbd78127 builtin/stash--helper.c  302) struct child_process cp = CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  308) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  309) argv_array_push(&cp.args, "reset");
f6bbd78127 builtin/stash--helper.c  311) return run_command(&cp);
1f5a011d90 builtin/stash--helper.c  314) static void add_diff_to_buf(struct diff_queue_struct *q,
1f5a011d90 builtin/stash--helper.c  320) for (i = 0; i < q->nr; i++) {
1f5a011d90 builtin/stash--helper.c  321) strbuf_addstr(data, q->queue[i]->one->path);
1f5a011d90 builtin/stash--helper.c  328) strbuf_addch(data, '\0');
1f5a011d90 builtin/stash--helper.c  330) }
f6bbd78127 builtin/stash--helper.c  332) static int get_newly_staged(struct strbuf *out, struct object_id *c_tree)
f6bbd78127 builtin/stash--helper.c  334) struct child_process cp = CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  335) const char *c_tree_hex = oid_to_hex(c_tree);
f6bbd78127 builtin/stash--helper.c  341) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  342) argv_array_pushl(&cp.args, "diff-index", "--cached", "--name-only",
f6bbd78127 builtin/stash--helper.c  344) argv_array_push(&cp.args, c_tree_hex);
f6bbd78127 builtin/stash--helper.c  345) return pipe_command(&cp, NULL, 0, out, 0, NULL, 0);
f6bbd78127 builtin/stash--helper.c  348) static int update_index(struct strbuf *out)
f6bbd78127 builtin/stash--helper.c  350) struct child_process cp = CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  356) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  357) argv_array_pushl(&cp.args, "update-index", "--add", "--stdin", NULL);
f6bbd78127 builtin/stash--helper.c  358) return pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0);
f6bbd78127 builtin/stash--helper.c  361) static int restore_untracked(struct object_id *u_tree)
f6bbd78127 builtin/stash--helper.c  364) struct child_process cp = CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  371) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  372) argv_array_push(&cp.args, "read-tree");
f6bbd78127 builtin/stash--helper.c  373) argv_array_push(&cp.args, oid_to_hex(u_tree));
f6bbd78127 builtin/stash--helper.c  374) argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s",
f6bbd78127 builtin/stash--helper.c  376) if (run_command(&cp)) {
f6bbd78127 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
f6bbd78127 builtin/stash--helper.c  378) return -1;
f6bbd78127 builtin/stash--helper.c  381) child_process_init(&cp);
f6bbd78127 builtin/stash--helper.c  382) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  383) argv_array_pushl(&cp.args, "checkout-index", "--all", NULL);
f6bbd78127 builtin/stash--helper.c  384) argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s",
f6bbd78127 builtin/stash--helper.c  387) res = run_command(&cp);
f6bbd78127 builtin/stash--helper.c  388) remove_path(stash_index_path.buf);
f6bbd78127 builtin/stash--helper.c  389) return res;
f6bbd78127 builtin/stash--helper.c  392) static int do_apply_stash(const char *prefix, struct stash_info *info,
f6bbd78127 builtin/stash--helper.c  396) int has_index = index;
f6bbd78127 builtin/stash--helper.c  403) read_cache_preload(NULL);
f6bbd78127 builtin/stash--helper.c  404) if (refresh_cache(REFRESH_QUIET))
f6bbd78127 builtin/stash--helper.c  405) return -1;
f6bbd78127 builtin/stash--helper.c  407) if (write_cache_as_tree(&c_tree, 0, NULL) || reset_tree(&c_tree, 0, 0))
f6bbd78127 builtin/stash--helper.c  408) return error(_("cannot apply a stash in the middle of a merge"));
f6bbd78127 builtin/stash--helper.c  410) if (index) {
f6bbd78127 builtin/stash--helper.c  411) if (oideq(&info->b_tree, &info->i_tree) ||
f6bbd78127 builtin/stash--helper.c  412)     oideq(&c_tree, &info->i_tree)) {
f6bbd78127 builtin/stash--helper.c  413) has_index = 0;
f6bbd78127 builtin/stash--helper.c  415) struct strbuf out = STRBUF_INIT;
f6bbd78127 builtin/stash--helper.c  417) if (diff_tree_binary(&out, &info->w_commit)) {
f6bbd78127 builtin/stash--helper.c  418) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  419) return error(_("could not generate diff %s^!."),
f6bbd78127 builtin/stash--helper.c  423) ret = apply_cached(&out);
f6bbd78127 builtin/stash--helper.c  424) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  425) if (ret)
f6bbd78127 builtin/stash--helper.c  426) return error(_("conflicts in index."
f6bbd78127 builtin/stash--helper.c  429) discard_cache();
f6bbd78127 builtin/stash--helper.c  430) read_cache();
f6bbd78127 builtin/stash--helper.c  431) if (write_cache_as_tree(&index_tree, 0, NULL))
f6bbd78127 builtin/stash--helper.c  432) return error(_("could not save index tree"));
f6bbd78127 builtin/stash--helper.c  434) reset_head();
f6bbd78127 builtin/stash--helper.c  438) if (info->has_u && restore_untracked(&info->u_tree))
f6bbd78127 builtin/stash--helper.c  439) return error(_("could not restore untracked files from stash"));
b6b4172bfb builtin/stash.c          441) init_merge_options(&o, the_repository);
f6bbd78127 builtin/stash--helper.c  443) o.branch1 = "Updated upstream";
f6bbd78127 builtin/stash--helper.c  444) o.branch2 = "Stashed changes";
f6bbd78127 builtin/stash--helper.c  446) if (oideq(&info->b_tree, &c_tree))
f6bbd78127 builtin/stash--helper.c  447) o.branch1 = "Version stash was based on";
f6bbd78127 builtin/stash--helper.c  449) if (quiet)
f6bbd78127 builtin/stash--helper.c  450) o.verbosity = 0;
f6bbd78127 builtin/stash--helper.c  452) if (o.verbosity >= 3)
f6bbd78127 builtin/stash--helper.c  453) printf_ln(_("Merging %s with %s"), o.branch1, o.branch2);
f6bbd78127 builtin/stash--helper.c  455) bases[0] = &info->b_tree;
f6bbd78127 builtin/stash--helper.c  457) ret = merge_recursive_generic(&o, &c_tree, &info->w_tree, 1, bases,
f6bbd78127 builtin/stash--helper.c  459) if (ret) {
f6bbd78127 builtin/stash--helper.c  460) rerere(0);
f6bbd78127 builtin/stash--helper.c  462) if (index)
f6bbd78127 builtin/stash--helper.c  463) fprintf_ln(stderr, _("Index was not unstashed."));
f6bbd78127 builtin/stash--helper.c  465) return ret;
f6bbd78127 builtin/stash--helper.c  468) if (has_index) {
f6bbd78127 builtin/stash--helper.c  469) if (reset_tree(&index_tree, 0, 0))
f6bbd78127 builtin/stash--helper.c  470) return -1;
f6bbd78127 builtin/stash--helper.c  472) struct strbuf out = STRBUF_INIT;
f6bbd78127 builtin/stash--helper.c  474) if (get_newly_staged(&out, &c_tree)) {
f6bbd78127 builtin/stash--helper.c  475) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  476) return -1;
f6bbd78127 builtin/stash--helper.c  479) if (reset_tree(&c_tree, 0, 1)) {
f6bbd78127 builtin/stash--helper.c  480) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  481) return -1;
f6bbd78127 builtin/stash--helper.c  484) ret = update_index(&out);
f6bbd78127 builtin/stash--helper.c  485) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  486) if (ret)
f6bbd78127 builtin/stash--helper.c  487) return -1;
f6bbd78127 builtin/stash--helper.c  489) discard_cache();
f6bbd78127 builtin/stash--helper.c  492) if (quiet) {
f6bbd78127 builtin/stash--helper.c  493) if (refresh_cache(REFRESH_QUIET))
f6bbd78127 builtin/stash--helper.c  494) warning("could not refresh index");
f6bbd78127 builtin/stash--helper.c  496) struct child_process cp = CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  503) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  504) cp.dir = prefix;
f6bbd78127 builtin/stash--helper.c  505) argv_array_push(&cp.args, "status");
f6bbd78127 builtin/stash--helper.c  506) run_command(&cp);
f6bbd78127 builtin/stash--helper.c  509) return 0;
f6bbd78127 builtin/stash--helper.c  512) static int apply_stash(int argc, const char **argv, const char *prefix)
f6bbd78127 builtin/stash--helper.c  515) int quiet = 0;
f6bbd78127 builtin/stash--helper.c  516) int index = 0;
f6bbd78127 builtin/stash--helper.c  518) struct option options[] = {
f6bbd78127 builtin/stash--helper.c  525) argc = parse_options(argc, argv, prefix, options,
f6bbd78127 builtin/stash--helper.c  528) if (get_stash_info(&info, argc, argv))
f6bbd78127 builtin/stash--helper.c  529) return -1;
f6bbd78127 builtin/stash--helper.c  531) ret = do_apply_stash(prefix, &info, index, quiet);
f6bbd78127 builtin/stash--helper.c  532) free_stash_info(&info);
f6bbd78127 builtin/stash--helper.c  533) return ret;
cdca49bc4c builtin/stash--helper.c  536) static int do_drop_stash(const char *prefix, struct stash_info *info, int quiet)
cdca49bc4c builtin/stash--helper.c  539) struct child_process cp_reflog = CHILD_PROCESS_INIT;
cdca49bc4c builtin/stash--helper.c  540) struct child_process cp = CHILD_PROCESS_INIT;
cdca49bc4c builtin/stash--helper.c  547) cp_reflog.git_cmd = 1;
cdca49bc4c builtin/stash--helper.c  548) argv_array_pushl(&cp_reflog.args, "reflog", "delete", "--updateref",
cdca49bc4c builtin/stash--helper.c  550) argv_array_push(&cp_reflog.args, info->revision.buf);
cdca49bc4c builtin/stash--helper.c  551) ret = run_command(&cp_reflog);
cdca49bc4c builtin/stash--helper.c  552) if (!ret) {
cdca49bc4c builtin/stash--helper.c  553) if (!quiet)
cdca49bc4c builtin/stash--helper.c  554) printf_ln(_("Dropped %s (%s)"), info->revision.buf,
cdca49bc4c builtin/stash--helper.c  555)   oid_to_hex(&info->w_commit));
cdca49bc4c builtin/stash--helper.c  557) return error(_("%s: Could not drop stash entry"),
cdca49bc4c builtin/stash--helper.c  565) cp.git_cmd = 1;
cdca49bc4c builtin/stash--helper.c  567) cp.no_stdout = 1;
cdca49bc4c builtin/stash--helper.c  568) argv_array_pushl(&cp.args, "rev-parse", "--verify", "--quiet", NULL);
cdca49bc4c builtin/stash--helper.c  569) argv_array_pushf(&cp.args, "%s@{0}", ref_stash);
cdca49bc4c builtin/stash--helper.c  570) ret = run_command(&cp);
cdca49bc4c builtin/stash--helper.c  573) if (ret)
cdca49bc4c builtin/stash--helper.c  574) do_clear_stash();
cdca49bc4c builtin/stash--helper.c  576) return 0;
cdca49bc4c builtin/stash--helper.c  579) static void assert_stash_ref(struct stash_info *info)
cdca49bc4c builtin/stash--helper.c  581) if (!info->is_stash_ref) {
cdca49bc4c builtin/stash--helper.c  582) free_stash_info(info);
cdca49bc4c builtin/stash--helper.c  583) error(_("'%s' is not a stash reference"), info->revision.buf);
cdca49bc4c builtin/stash--helper.c  584) exit(128);
cdca49bc4c builtin/stash--helper.c  586) }
cdca49bc4c builtin/stash--helper.c  588) static int drop_stash(int argc, const char **argv, const char *prefix)
cdca49bc4c builtin/stash--helper.c  591) int quiet = 0;
cdca49bc4c builtin/stash--helper.c  593) struct option options[] = {
cdca49bc4c builtin/stash--helper.c  598) argc = parse_options(argc, argv, prefix, options,
cdca49bc4c builtin/stash--helper.c  601) if (get_stash_info(&info, argc, argv))
cdca49bc4c builtin/stash--helper.c  602) return -1;
cdca49bc4c builtin/stash--helper.c  604) assert_stash_ref(&info);
cdca49bc4c builtin/stash--helper.c  606) ret = do_drop_stash(prefix, &info, quiet);
cdca49bc4c builtin/stash--helper.c  607) free_stash_info(&info);
cdca49bc4c builtin/stash--helper.c  608) return ret;
e1d01876a4 builtin/stash--helper.c  611) static int pop_stash(int argc, const char **argv, const char *prefix)
e1d01876a4 builtin/stash--helper.c  614) int index = 0;
e1d01876a4 builtin/stash--helper.c  615) int quiet = 0;
e1d01876a4 builtin/stash--helper.c  617) struct option options[] = {
e1d01876a4 builtin/stash--helper.c  624) argc = parse_options(argc, argv, prefix, options,
e1d01876a4 builtin/stash--helper.c  627) if (get_stash_info(&info, argc, argv))
e1d01876a4 builtin/stash--helper.c  628) return -1;
e1d01876a4 builtin/stash--helper.c  630) assert_stash_ref(&info);
e1d01876a4 builtin/stash--helper.c  631) if ((ret = do_apply_stash(prefix, &info, index, quiet)))
e1d01876a4 builtin/stash--helper.c  632) printf_ln(_("The stash entry is kept in case "
e1d01876a4 builtin/stash--helper.c  635) ret = do_drop_stash(prefix, &info, quiet);
e1d01876a4 builtin/stash--helper.c  637) free_stash_info(&info);
e1d01876a4 builtin/stash--helper.c  638) return ret;
f596f3366c builtin/stash--helper.c  641) static int branch_stash(int argc, const char **argv, const char *prefix)
f596f3366c builtin/stash--helper.c  644) const char *branch = NULL;
f596f3366c builtin/stash--helper.c  646) struct child_process cp = CHILD_PROCESS_INIT;
f596f3366c builtin/stash--helper.c  647) struct option options[] = {
f596f3366c builtin/stash--helper.c  651) argc = parse_options(argc, argv, prefix, options,
f596f3366c builtin/stash--helper.c  654) if (!argc) {
f596f3366c builtin/stash--helper.c  655) fprintf_ln(stderr, _("No branch name specified"));
f596f3366c builtin/stash--helper.c  656) return -1;
f596f3366c builtin/stash--helper.c  659) branch = argv[0];
f596f3366c builtin/stash--helper.c  661) if (get_stash_info(&info, argc - 1, argv + 1))
f596f3366c builtin/stash--helper.c  662) return -1;
f596f3366c builtin/stash--helper.c  664) cp.git_cmd = 1;
f596f3366c builtin/stash--helper.c  665) argv_array_pushl(&cp.args, "checkout", "-b", NULL);
f596f3366c builtin/stash--helper.c  666) argv_array_push(&cp.args, branch);
f596f3366c builtin/stash--helper.c  667) argv_array_push(&cp.args, oid_to_hex(&info.b_commit));
f596f3366c builtin/stash--helper.c  668) ret = run_command(&cp);
f596f3366c builtin/stash--helper.c  669) if (!ret)
f596f3366c builtin/stash--helper.c  670) ret = do_apply_stash(prefix, &info, 1, 0);
f596f3366c builtin/stash--helper.c  671) if (!ret && info.is_stash_ref)
f596f3366c builtin/stash--helper.c  672) ret = do_drop_stash(prefix, &info, 0);
f596f3366c builtin/stash--helper.c  674) free_stash_info(&info);
f596f3366c builtin/stash--helper.c  676) return ret;
9b77b07ba4 builtin/stash--helper.c  679) static int list_stash(int argc, const char **argv, const char *prefix)
9b77b07ba4 builtin/stash--helper.c  681) struct child_process cp = CHILD_PROCESS_INIT;
9b77b07ba4 builtin/stash--helper.c  682) struct option options[] = {
9b77b07ba4 builtin/stash--helper.c  686) argc = parse_options(argc, argv, prefix, options,
9b77b07ba4 builtin/stash--helper.c  690) if (!ref_exists(ref_stash))
9b77b07ba4 builtin/stash--helper.c  691) return 0;
9b77b07ba4 builtin/stash--helper.c  693) cp.git_cmd = 1;
9b77b07ba4 builtin/stash--helper.c  694) argv_array_pushl(&cp.args, "log", "--format=%gd: %gs", "-g",
9b77b07ba4 builtin/stash--helper.c  696) argv_array_pushv(&cp.args, argv);
9b77b07ba4 builtin/stash--helper.c  697) argv_array_push(&cp.args, ref_stash);
9b77b07ba4 builtin/stash--helper.c  698) argv_array_push(&cp.args, "--");
9b77b07ba4 builtin/stash--helper.c  699) return run_command(&cp);
b4493f269e builtin/stash--helper.c  705) static int git_stash_config(const char *var, const char *value, void *cb)
b4493f269e builtin/stash--helper.c  707) if (!strcmp(var, "stash.showstat")) {
b4493f269e builtin/stash--helper.c  708) show_stat = git_config_bool(var, value);
b4493f269e builtin/stash--helper.c  709) return 0;
b4493f269e builtin/stash--helper.c  711) if (!strcmp(var, "stash.showpatch")) {
b4493f269e builtin/stash--helper.c  712) show_patch = git_config_bool(var, value);
b4493f269e builtin/stash--helper.c  713) return 0;
b4493f269e builtin/stash--helper.c  715) return git_default_config(var, value, cb);
b4493f269e builtin/stash--helper.c  718) static int show_stash(int argc, const char **argv, const char *prefix)
b4493f269e builtin/stash--helper.c  721) int opts = 0;
b4493f269e builtin/stash--helper.c  722) int ret = 0;
b4493f269e builtin/stash--helper.c  725) struct argv_array stash_args = ARGV_ARRAY_INIT;
b4493f269e builtin/stash--helper.c  726) struct option options[] = {
b4493f269e builtin/stash--helper.c  730) init_diff_ui_defaults();
b4493f269e builtin/stash--helper.c  731) git_config(git_diff_ui_config, NULL);
b4493f269e builtin/stash--helper.c  732) init_revisions(&rev, prefix);
b4493f269e builtin/stash--helper.c  734) for (i = 1; i < argc; i++) {
b4493f269e builtin/stash--helper.c  735) if (argv[i][0] != '-')
b4493f269e builtin/stash--helper.c  736) argv_array_push(&stash_args, argv[i]);
b4493f269e builtin/stash--helper.c  738) opts++;
b4493f269e builtin/stash--helper.c  741) ret = get_stash_info(&info, stash_args.argc, stash_args.argv);
b4493f269e builtin/stash--helper.c  742) argv_array_clear(&stash_args);
b4493f269e builtin/stash--helper.c  743) if (ret)
b4493f269e builtin/stash--helper.c  744) return -1;
b4493f269e builtin/stash--helper.c  750) if (!opts) {
b4493f269e builtin/stash--helper.c  751) git_config(git_stash_config, NULL);
b4493f269e builtin/stash--helper.c  752) if (show_stat)
b4493f269e builtin/stash--helper.c  753) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT;
b4493f269e builtin/stash--helper.c  755) if (show_patch)
b4493f269e builtin/stash--helper.c  756) rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
b4493f269e builtin/stash--helper.c  758) if (!show_stat && !show_patch) {
b4493f269e builtin/stash--helper.c  759) free_stash_info(&info);
b4493f269e builtin/stash--helper.c  760) return 0;
b4493f269e builtin/stash--helper.c  764) argc = setup_revisions(argc, argv, &rev, NULL);
b4493f269e builtin/stash--helper.c  765) if (argc > 1) {
b4493f269e builtin/stash--helper.c  766) free_stash_info(&info);
51809c70ca builtin/stash.c          767) usage_with_options(git_stash_show_usage, options);
b4493f269e builtin/stash--helper.c  770) rev.diffopt.flags.recursive = 1;
b4493f269e builtin/stash--helper.c  771) setup_diff_pager(&rev.diffopt);
b4493f269e builtin/stash--helper.c  772) diff_tree_oid(&info.b_commit, &info.w_commit, "", &rev.diffopt);
b4493f269e builtin/stash--helper.c  773) log_tree_diff_flush(&rev);
b4493f269e builtin/stash--helper.c  775) free_stash_info(&info);
b4493f269e builtin/stash--helper.c  776) return diff_result_code(&rev.diffopt, 0);
847eb0b0a8 builtin/stash--helper.c  779) static int do_store_stash(const struct object_id *w_commit, const char *stash_msg,
847eb0b0a8 builtin/stash--helper.c  782) if (!stash_msg)
847eb0b0a8 builtin/stash--helper.c  783) stash_msg = "Created via \"git stash store\".";
847eb0b0a8 builtin/stash--helper.c  785) if (update_ref(stash_msg, ref_stash, w_commit, NULL,
847eb0b0a8 builtin/stash--helper.c  789) if (!quiet) {
847eb0b0a8 builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot update %s with %s"),
847eb0b0a8 builtin/stash--helper.c  793) return -1;
847eb0b0a8 builtin/stash--helper.c  796) return 0;
847eb0b0a8 builtin/stash--helper.c  799) static int store_stash(int argc, const char **argv, const char *prefix)
847eb0b0a8 builtin/stash--helper.c  801) int quiet = 0;
847eb0b0a8 builtin/stash--helper.c  802) const char *stash_msg = NULL;
847eb0b0a8 builtin/stash--helper.c  805) struct option options[] = {
847eb0b0a8 builtin/stash--helper.c  812) argc = parse_options(argc, argv, prefix, options,
847eb0b0a8 builtin/stash--helper.c  816) if (argc != 1) {
847eb0b0a8 builtin/stash--helper.c  817) if (!quiet)
847eb0b0a8 builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git stash store\" requires one "
847eb0b0a8 builtin/stash--helper.c  820) return -1;
b6b4172bfb builtin/stash.c          823) if (get_oid_with_context(the_repository,
847eb0b0a8 builtin/stash--helper.c  826) if (!quiet)
847eb0b0a8 builtin/stash--helper.c  827) fprintf_ln(stderr, _("Cannot update %s with %s"),
847eb0b0a8 builtin/stash--helper.c  829) return -1;
847eb0b0a8 builtin/stash--helper.c  832) return do_store_stash(&obj, stash_msg, quiet);
1f5a011d90 builtin/stash--helper.c  835) static void add_pathspecs(struct argv_array *args,
1f5a011d90 builtin/stash--helper.c  839) for (i = 0; i < ps.nr; i++)
1f5a011d90 builtin/stash--helper.c  840) argv_array_push(args, ps.items[i].match);
1f5a011d90 builtin/stash--helper.c  841) }
1f5a011d90 builtin/stash--helper.c  850) static int get_untracked_files(struct pathspec ps, int include_untracked,
1f5a011d90 builtin/stash--helper.c  855) int found = 0;
1f5a011d90 builtin/stash--helper.c  859) memset(&dir, 0, sizeof(dir));
1f5a011d90 builtin/stash--helper.c  860) if (include_untracked != INCLUDE_ALL_FILES)
1f5a011d90 builtin/stash--helper.c  861) setup_standard_excludes(&dir);
1f5a011d90 builtin/stash--helper.c  863) seen = xcalloc(ps.nr, 1);
1f5a011d90 builtin/stash--helper.c  865) max_len = fill_directory(&dir, the_repository->index, &ps);
1f5a011d90 builtin/stash--helper.c  866) for (i = 0; i < dir.nr; i++) {
1f5a011d90 builtin/stash--helper.c  867) struct dir_entry *ent = dir.entries[i];
1f5a011d90 builtin/stash--helper.c  868) if (dir_path_match(&the_index, ent, &ps, max_len, seen)) {
1f5a011d90 builtin/stash--helper.c  869) found++;
1f5a011d90 builtin/stash--helper.c  870) strbuf_addstr(untracked_files, ent->name);
1f5a011d90 builtin/stash--helper.c  872) strbuf_addch(untracked_files, 0);
1f5a011d90 builtin/stash--helper.c  874) free(ent);
1f5a011d90 builtin/stash--helper.c  877) free(seen);
1f5a011d90 builtin/stash--helper.c  878) free(dir.entries);
1f5a011d90 builtin/stash--helper.c  879) free(dir.ignored);
1f5a011d90 builtin/stash--helper.c  880) clear_directory(&dir);
1f5a011d90 builtin/stash--helper.c  881) return found;
168e6cff5e builtin/stash--helper.c  892) static int check_changes_tracked_files(struct pathspec ps)
1f5a011d90 builtin/stash--helper.c  899) if (get_oid("HEAD", &dummy))
1f5a011d90 builtin/stash--helper.c  900) return -1;
1f5a011d90 builtin/stash--helper.c  902) if (read_cache() < 0)
1f5a011d90 builtin/stash--helper.c  903) return -1;
1f5a011d90 builtin/stash--helper.c  905) init_revisions(&rev, NULL);
1f5a011d90 builtin/stash--helper.c  906) rev.prune_data = ps;
1f5a011d90 builtin/stash--helper.c  908) rev.diffopt.flags.quick = 1;
1f5a011d90 builtin/stash--helper.c  909) rev.diffopt.flags.ignore_submodules = 1;
1f5a011d90 builtin/stash--helper.c  910) rev.abbrev = 0;
1f5a011d90 builtin/stash--helper.c  912) add_head_to_pending(&rev);
1f5a011d90 builtin/stash--helper.c  913) diff_setup_done(&rev.diffopt);
1f5a011d90 builtin/stash--helper.c  915) result = run_diff_index(&rev, 1);
1f5a011d90 builtin/stash--helper.c  916) if (diff_result_code(&rev.diffopt, result))
1f5a011d90 builtin/stash--helper.c  917) return 1;
1f5a011d90 builtin/stash--helper.c  919) object_array_clear(&rev.pending);
1f5a011d90 builtin/stash--helper.c  920) result = run_diff_files(&rev, 0);
1f5a011d90 builtin/stash--helper.c  921) if (diff_result_code(&rev.diffopt, result))
1f5a011d90 builtin/stash--helper.c  922) return 1;
168e6cff5e builtin/stash--helper.c  924) return 0;
168e6cff5e builtin/stash--helper.c  932) static int check_changes(struct pathspec ps, int include_untracked,
168e6cff5e builtin/stash--helper.c  935) int ret = 0;
168e6cff5e builtin/stash--helper.c  936) if (check_changes_tracked_files(ps))
168e6cff5e builtin/stash--helper.c  937) ret = 1;
1f5a011d90 builtin/stash--helper.c  939) if (include_untracked && get_untracked_files(ps, include_untracked,
168e6cff5e builtin/stash--helper.c  941) ret = 1;
168e6cff5e builtin/stash--helper.c  943) return ret;
1f5a011d90 builtin/stash--helper.c  946) static int save_untracked_files(struct stash_info *info, struct strbuf *msg,
1f5a011d90 builtin/stash--helper.c  949) int ret = 0;
1f5a011d90 builtin/stash--helper.c  950) struct strbuf untracked_msg = STRBUF_INIT;
1f5a011d90 builtin/stash--helper.c  951) struct child_process cp_upd_index = CHILD_PROCESS_INIT;
559edead8f builtin/stash--helper.c  952) struct index_state istate = { NULL };
1f5a011d90 builtin/stash--helper.c  954) cp_upd_index.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c  955) argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
1f5a011d90 builtin/stash--helper.c  957) argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
1f5a011d90 builtin/stash--helper.c  960) strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf);
1f5a011d90 builtin/stash--helper.c  961) if (pipe_command(&cp_upd_index, files.buf, files.len, NULL, 0,
1f5a011d90 builtin/stash--helper.c  963) ret = -1;
1f5a011d90 builtin/stash--helper.c  964) goto done;
559edead8f builtin/stash--helper.c  967) if (write_index_as_tree(&info->u_tree, &istate, stash_index_path.buf, 0,
1f5a011d90 builtin/stash--helper.c  969) ret = -1;
1f5a011d90 builtin/stash--helper.c  970) goto done;
1f5a011d90 builtin/stash--helper.c  973) if (commit_tree(untracked_msg.buf, untracked_msg.len,
1f5a011d90 builtin/stash--helper.c  974) &info->u_tree, NULL, &info->u_commit, NULL, NULL)) {
1f5a011d90 builtin/stash--helper.c  975) ret = -1;
1f5a011d90 builtin/stash--helper.c  976) goto done;
559edead8f builtin/stash--helper.c  980) discard_index(&istate);
1f5a011d90 builtin/stash--helper.c  981) strbuf_release(&untracked_msg);
1f5a011d90 builtin/stash--helper.c  982) remove_path(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c  983) return ret;
1f5a011d90 builtin/stash--helper.c  986) static int stash_patch(struct stash_info *info, struct pathspec ps,
1f5a011d90 builtin/stash--helper.c  989) int ret = 0;
1f5a011d90 builtin/stash--helper.c  990) struct child_process cp_read_tree = CHILD_PROCESS_INIT;
1f5a011d90 builtin/stash--helper.c  991) struct child_process cp_add_i = CHILD_PROCESS_INIT;
1f5a011d90 builtin/stash--helper.c  992) struct child_process cp_diff_tree = CHILD_PROCESS_INIT;
559edead8f builtin/stash--helper.c  993) struct index_state istate = { NULL };
1f5a011d90 builtin/stash--helper.c  995) remove_path(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c  997) cp_read_tree.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c  998) argv_array_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL);
1f5a011d90 builtin/stash--helper.c  999) argv_array_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s",
1f5a011d90 builtin/stash--helper.c 1001) if (run_command(&cp_read_tree)) {
1f5a011d90 builtin/stash--helper.c 1002) ret = -1;
1f5a011d90 builtin/stash--helper.c 1003) goto done;
1f5a011d90 builtin/stash--helper.c 1007) cp_add_i.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c 1008) argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash",
1f5a011d90 builtin/stash--helper.c 1010) add_pathspecs(&cp_add_i.args, ps);
1f5a011d90 builtin/stash--helper.c 1011) argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s",
1f5a011d90 builtin/stash--helper.c 1013) if (run_command(&cp_add_i)) {
1f5a011d90 builtin/stash--helper.c 1014) ret = -1;
1f5a011d90 builtin/stash--helper.c 1015) goto done;
559edead8f builtin/stash--helper.c 1019) if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0,
1f5a011d90 builtin/stash--helper.c 1021) ret = -1;
1f5a011d90 builtin/stash--helper.c 1022) goto done;
1f5a011d90 builtin/stash--helper.c 1025) cp_diff_tree.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c 1026) argv_array_pushl(&cp_diff_tree.args, "diff-tree", "-p", "HEAD",
1f5a011d90 builtin/stash--helper.c 1027)  oid_to_hex(&info->w_tree), "--", NULL);
1f5a011d90 builtin/stash--helper.c 1028) if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) {
1f5a011d90 builtin/stash--helper.c 1029) ret = -1;
1f5a011d90 builtin/stash--helper.c 1030) goto done;
1f5a011d90 builtin/stash--helper.c 1033) if (!out_patch->len) {
9a95010a11 builtin/stash--helper.c 1034) if (!quiet)
9a95010a11 builtin/stash--helper.c 1035) fprintf_ln(stderr, _("No changes selected"));
1f5a011d90 builtin/stash--helper.c 1036) ret = 1;
559edead8f builtin/stash--helper.c 1040) discard_index(&istate);
1f5a011d90 builtin/stash--helper.c 1041) remove_path(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c 1042) return ret;
1f5a011d90 builtin/stash--helper.c 1045) static int stash_working_tree(struct stash_info *info, struct pathspec ps)
1f5a011d90 builtin/stash--helper.c 1047) int ret = 0;
1f5a011d90 builtin/stash--helper.c 1049) struct child_process cp_upd_index = CHILD_PROCESS_INIT;
1f5a011d90 builtin/stash--helper.c 1050) struct strbuf diff_output = STRBUF_INIT;
559edead8f builtin/stash--helper.c 1051) struct index_state istate = { NULL };
ed5d77f7d3 builtin/stash.c         1053) init_revisions(&rev, NULL);
1f5a011d90 builtin/stash--helper.c 1055) set_alternate_index_output(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c 1056) if (reset_tree(&info->i_tree, 0, 0)) {
1f5a011d90 builtin/stash--helper.c 1057) ret = -1;
1f5a011d90 builtin/stash--helper.c 1058) goto done;
1f5a011d90 builtin/stash--helper.c 1060) set_alternate_index_output(NULL);
1f5a011d90 builtin/stash--helper.c 1062) rev.prune_data = ps;
1f5a011d90 builtin/stash--helper.c 1063) rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
1f5a011d90 builtin/stash--helper.c 1064) rev.diffopt.format_callback = add_diff_to_buf;
1f5a011d90 builtin/stash--helper.c 1065) rev.diffopt.format_callback_data = &diff_output;
1f5a011d90 builtin/stash--helper.c 1067) if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
1f5a011d90 builtin/stash--helper.c 1068) ret = -1;
1f5a011d90 builtin/stash--helper.c 1069) goto done;
1f5a011d90 builtin/stash--helper.c 1072) add_pending_object(&rev, parse_object(the_repository, &info->b_commit),
1f5a011d90 builtin/stash--helper.c 1074) if (run_diff_index(&rev, 0)) {
1f5a011d90 builtin/stash--helper.c 1075) ret = -1;
1f5a011d90 builtin/stash--helper.c 1076) goto done;
1f5a011d90 builtin/stash--helper.c 1079) cp_upd_index.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c 1080) argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
1f5a011d90 builtin/stash--helper.c 1082) argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
1f5a011d90 builtin/stash--helper.c 1085) if (pipe_command(&cp_upd_index, diff_output.buf, diff_output.len,
1f5a011d90 builtin/stash--helper.c 1087) ret = -1;
1f5a011d90 builtin/stash--helper.c 1088) goto done;
559edead8f builtin/stash--helper.c 1091) if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0,
1f5a011d90 builtin/stash--helper.c 1093) ret = -1;
1f5a011d90 builtin/stash--helper.c 1094) goto done;
559edead8f builtin/stash--helper.c 1098) discard_index(&istate);
1f5a011d90 builtin/stash--helper.c 1100) object_array_clear(&rev.pending);
1f5a011d90 builtin/stash--helper.c 1101) strbuf_release(&diff_output);
1f5a011d90 builtin/stash--helper.c 1102) remove_path(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c 1103) return ret;
1f5a011d90 builtin/stash--helper.c 1106) static int do_create_stash(struct pathspec ps, struct strbuf *stash_msg_buf,
1f5a011d90 builtin/stash--helper.c 1111) int ret = 0;
1f5a011d90 builtin/stash--helper.c 1112) int flags = 0;
1f5a011d90 builtin/stash--helper.c 1113) int untracked_commit_option = 0;
1f5a011d90 builtin/stash--helper.c 1114) const char *head_short_sha1 = NULL;
1f5a011d90 builtin/stash--helper.c 1115) const char *branch_ref = NULL;
1f5a011d90 builtin/stash--helper.c 1116) const char *branch_name = "(no branch)";
1f5a011d90 builtin/stash--helper.c 1117) struct commit *head_commit = NULL;
1f5a011d90 builtin/stash--helper.c 1118) struct commit_list *parents = NULL;
1f5a011d90 builtin/stash--helper.c 1119) struct strbuf msg = STRBUF_INIT;
1f5a011d90 builtin/stash--helper.c 1120) struct strbuf commit_tree_label = STRBUF_INIT;
1f5a011d90 builtin/stash--helper.c 1121) struct strbuf untracked_files = STRBUF_INIT;
1f5a011d90 builtin/stash--helper.c 1123) prepare_fallback_ident("git stash", "git@stash");
1f5a011d90 builtin/stash--helper.c 1125) read_cache_preload(NULL);
1f5a011d90 builtin/stash--helper.c 1126) refresh_cache(REFRESH_QUIET);
1f5a011d90 builtin/stash--helper.c 1128) if (get_oid("HEAD", &info->b_commit)) {
9a95010a11 builtin/stash--helper.c 1129) if (!quiet)
9a95010a11 builtin/stash--helper.c 1130) fprintf_ln(stderr, _("You do not have "
1f5a011d90 builtin/stash--helper.c 1132) ret = -1;
1f5a011d90 builtin/stash--helper.c 1133) goto done;
1f5a011d90 builtin/stash--helper.c 1135) head_commit = lookup_commit(the_repository, &info->b_commit);
168e6cff5e builtin/stash--helper.c 1138) if (!check_changes(ps, include_untracked, &untracked_files)) {
1f5a011d90 builtin/stash--helper.c 1139) ret = 1;
1f5a011d90 builtin/stash--helper.c 1140) goto done;
1f5a011d90 builtin/stash--helper.c 1143) branch_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flags);
1f5a011d90 builtin/stash--helper.c 1144) if (flags & REF_ISSYMREF)
1f5a011d90 builtin/stash--helper.c 1145) branch_name = strrchr(branch_ref, '/') + 1;
1f5a011d90 builtin/stash--helper.c 1146) head_short_sha1 = find_unique_abbrev(&head_commit->object.oid,
1f5a011d90 builtin/stash--helper.c 1148) strbuf_addf(&msg, "%s: %s ", branch_name, head_short_sha1);
1f5a011d90 builtin/stash--helper.c 1149) pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg);
1f5a011d90 builtin/stash--helper.c 1151) strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf);
1f5a011d90 builtin/stash--helper.c 1152) commit_list_insert(head_commit, &parents);
1f5a011d90 builtin/stash--helper.c 1153) if (write_cache_as_tree(&info->i_tree, 0, NULL) ||
1f5a011d90 builtin/stash--helper.c 1154)     commit_tree(commit_tree_label.buf, commit_tree_label.len,
1f5a011d90 builtin/stash--helper.c 1155) &info->i_tree, parents, &info->i_commit, NULL, NULL)) {
9a95010a11 builtin/stash--helper.c 1156) if (!quiet)
9a95010a11 builtin/stash--helper.c 1157) fprintf_ln(stderr, _("Cannot save the current "
1f5a011d90 builtin/stash--helper.c 1159) ret = -1;
1f5a011d90 builtin/stash--helper.c 1160) goto done;
168e6cff5e builtin/stash--helper.c 1163) if (include_untracked) {
1f5a011d90 builtin/stash--helper.c 1164) if (save_untracked_files(info, &msg, untracked_files)) {
9a95010a11 builtin/stash--helper.c 1165) if (!quiet)
9a95010a11 builtin/stash--helper.c 1166) fprintf_ln(stderr, _("Cannot save "
1f5a011d90 builtin/stash--helper.c 1168) ret = -1;
1f5a011d90 builtin/stash--helper.c 1169) goto done;
1f5a011d90 builtin/stash--helper.c 1171) untracked_commit_option = 1;
1f5a011d90 builtin/stash--helper.c 1173) if (patch_mode) {
9a95010a11 builtin/stash--helper.c 1174) ret = stash_patch(info, ps, patch, quiet);
1f5a011d90 builtin/stash--helper.c 1175) if (ret < 0) {
9a95010a11 builtin/stash--helper.c 1176) if (!quiet)
9a95010a11 builtin/stash--helper.c 1177) fprintf_ln(stderr, _("Cannot save the current "
1f5a011d90 builtin/stash--helper.c 1179) goto done;
1f5a011d90 builtin/stash--helper.c 1180) } else if (ret > 0) {
1f5a011d90 builtin/stash--helper.c 1181) goto done;
1f5a011d90 builtin/stash--helper.c 1184) if (stash_working_tree(info, ps)) {
9a95010a11 builtin/stash--helper.c 1185) if (!quiet)
9a95010a11 builtin/stash--helper.c 1186) fprintf_ln(stderr, _("Cannot save the current "
1f5a011d90 builtin/stash--helper.c 1188) ret = -1;
1f5a011d90 builtin/stash--helper.c 1189) goto done;
1f5a011d90 builtin/stash--helper.c 1193) if (!stash_msg_buf->len)
1f5a011d90 builtin/stash--helper.c 1194) strbuf_addf(stash_msg_buf, "WIP on %s", msg.buf);
1f5a011d90 builtin/stash--helper.c 1196) strbuf_insertf(stash_msg_buf, 0, "On %s: ", branch_name);
1f5a011d90 builtin/stash--helper.c 1202) parents = NULL;
1f5a011d90 builtin/stash--helper.c 1203) if (untracked_commit_option)
1f5a011d90 builtin/stash--helper.c 1204) commit_list_insert(lookup_commit(the_repository,
1f5a011d90 builtin/stash--helper.c 1205)  &info->u_commit),
1f5a011d90 builtin/stash--helper.c 1207) commit_list_insert(lookup_commit(the_repository, &info->i_commit),
1f5a011d90 builtin/stash--helper.c 1209) commit_list_insert(head_commit, &parents);
1f5a011d90 builtin/stash--helper.c 1211) if (commit_tree(stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree,
9a95010a11 builtin/stash--helper.c 1213) if (!quiet)
9a95010a11 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot record "
1f5a011d90 builtin/stash--helper.c 1216) ret = -1;
1f5a011d90 builtin/stash--helper.c 1217) goto done;
1f5a011d90 builtin/stash--helper.c 1221) strbuf_release(&commit_tree_label);
1f5a011d90 builtin/stash--helper.c 1222) strbuf_release(&msg);
1f5a011d90 builtin/stash--helper.c 1223) strbuf_release(&untracked_files);
1f5a011d90 builtin/stash--helper.c 1224) return ret;
1f5a011d90 builtin/stash--helper.c 1227) static int create_stash(int argc, const char **argv, const char *prefix)
1f5a011d90 builtin/stash--helper.c 1229) int ret = 0;
1f5a011d90 builtin/stash--helper.c 1230) struct strbuf stash_msg_buf = STRBUF_INIT;
51809c70ca builtin/stash.c         1235) strbuf_join_argv(&stash_msg_buf, argc - 1, ++argv, ' ');
1f5a011d90 builtin/stash--helper.c 1237) memset(&ps, 0, sizeof(ps));
168e6cff5e builtin/stash--helper.c 1238) if (!check_changes_tracked_files(ps))
168e6cff5e builtin/stash--helper.c 1239) return 0;
168e6cff5e builtin/stash--helper.c 1241) if (!(ret = do_create_stash(ps, &stash_msg_buf, 0, 0, &info, NULL, 0)))
1f5a011d90 builtin/stash--helper.c 1242) printf_ln("%s", oid_to_hex(&info.w_commit));
1f5a011d90 builtin/stash--helper.c 1244) strbuf_release(&stash_msg_buf);
168e6cff5e builtin/stash--helper.c 1245) return ret;
fa38428f76 builtin/stash--helper.c 1248) static int do_push_stash(struct pathspec ps, const char *stash_msg, int quiet,
fa38428f76 builtin/stash--helper.c 1251) int ret = 0;
fa38428f76 builtin/stash--helper.c 1253) struct strbuf patch = STRBUF_INIT;
fa38428f76 builtin/stash--helper.c 1254) struct strbuf stash_msg_buf = STRBUF_INIT;
168e6cff5e builtin/stash--helper.c 1255) struct strbuf untracked_files = STRBUF_INIT;
fa38428f76 builtin/stash--helper.c 1257) if (patch_mode && keep_index == -1)
fa38428f76 builtin/stash--helper.c 1258) keep_index = 1;
fa38428f76 builtin/stash--helper.c 1260) if (patch_mode && include_untracked) {
fa38428f76 builtin/stash--helper.c 1261) fprintf_ln(stderr, _("Can't use --patch and --include-untracked"
fa38428f76 builtin/stash--helper.c 1263) ret = -1;
fa38428f76 builtin/stash--helper.c 1264) goto done;
fa38428f76 builtin/stash--helper.c 1267) read_cache_preload(NULL);
fa38428f76 builtin/stash--helper.c 1268) if (!include_untracked && ps.nr) {
fa38428f76 builtin/stash--helper.c 1270) char *ps_matched = xcalloc(ps.nr, 1);
fa38428f76 builtin/stash--helper.c 1272) for (i = 0; i < active_nr; i++)
fa38428f76 builtin/stash--helper.c 1273) ce_path_match(&the_index, active_cache[i], &ps,
fa38428f76 builtin/stash--helper.c 1276) if (report_path_error(ps_matched, &ps, NULL)) {
fa38428f76 builtin/stash--helper.c 1277) fprintf_ln(stderr, _("Did you forget to 'git add'?"));
fa38428f76 builtin/stash--helper.c 1278) ret = -1;
fa38428f76 builtin/stash--helper.c 1279) free(ps_matched);
fa38428f76 builtin/stash--helper.c 1280) goto done;
fa38428f76 builtin/stash--helper.c 1282) free(ps_matched);
fa38428f76 builtin/stash--helper.c 1285) if (refresh_cache(REFRESH_QUIET)) {
fa38428f76 builtin/stash--helper.c 1286) ret = -1;
fa38428f76 builtin/stash--helper.c 1287) goto done;
168e6cff5e builtin/stash--helper.c 1290) if (!check_changes(ps, include_untracked, &untracked_files)) {
fa38428f76 builtin/stash--helper.c 1291) if (!quiet)
fa38428f76 builtin/stash--helper.c 1292) printf_ln(_("No local changes to save"));
fa38428f76 builtin/stash--helper.c 1293) goto done;
fa38428f76 builtin/stash--helper.c 1296) if (!reflog_exists(ref_stash) && do_clear_stash()) {
fa38428f76 builtin/stash--helper.c 1297) ret = -1;
9a95010a11 builtin/stash--helper.c 1298) if (!quiet)
9a95010a11 builtin/stash--helper.c 1299) fprintf_ln(stderr, _("Cannot initialize stash"));
fa38428f76 builtin/stash--helper.c 1300) goto done;
fa38428f76 builtin/stash--helper.c 1303) if (stash_msg)
fa38428f76 builtin/stash--helper.c 1304) strbuf_addstr(&stash_msg_buf, stash_msg);
fa38428f76 builtin/stash--helper.c 1305) if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode,
fa38428f76 builtin/stash--helper.c 1307) ret = -1;
fa38428f76 builtin/stash--helper.c 1308) goto done;
fa38428f76 builtin/stash--helper.c 1311) if (do_store_stash(&info.w_commit, stash_msg_buf.buf, 1)) {
fa38428f76 builtin/stash--helper.c 1312) ret = -1;
9a95010a11 builtin/stash--helper.c 1313) if (!quiet)
9a95010a11 builtin/stash--helper.c 1314) fprintf_ln(stderr, _("Cannot save the current status"));
fa38428f76 builtin/stash--helper.c 1315) goto done;
9a95010a11 builtin/stash--helper.c 1318) if (!quiet)
9a95010a11 builtin/stash--helper.c 1319) printf_ln(_("Saved working directory and index state %s"),
fa38428f76 builtin/stash--helper.c 1322) if (!patch_mode) {
fa38428f76 builtin/stash--helper.c 1323) if (include_untracked && !ps.nr) {
fa38428f76 builtin/stash--helper.c 1324) struct child_process cp = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1326) cp.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1327) argv_array_pushl(&cp.args, "clean", "--force",
fa38428f76 builtin/stash--helper.c 1329) if (include_untracked == INCLUDE_ALL_FILES)
fa38428f76 builtin/stash--helper.c 1330) argv_array_push(&cp.args, "-x");
fa38428f76 builtin/stash--helper.c 1331) if (run_command(&cp)) {
fa38428f76 builtin/stash--helper.c 1332) ret = -1;
fa38428f76 builtin/stash--helper.c 1333) goto done;
fa38428f76 builtin/stash--helper.c 1336) if (ps.nr) {
fa38428f76 builtin/stash--helper.c 1337) struct child_process cp_add = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1338) struct child_process cp_diff = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1339) struct child_process cp_apply = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1340) struct strbuf out = STRBUF_INIT;
fa38428f76 builtin/stash--helper.c 1342) cp_add.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1343) argv_array_push(&cp_add.args, "add");
fa38428f76 builtin/stash--helper.c 1344) if (!include_untracked)
fa38428f76 builtin/stash--helper.c 1345) argv_array_push(&cp_add.args, "-u");
fa38428f76 builtin/stash--helper.c 1346) if (include_untracked == INCLUDE_ALL_FILES)
fa38428f76 builtin/stash--helper.c 1347) argv_array_push(&cp_add.args, "--force");
fa38428f76 builtin/stash--helper.c 1348) argv_array_push(&cp_add.args, "--");
fa38428f76 builtin/stash--helper.c 1349) add_pathspecs(&cp_add.args, ps);
fa38428f76 builtin/stash--helper.c 1350) if (run_command(&cp_add)) {
fa38428f76 builtin/stash--helper.c 1351) ret = -1;
fa38428f76 builtin/stash--helper.c 1352) goto done;
fa38428f76 builtin/stash--helper.c 1355) cp_diff.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1356) argv_array_pushl(&cp_diff.args, "diff-index", "-p",
fa38428f76 builtin/stash--helper.c 1359) add_pathspecs(&cp_diff.args, ps);
fa38428f76 builtin/stash--helper.c 1360) if (pipe_command(&cp_diff, NULL, 0, &out, 0, NULL, 0)) {
fa38428f76 builtin/stash--helper.c 1361) ret = -1;
fa38428f76 builtin/stash--helper.c 1362) goto done;
fa38428f76 builtin/stash--helper.c 1365) cp_apply.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1366) argv_array_pushl(&cp_apply.args, "apply", "--index",
fa38428f76 builtin/stash--helper.c 1368) if (pipe_command(&cp_apply, out.buf, out.len, NULL, 0,
fa38428f76 builtin/stash--helper.c 1370) ret = -1;
fa38428f76 builtin/stash--helper.c 1371) goto done;
fa38428f76 builtin/stash--helper.c 1374) struct child_process cp = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1375) cp.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1376) argv_array_pushl(&cp.args, "reset", "--hard", "-q",
fa38428f76 builtin/stash--helper.c 1378) if (run_command(&cp)) {
fa38428f76 builtin/stash--helper.c 1379) ret = -1;
fa38428f76 builtin/stash--helper.c 1380) goto done;
fa38428f76 builtin/stash--helper.c 1384) if (keep_index == 1 && !is_null_oid(&info.i_tree)) {
fa38428f76 builtin/stash--helper.c 1385) struct child_process cp_ls = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1386) struct child_process cp_checkout = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1387) struct strbuf out = STRBUF_INIT;
fa38428f76 builtin/stash--helper.c 1389) if (reset_tree(&info.i_tree, 0, 1)) {
fa38428f76 builtin/stash--helper.c 1390) ret = -1;
fa38428f76 builtin/stash--helper.c 1391) goto done;
fa38428f76 builtin/stash--helper.c 1394) cp_ls.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1395) argv_array_pushl(&cp_ls.args, "ls-files", "-z",
fa38428f76 builtin/stash--helper.c 1398) add_pathspecs(&cp_ls.args, ps);
fa38428f76 builtin/stash--helper.c 1399) if (pipe_command(&cp_ls, NULL, 0, &out, 0, NULL, 0)) {
fa38428f76 builtin/stash--helper.c 1400) ret = -1;
fa38428f76 builtin/stash--helper.c 1401) goto done;
fa38428f76 builtin/stash--helper.c 1404) cp_checkout.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1405) argv_array_pushl(&cp_checkout.args, "checkout-index",
fa38428f76 builtin/stash--helper.c 1407) if (pipe_command(&cp_checkout, out.buf, out.len, NULL,
fa38428f76 builtin/stash--helper.c 1409) ret = -1;
fa38428f76 builtin/stash--helper.c 1410) goto done;
fa38428f76 builtin/stash--helper.c 1413) goto done;
fa38428f76 builtin/stash--helper.c 1415) struct child_process cp = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1417) cp.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1418) argv_array_pushl(&cp.args, "apply", "-R", NULL);
fa38428f76 builtin/stash--helper.c 1420) if (pipe_command(&cp, patch.buf, patch.len, NULL, 0, NULL, 0)) {
9a95010a11 builtin/stash--helper.c 1421) if (!quiet)
9a95010a11 builtin/stash--helper.c 1422) fprintf_ln(stderr, _("Cannot remove "
fa38428f76 builtin/stash--helper.c 1424) ret = -1;
fa38428f76 builtin/stash--helper.c 1425) goto done;
fa38428f76 builtin/stash--helper.c 1428) if (keep_index < 1) {
fa38428f76 builtin/stash--helper.c 1429) struct child_process cp = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1431) cp.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1432) argv_array_pushl(&cp.args, "reset", "-q", "--", NULL);
fa38428f76 builtin/stash--helper.c 1433) add_pathspecs(&cp.args, ps);
fa38428f76 builtin/stash--helper.c 1434) if (run_command(&cp)) {
fa38428f76 builtin/stash--helper.c 1435) ret = -1;
fa38428f76 builtin/stash--helper.c 1436) goto done;
fa38428f76 builtin/stash--helper.c 1439) goto done;
fa38428f76 builtin/stash--helper.c 1443) strbuf_release(&stash_msg_buf);
fa38428f76 builtin/stash--helper.c 1444) return ret;
fa38428f76 builtin/stash--helper.c 1447) static int push_stash(int argc, const char **argv, const char *prefix)
fa38428f76 builtin/stash--helper.c 1449) int keep_index = -1;
fa38428f76 builtin/stash--helper.c 1450) int patch_mode = 0;
fa38428f76 builtin/stash--helper.c 1451) int include_untracked = 0;
fa38428f76 builtin/stash--helper.c 1452) int quiet = 0;
fa38428f76 builtin/stash--helper.c 1453) const char *stash_msg = NULL;
fa38428f76 builtin/stash--helper.c 1455) struct option options[] = {
51809c70ca builtin/stash.c         1470) if (argc)
51809c70ca builtin/stash.c         1471) argc = parse_options(argc, argv, prefix, options,
fa38428f76 builtin/stash--helper.c 1475) parse_pathspec(&ps, 0, PATHSPEC_PREFER_FULL, prefix, argv);
fa38428f76 builtin/stash--helper.c 1476) return do_push_stash(ps, stash_msg, quiet, keep_index, patch_mode,
cf5b27d699 builtin/stash--helper.c 1480) static int save_stash(int argc, const char **argv, const char *prefix)
cf5b27d699 builtin/stash--helper.c 1482) int keep_index = -1;
cf5b27d699 builtin/stash--helper.c 1483) int patch_mode = 0;
cf5b27d699 builtin/stash--helper.c 1484) int include_untracked = 0;
cf5b27d699 builtin/stash--helper.c 1485) int quiet = 0;
cf5b27d699 builtin/stash--helper.c 1486) int ret = 0;
cf5b27d699 builtin/stash--helper.c 1487) const char *stash_msg = NULL;
cf5b27d699 builtin/stash--helper.c 1489) struct strbuf stash_msg_buf = STRBUF_INIT;
cf5b27d699 builtin/stash--helper.c 1490) struct option options[] = {
cf5b27d699 builtin/stash--helper.c 1505) argc = parse_options(argc, argv, prefix, options,
cf5b27d699 builtin/stash--helper.c 1509) if (argc)
cf5b27d699 builtin/stash--helper.c 1510) stash_msg = strbuf_join_argv(&stash_msg_buf, argc, argv, ' ');
cf5b27d699 builtin/stash--helper.c 1512) memset(&ps, 0, sizeof(ps));
cf5b27d699 builtin/stash--helper.c 1513) ret = do_push_stash(ps, stash_msg, quiet, keep_index,
cf5b27d699 builtin/stash--helper.c 1516) strbuf_release(&stash_msg_buf);
cf5b27d699 builtin/stash--helper.c 1517) return ret;
bec65d5b78 builtin/stash.c         1527) return env;
26799a208f builtin/stash.c         1537) strbuf_trim(&out);
26799a208f builtin/stash.c         1538) ret = !strcmp("true", out.buf);
26799a208f builtin/stash.c         1539) strbuf_release(&out);
26799a208f builtin/stash.c         1555) const char *path = mkpath("%s/git-legacy-stash",
26799a208f builtin/stash.c         1558) if (sane_execvp(path, (char **)argv) < 0)
26799a208f builtin/stash.c         1559) die_errno(_("could not exec %s"), path);
f6bbd78127 builtin/stash--helper.c 1573) index_file = get_index_file();
f6bbd78127 builtin/stash--helper.c 1574) strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file,
51809c70ca builtin/stash.c         1577) if (!argc)
51809c70ca builtin/stash.c         1578) return !!push_stash(0, NULL, prefix);
51809c70ca builtin/stash.c         1579) else if (!strcmp(argv[0], "apply"))
f6bbd78127 builtin/stash--helper.c 1580) return !!apply_stash(argc, argv, prefix);
cdca49bc4c builtin/stash--helper.c 1581) else if (!strcmp(argv[0], "clear"))
cdca49bc4c builtin/stash--helper.c 1582) return !!clear_stash(argc, argv, prefix);
cdca49bc4c builtin/stash--helper.c 1583) else if (!strcmp(argv[0], "drop"))
cdca49bc4c builtin/stash--helper.c 1584) return !!drop_stash(argc, argv, prefix);
e1d01876a4 builtin/stash--helper.c 1585) else if (!strcmp(argv[0], "pop"))
e1d01876a4 builtin/stash--helper.c 1586) return !!pop_stash(argc, argv, prefix);
f596f3366c builtin/stash--helper.c 1587) else if (!strcmp(argv[0], "branch"))
f596f3366c builtin/stash--helper.c 1588) return !!branch_stash(argc, argv, prefix);
9b77b07ba4 builtin/stash--helper.c 1589) else if (!strcmp(argv[0], "list"))
9b77b07ba4 builtin/stash--helper.c 1590) return !!list_stash(argc, argv, prefix);
b4493f269e builtin/stash--helper.c 1591) else if (!strcmp(argv[0], "show"))
b4493f269e builtin/stash--helper.c 1592) return !!show_stash(argc, argv, prefix);
847eb0b0a8 builtin/stash--helper.c 1593) else if (!strcmp(argv[0], "store"))
847eb0b0a8 builtin/stash--helper.c 1594) return !!store_stash(argc, argv, prefix);
1f5a011d90 builtin/stash--helper.c 1595) else if (!strcmp(argv[0], "create"))
1f5a011d90 builtin/stash--helper.c 1596) return !!create_stash(argc, argv, prefix);
fa38428f76 builtin/stash--helper.c 1597) else if (!strcmp(argv[0], "push"))
fa38428f76 builtin/stash--helper.c 1598) return !!push_stash(argc, argv, prefix);
cf5b27d699 builtin/stash--helper.c 1599) else if (!strcmp(argv[0], "save"))
cf5b27d699 builtin/stash--helper.c 1600) return !!save_stash(argc, argv, prefix);
51809c70ca builtin/stash.c         1601) else if (*argv[0] != '-')
51809c70ca builtin/stash.c         1602) usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
51809c70ca builtin/stash.c         1605) if (strcmp(argv[0], "-p")) {
51809c70ca builtin/stash.c         1606) while (++i < argc && strcmp(argv[i], "--")) {
51809c70ca builtin/stash.c         1611) if ((strlen(argv[i]) == 2) && *argv[i] == '-' &&
51809c70ca builtin/stash.c         1612)     strchr("akpqu", argv[i][1]))
51809c70ca builtin/stash.c         1613) continue;
51809c70ca builtin/stash.c         1615) if (!strcmp(argv[i], "--all") ||
51809c70ca builtin/stash.c         1616)     !strcmp(argv[i], "--keep-index") ||
51809c70ca builtin/stash.c         1617)     !strcmp(argv[i], "--no-keep-index") ||
51809c70ca builtin/stash.c         1618)     !strcmp(argv[i], "--patch") ||
51809c70ca builtin/stash.c         1619)     !strcmp(argv[i], "--quiet") ||
51809c70ca builtin/stash.c         1620)     !strcmp(argv[i], "--include-untracked"))
51809c70ca builtin/stash.c         1621) continue;
51809c70ca builtin/stash.c         1628) if (starts_with(argv[i], "-m") ||
51809c70ca builtin/stash.c         1629)     starts_with(argv[i], "--message="))
51809c70ca builtin/stash.c         1630) continue;
51809c70ca builtin/stash.c         1632) usage_with_options(git_stash_usage, options);
51809c70ca builtin/stash.c         1636) argv_array_push(&args, "push");
51809c70ca builtin/stash.c         1637) argv_array_pushv(&args, argv);
51809c70ca builtin/stash.c         1638) return !!push_stash(args.argc, args.argv, prefix);

builtin/update-index.c
08339886b9 builtin/update-index.c  895) static enum parse_opt_result stdin_callback(
9b4ae5190a builtin/update-index.c  902) BUG_ON_OPT_ARG(arg);
08339886b9 builtin/update-index.c  910) static enum parse_opt_result unresolve_callback(
9b4ae5190a builtin/update-index.c  918) BUG_ON_OPT_ARG(arg);
08339886b9 builtin/update-index.c  931) static enum parse_opt_result reupdate_callback(
9b4ae5190a builtin/update-index.c  939) BUG_ON_OPT_ARG(arg);

builtin/upload-archive.c
6da1f1a920 builtin/upload-archive.c  86) register_allowed_protocol_version(protocol_v0);

commit-graph.c
97b202471c  885) for_each_object_in_pack(p, add_packed_commits, &oids,
97b202471c  932) for_each_packed_object(add_packed_commits, &oids,

config.c
06800238c6 1684) worktree_config = mkpathdup("%s/config.worktree", opts->git_dir);
06800238c6 1709) ret += git_config_from_file(fn, worktree_config, data);
8f7c7f5555 2147) int repo_config_set_gently(struct repository *r,
8f7c7f5555 2150) char *path = repo_git_path(r, "config");
8f7c7f5555 2151) int ret = git_config_set_multivar_in_file_gently(path, key, value, NULL, 0);
8f7c7f5555 2152) free(path);
8f7c7f5555 2153) return ret;
8f7c7f5555 2156) void repo_config_set(struct repository *r, const char *key, const char *value)
8f7c7f5555 2158) if (!repo_config_set_gently(r, key, value))
8f7c7f5555 2159) return;
8f7c7f5555 2160) if (value)
8f7c7f5555 2161) die(_("could not set '%s' to '%s'"), key, value);
8f7c7f5555 2163) die(_("could not unset '%s'"), key);
8f7c7f5555 2166) int repo_config_set_worktree_gently(struct repository *r,
8f7c7f5555 2172) path = get_worktree_config(r);
8f7c7f5555 2173) if (!path)
8f7c7f5555 2174) return CONFIG_INVALID_FILE;
8f7c7f5555 2175) ret = git_config_set_multivar_in_file_gently(path, key, value, NULL, 0);
8f7c7f5555 2176) free(path);
8f7c7f5555 2177) return ret;

connect.c
6da1f1a920 1085) strbuf_addch(&request, '\0');
6da1f1a920 1086) strbuf_addf(&request, "%s%c", version_advert->buf, '\0');
6da1f1a920 1103) if (variant == VARIANT_SSH) {
6da1f1a920 1106) argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=%s",
6da1f1a920 1194) push_ssh_options(&detect.args, &detect.env_array, VARIANT_SSH,
6da1f1a920 1202) push_ssh_options(&conn->args, &conn->env_array, variant, port,
6da1f1a920 1241) conn = git_connect_git(fd, hostandport, path, prog,
6da1f1a920 1285) fill_ssh_args(conn, ssh_host, port, &version_advert,

date.c
acdd37769d  113) die("Timestamp too large for this system: %"PRItime, time);
6943bd42fb  137) gettimeofday(now, NULL);
acdd37769d  245) hide.date = 1;
acdd37769d  926) return DATE_HUMAN;
86177eb5c4  943) if (isatty(1) || pager_in_use())
86177eb5c4  944) format = p;
86177eb5c4  946) format = "default";

diff-no-index.c
963389f6e7 268) if (implicit_no_index)
963389f6e7 269) warning(_("Not a git repository. Use --no-index to "
963389f6e7 271) usage_with_options(diff_no_index_usage, options);
963389f6e7 305) return 1;

diff.c
0eb03c4cd0 4745) width = strtoul(value, &end, 10);
0eb03c4cd0 4746) if (*end == ',')
0eb03c4cd0 4747) name_width = strtoul(end+1, &end, 10);
0eb03c4cd0 4748) if (*end == ',')
0eb03c4cd0 4749) count = strtoul(end+1, &end, 10);
0eb03c4cd0 4750) if (*end)
0eb03c4cd0 4751) return error(_("invalid --stat value: %s"), value);
0eb03c4cd0 4753) } else if (!strcmp(opt->long_name, "stat-width")) {
0eb03c4cd0 4754) width = strtoul(value, &end, 10);
0eb03c4cd0 4755) if (*end)
0eb03c4cd0 4756) return error(_("%s expects a numerical value"),
0eb03c4cd0 4758) } else if (!strcmp(opt->long_name, "stat-name-width")) {
0eb03c4cd0 4759) name_width = strtoul(value, &end, 10);
0eb03c4cd0 4760) if (*end)
0eb03c4cd0 4761) return error(_("%s expects a numerical value"),
0eb03c4cd0 4763) } else if (!strcmp(opt->long_name, "stat-graph-width")) {
0eb03c4cd0 4764) graph_width = strtoul(value, &end, 10);
0eb03c4cd0 4765) if (*end)
0eb03c4cd0 4766) return error(_("%s expects a numerical value"),
0eb03c4cd0 4768) } else if (!strcmp(opt->long_name, "stat-count")) {
0eb03c4cd0 4769) count = strtoul(value, &end, 10);
0eb03c4cd0 4770) if (*end)
0eb03c4cd0 4771) return error(_("%s expects a numerical value"),
b74a81799d 4836) static int diff_opt_diff_filter(const struct option *option,
b74a81799d 4839) struct diff_options *opt = option->value;
b74a81799d 4842) BUG_ON_OPT_NEG(unset);
b74a81799d 4873) return error(_("unknown change class '%c' in --diff-filter=%s"),
8b70e41773 4889) static int diff_opt_ws_error_highlight(const struct option *option,
8b70e41773 4892) struct diff_options *opt = option->value;
8b70e41773 4895) BUG_ON_OPT_NEG(unset);
8b70e41773 4896) if (val < 0)
8b70e41773 4897) return error("unknown value after ws-error-highlight=%.*s",
8b70e41773 4900) return 0;
5866e9ce9a 4903) static int diff_opt_find_object(const struct option *option,
5866e9ce9a 4906) struct diff_options *opt = option->value;
5866e9ce9a 4909) BUG_ON_OPT_NEG(unset);
5866e9ce9a 4911) return error(_("unable to resolve '%s'"), arg);
5866e9ce9a 4920) return 0;
b065b66077 4923) static int diff_opt_anchored(const struct option *opt,
b065b66077 4926) struct diff_options *options = opt->value;
b065b66077 4928) BUG_ON_OPT_NEG(unset);
b065b66077 4929) options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
b065b66077 4930) ALLOC_GROW(options->anchors, options->anchors_nr + 1,
b065b66077 4932) options->anchors[options->anchors_nr++] = xstrdup(arg);
b065b66077 4933) return 0;
6d0300b2e3 4936) static int diff_opt_binary(const struct option *opt,
6d0300b2e3 4939) struct diff_options *options = opt->value;
6d0300b2e3 4941) BUG_ON_OPT_NEG(unset);
6d0300b2e3 4942) BUG_ON_OPT_ARG(arg);
6d0300b2e3 4943) enable_patch_output(&options->output_format);
6d0300b2e3 4944) options->flags.binary = 1;
6d0300b2e3 4945) return 0;
b9b760ed1c 4948) static int diff_opt_break_rewrites(const struct option *opt,
b9b760ed1c 4951) int *break_opt = opt->value;
b9b760ed1c 4954) BUG_ON_OPT_NEG(unset);
b9b760ed1c 4955) if (!arg)
b9b760ed1c 4956) arg = "";
b9b760ed1c 4957) opt1 = parse_rename_score(&arg);
b9b760ed1c 4958) switch (*arg) {
b9b760ed1c 4960) opt2 = 0;
b9b760ed1c 4961) break;
b9b760ed1c 4963) arg++;
b9b760ed1c 4964) opt2 = parse_rename_score(&arg);
b9b760ed1c 4965) break;
b9b760ed1c 4967) if (*arg != 0)
b9b760ed1c 4968) return error(_("%s expects <n>/<m> form"), opt->long_name);
b9b760ed1c 4969) *break_opt = opt1 | (opt2 << 16);
b9b760ed1c 4970) return 0;
3d810d1860 4973) static int diff_opt_char(const struct option *opt,
3d810d1860 4976) char *value = opt->value;
3d810d1860 4978) BUG_ON_OPT_NEG(unset);
3d810d1860 4979) if (arg[1])
3d810d1860 4980) return error(_("%s expects a character, got '%s'"),
3d810d1860 4982) *value = arg[0];
3d810d1860 4983) return 0;
221d676696 4986) static int diff_opt_color_moved(const struct option *opt,
221d676696 4989) struct diff_options *options = opt->value;
221d676696 4991) if (unset) {
221d676696 4992) options->color_moved = COLOR_MOVED_NO;
221d676696 4993) } else if (!arg) {
221d676696 5004) return 0;
7c33a67a2e 5007) static int diff_opt_color_moved_ws(const struct option *opt,
7c33a67a2e 5010) struct diff_options *options = opt->value;
da9db54b3e 5013) if (unset) {
da9db54b3e 5015) return 0;
7c33a67a2e 5018) cm = parse_color_moved_ws(arg);
7c33a67a2e 5019) if (cm & COLOR_MOVED_WS_ERROR)
7c33a67a2e 5020) return error(_("invalid mode '%s' in --color-moved-ws"), arg);
7c33a67a2e 5021) options->color_moved_ws_handling = cm;
7c33a67a2e 5022) return 0;
f3b49b7f9e 5025) static int diff_opt_color_words(const struct option *opt,
f3b49b7f9e 5028) struct diff_options *options = opt->value;
f3b49b7f9e 5030) BUG_ON_OPT_NEG(unset);
f3b49b7f9e 5031) options->use_color = 1;
f3b49b7f9e 5032) options->word_diff = DIFF_WORDS_COLOR;
f3b49b7f9e 5033) options->word_regex = arg;
f3b49b7f9e 5034) return 0;
58c7ef398e 5037) static int diff_opt_compact_summary(const struct option *opt,
58c7ef398e 5040) struct diff_options *options = opt->value;
58c7ef398e 5042) BUG_ON_OPT_ARG(arg);
58c7ef398e 5043) if (unset) {
58c7ef398e 5044) options->flags.stat_with_summary = 0;
58c7ef398e 5046) options->flags.stat_with_summary = 1;
58c7ef398e 5047) options->output_format |= DIFF_FORMAT_DIFFSTAT;
58c7ef398e 5049) return 0;
1efc2689d6 5052) static int diff_opt_diff_algorithm(const struct option *opt,
1efc2689d6 5055) struct diff_options *options = opt->value;
1efc2689d6 5056) long value = parse_algorithm_value(arg);
1efc2689d6 5058) BUG_ON_OPT_NEG(unset);
1efc2689d6 5059) if (value < 0)
1efc2689d6 5060) return error(_("option diff-algorithm accepts \"myers\", "
1efc2689d6 5064) DIFF_XDL_CLR(options, NEED_MINIMAL);
1efc2689d6 5065) options->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK;
1efc2689d6 5066) options->xdl_opts |= value;
1efc2689d6 5067) return 0;
f8d10810d3 5070) static int diff_opt_dirstat(const struct option *opt,
f8d10810d3 5073) struct diff_options *options = opt->value;
f8d10810d3 5075) BUG_ON_OPT_NEG(unset);
f8d10810d3 5076) if (!strcmp(opt->long_name, "cumulative")) {
f8d10810d3 5077) if (arg)
f8d10810d3 5079) arg = "cumulative";
f8d10810d3 5080) } else if (!strcmp(opt->long_name, "dirstat-by-file"))
f8d10810d3 5081) parse_dirstat_opt(options, "files");
f8d10810d3 5082) parse_dirstat_opt(options, arg ? arg : "");
f8d10810d3 5083) return 0;
97e53999cd 5086) static int diff_opt_find_copies(const struct option *opt,
97e53999cd 5089) struct diff_options *options = opt->value;
97e53999cd 5091) BUG_ON_OPT_NEG(unset);
97e53999cd 5092) if (!arg)
97e53999cd 5093) arg = "";
97e53999cd 5094) options->rename_score = parse_rename_score(&arg);
97e53999cd 5095) if (*arg != 0)
97e53999cd 5096) return error(_("invalid argument to %s"), opt->long_name);
97e53999cd 5098) if (options->detect_rename == DIFF_DETECT_COPY)
97e53999cd 5099) options->flags.find_copies_harder = 1;
97e53999cd 5101) options->detect_rename = DIFF_DETECT_COPY;
97e53999cd 5103) return 0;
10e07ecc0c 5116) return error(_("invalid argument to %s"), opt->long_name);
c2dcec4fd2 5122) static int diff_opt_follow(const struct option *opt,
c2dcec4fd2 5125) struct diff_options *options = opt->value;
c2dcec4fd2 5127) BUG_ON_OPT_ARG(arg);
c2dcec4fd2 5128) if (unset) {
c2dcec4fd2 5129) options->flags.follow_renames = 0;
c2dcec4fd2 5130) options->flags.default_follow_renames = 0;
c2dcec4fd2 5132) options->flags.follow_renames = 1;
c2dcec4fd2 5134) return 0;
6c0ec4f728 5150) static int diff_opt_line_prefix(const struct option *opt,
6c0ec4f728 5153) struct diff_options *options = opt->value;
6c0ec4f728 5155) BUG_ON_OPT_NEG(unset);
6c0ec4f728 5156) options->line_prefix = optarg;
6c0ec4f728 5157) options->line_prefix_length = strlen(options->line_prefix);
6c0ec4f728 5158) graph_setup_line_prefix(options);
6c0ec4f728 5159) return 0;
059343267e 5162) static int diff_opt_no_prefix(const struct option *opt,
059343267e 5165) struct diff_options *options = opt->value;
059343267e 5167) BUG_ON_OPT_NEG(unset);
059343267e 5168) BUG_ON_OPT_ARG(optarg);
059343267e 5169) options->a_prefix = "";
059343267e 5170) options->b_prefix = "";
059343267e 5171) return 0;
3d810d1860 5174) static enum parse_opt_result diff_opt_output(struct parse_opt_ctx_t *ctx,
3d810d1860 5178) struct diff_options *options = opt->value;
3d810d1860 5181) BUG_ON_OPT_NEG(unset);
3d810d1860 5182) path = prefix_filename(ctx->prefix, arg);
3d810d1860 5183) options->file = xfopen(path, "w");
3d810d1860 5184) options->close_file = 1;
3d810d1860 5185) if (options->use_color != GIT_COLOR_ALWAYS)
3d810d1860 5186) options->use_color = GIT_COLOR_NEVER;
3d810d1860 5187) free(path);
3d810d1860 5188) return 0;
2156b1fd0c 5191) static int diff_opt_patience(const struct option *opt,
2156b1fd0c 5194) struct diff_options *options = opt->value;
2156b1fd0c 5197) BUG_ON_OPT_NEG(unset);
2156b1fd0c 5198) BUG_ON_OPT_ARG(arg);
2156b1fd0c 5199) options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
2156b1fd0c 5205) for (i = 0; i < options->anchors_nr; i++)
2156b1fd0c 5206) free(options->anchors[i]);
2156b1fd0c 5207) options->anchors_nr = 0;
2156b1fd0c 5208) return 0;
d071ebcc8a 5211) static int diff_opt_pickaxe_regex(const struct option *opt,
d071ebcc8a 5214) struct diff_options *options = opt->value;
d071ebcc8a 5216) BUG_ON_OPT_NEG(unset);
d071ebcc8a 5217) options->pickaxe = arg;
d071ebcc8a 5218) options->pickaxe_opts |= DIFF_PICKAXE_KIND_G;
d071ebcc8a 5219) return 0;
d071ebcc8a 5222) static int diff_opt_pickaxe_string(const struct option *opt,
d071ebcc8a 5225) struct diff_options *options = opt->value;
d071ebcc8a 5227) BUG_ON_OPT_NEG(unset);
d071ebcc8a 5228) options->pickaxe = arg;
d071ebcc8a 5229) options->pickaxe_opts |= DIFF_PICKAXE_KIND_S;
d071ebcc8a 5230) return 0;
350a71f2fc 5233) static int diff_opt_relative(const struct option *opt,
350a71f2fc 5236) struct diff_options *options = opt->value;
350a71f2fc 5238) BUG_ON_OPT_NEG(unset);
350a71f2fc 5239) options->flags.relative_name = 1;
350a71f2fc 5240) if (arg)
350a71f2fc 5241) options->prefix = arg;
350a71f2fc 5242) return 0;
1d2890f4f5 5245) static int diff_opt_submodule(const struct option *opt,
1d2890f4f5 5248) struct diff_options *options = opt->value;
1d2890f4f5 5250) BUG_ON_OPT_NEG(unset);
1d2890f4f5 5251) if (!arg)
1d2890f4f5 5252) arg = "log";
1d2890f4f5 5253) if (parse_submodule_params(options, arg))
1d2890f4f5 5254) return error(_("failed to parse --submodule option parameter: '%s'"),
1d2890f4f5 5256) return 0;
1d85988346 5259) static int diff_opt_textconv(const struct option *opt,
1d85988346 5262) struct diff_options *options = opt->value;
1d85988346 5264) BUG_ON_OPT_ARG(arg);
1d85988346 5265) if (unset) {
1d85988346 5266) options->flags.allow_textconv = 0;
1d85988346 5268) options->flags.allow_textconv = 1;
1d85988346 5269) options->flags.textconv_set_via_cmdline = 1;
1d85988346 5271) return 0;
6643eb7bbf 5284) return error(_("%s expects a numerical value"), "--unified");
08d080bf7f 5290) static int diff_opt_word_diff(const struct option *opt,
08d080bf7f 5293) struct diff_options *options = opt->value;
08d080bf7f 5295) BUG_ON_OPT_NEG(unset);
08d080bf7f 5296) if (arg) {
08d080bf7f 5308) return error(_("bad --word-diff argument: %s"), arg);
08d080bf7f 5313) return 0;
afe77a4dd9 5316) static int diff_opt_word_diff_regex(const struct option *opt,
afe77a4dd9 5319) struct diff_options *options = opt->value;
afe77a4dd9 5321) BUG_ON_OPT_NEG(unset);
afe77a4dd9 5322) if (options->word_diff == DIFF_WORDS_NONE)
afe77a4dd9 5323) options->word_diff = DIFF_WORDS_PLAIN;
afe77a4dd9 5324) options->word_regex = arg;
afe77a4dd9 5325) return 0;

fsck.c
ef644c4150  252) oidset_parse_file(&options->skiplist, buf + equal + 1);

ident.c
97f56073ce 568) static void set_env_if(const char *key, const char *value, int *given, int bit)
97f56073ce 570) if ((*given & bit) || getenv(key))
97f56073ce 571) return; /* nothing to do */
97f56073ce 572) setenv(key, value, 0);
97f56073ce 573) *given |= bit;
97f56073ce 576) void prepare_fallback_ident(const char *name, const char *email)
97f56073ce 578) set_env_if("GIT_AUTHOR_NAME", name,
97f56073ce 580) set_env_if("GIT_AUTHOR_EMAIL", email,
97f56073ce 582) set_env_if("GIT_COMMITTER_NAME", name,
97f56073ce 584) set_env_if("GIT_COMMITTER_EMAIL", email,
97f56073ce 586) }

list-objects-filter-options.c
3a7a698e93  74) if (!get_oid_with_context(the_repository, v0, GET_OID_BLOB,

list-objects.c
4f6d26b167 229) static void add_edge_parents(struct commit *commit,
4f6d26b167 236) for (parents = commit->parents; parents; parents = parents->next) {
4f6d26b167 237) struct commit *parent = parents->item;
4f6d26b167 238) struct tree *tree = get_commit_tree(parent);
4f6d26b167 240) if (!tree)
4f6d26b167 241) continue;
4f6d26b167 243) oidset_insert(set, &tree->object.oid);
4f6d26b167 245) if (!(parent->object.flags & UNINTERESTING))
4f6d26b167 246) continue;
4f6d26b167 247) tree->object.flags |= UNINTERESTING;
4f6d26b167 249) if (revs->edge_hint && !(parent->object.flags & SHOWN)) {
4f6d26b167 250) parent->object.flags |= SHOWN;
4f6d26b167 251) show_edge(parent);
4f6d26b167 254) }
4f6d26b167 265) oidset_init(&set, 16);
4f6d26b167 267) for (list = revs->commits; list; list = list->next) {
4f6d26b167 268) struct commit *commit = list->item;
4f6d26b167 269) struct tree *tree = get_commit_tree(commit);
4f6d26b167 271) if (commit->object.flags & UNINTERESTING)
4f6d26b167 272) tree->object.flags |= UNINTERESTING;
4f6d26b167 274) oidset_insert(&set, &tree->object.oid);
4f6d26b167 275) add_edge_parents(commit, revs, show_edge, &set);
4f6d26b167 278) mark_trees_uninteresting_sparse(revs->repo, &set);
4f6d26b167 279) oidset_clear(&set);
4f6d26b167 287) commit->object.flags |= SHOWN;
4f6d26b167 288) show_edge(commit);

merge-recursive.c
d7cf3a96e9  149) static struct tree *shift_tree_object(struct repository *repo,
d7cf3a96e9  163) return lookup_tree(repo, &shifted);
0d6caa2d08  428) struct index_state *istate = o->repo->index;
0d6caa2d08  430) if (unmerged_index(istate)) {
0d6caa2d08  433) for (i = 0; i < istate->cache_nr; i++) {
0d6caa2d08  434) const struct cache_entry *ce = istate->cache[i];
0d6caa2d08  442) if (!istate->cache_tree)
0d6caa2d08  443) istate->cache_tree = cache_tree();
0d6caa2d08  445) if (!cache_tree_fully_valid(istate->cache_tree) &&
0d6caa2d08  446)     cache_tree_update(istate, 0) < 0) {
d7cf3a96e9  451) result = lookup_tree(o->repo, &istate->cache_tree->oid);
0d6caa2d08  733) ce = index_file_exists(o->repo->index, path, strlen(path),
0d6caa2d08 1116) static int find_first_merges(struct repository *repo,
0d6caa2d08 1137) repo_init_revisions(repo, &revs, NULL);
d7cf3a96e9 1215) if (!(commit_base = lookup_commit_reference(o->repo, base)) ||
d7cf3a96e9 1216)     !(commit_a = lookup_commit_reference(o->repo, a)) ||
d7cf3a96e9 1217)     !(commit_b = lookup_commit_reference(o->repo, b))) {
0d6caa2d08 1267) parent_count = find_first_merges(o->repo, &merges, path,
0d6caa2d08 1416) if (!o->call_depth && would_lose_untracked(o, dest->path)) {
0d6caa2d08 1455)     (!o->call_depth && would_lose_untracked(o, path))) {
0d6caa2d08 1465) ret = remove_file_from_index(o->repo->index, path);
0d6caa2d08 1541) return remove_file_from_index(o->repo->index, dest->path);
0d6caa2d08 1622)     o->call_depth || would_lose_untracked(o, prev_path1));
0d6caa2d08 1625)     o->call_depth || would_lose_untracked(o, prev_path2));
0d6caa2d08 1732) if (dir_in_way(o->repo->index, path, !o->call_depth, 0)) {
0d6caa2d08 1737) } else if (would_lose_untracked(o, path)) {
0d6caa2d08 1798) remove_file_from_index(o->repo->index, a->path);
0d6caa2d08 1805) remove_file_from_index(o->repo->index, b->path);
0d6caa2d08 3057) if (renormalize_buffer(opt->repo->index, path, o.buf, o.len, &o) |
0d6caa2d08 3058)     renormalize_buffer(opt->repo->index, path, a.buf, a.len, &a))
0d6caa2d08 3139) if (dir_in_way(o->repo->index, path, !o->call_depth,
0d6caa2d08 3173) pos = index_name_pos(o->repo->index, path, strlen(path));
0d6caa2d08 3174) ce = o->repo->index->cache[pos];
0d6caa2d08 3193) remove_file_from_index(o->repo->index, path);
0d6caa2d08 3364) remove_file_from_index(o->repo->index, path);
d7cf3a96e9 3423) merge = shift_tree_object(o->repo, head, merge, o->subtree_shift);
d7cf3a96e9 3424) common = shift_tree_object(o->repo, head, common, o->subtree_shift);
d7cf3a96e9 3560) tree = lookup_tree(o->repo, o->repo->hash_algo->empty_tree);
d7cf3a96e9 3561) merged_common_ancestors = make_virtual_commit(o->repo, tree, "ancestor");
0d6caa2d08 3575) discard_index(o->repo->index);
d7cf3a96e9 3605) *result = make_virtual_commit(o->repo, mrtree, "merged tree");

merge.c
e1ff0a32e4  40) if (repo_read_index(r) < 0)

notes-merge.c
1d18d7581c 652) create_notes_commit(o->repo, local_tree, parents, o->commit_msg.buf,
1d18d7581c 727) create_notes_commit(o->repo, partial_tree, partial_commit->parents, msg,

notes-utils.c
1d18d7581c   8) void create_notes_commit(struct repository *r,
1d18d7581c  25) struct commit *parent = lookup_commit(r, &parent_oid);
1d18d7581c  38) void commit_notes(struct repository *r, struct notes_tree *t, const char *msg)
1d18d7581c  54) create_notes_commit(r, t, NULL, buf.buf, buf.len, &commit_oid);
1d18d7581c 175) void finish_copy_notes_for_rewrite(struct repository *r,
1d18d7581c 181) commit_notes(r, c->trees[i], msg);

oidset.c
ef644c4150 39) void oidset_parse_file(struct oidset *set, const char *path)
ef644c4150 42) struct strbuf sb = STRBUF_INIT;
ef644c4150 45) fp = fopen(path, "r");
ef644c4150 46) if (!fp)
ef644c4150 47) die("Could not open skip list: %s", path);
ef644c4150 48) while (!strbuf_getline(&sb, fp)) {
ef644c4150 57) hash = strchr(sb.buf, '#');
ef644c4150 58) if (hash)
ef644c4150 59) strbuf_setlen(&sb, hash - sb.buf);
ef644c4150 60) strbuf_trim(&sb);
ef644c4150 61) if (!sb.len)
ef644c4150 62) continue;
ef644c4150 64) if (parse_oid_hex(sb.buf, &oid, &p) || *p != '\0')
ef644c4150 65) die("Invalid SHA-1: %s", sb.buf);
ef644c4150 66) oidset_insert(set, &oid);
ef644c4150 68) if (ferror(fp))
ef644c4150 69) die_errno("Could not read '%s'", path);
ef644c4150 70) fclose(fp);
ef644c4150 71) strbuf_release(&sb);
ef644c4150 72) }

parse-options-cb.c
8fc6b47cd5  26) v = the_hash_algo->hexsz;
08339886b9 173) enum parse_opt_result parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx,
9b4ae5190a 177) BUG_ON_OPT_ARG(arg);
08339886b9 178) return PARSE_OPT_UNKNOWN;

parse-options.c
08339886b9  48) static enum parse_opt_result opt_command_mode_error(
08339886b9  74) return PARSE_OPT_ERROR;
9b4ae5190a 183) return (*opt->ll_callback)(p, opt, p_arg, p_unset);
9b4ae5190a 255) rc = (*numopt->ll_callback)(p, numopt, arg, 0);

pretty.c
4681fe38e1 1060) static int match_placeholder_arg_value(const char *to_parse, const char *candidate,
4681fe38e1 1067) if (valuestart) {
4681fe38e1 1068) if (*p != '=')
4681fe38e1 1069) return 0;
4681fe38e1 1070) *valuestart = p + 1;
4681fe38e1 1071) *valuelen = strcspn(*valuestart, ",)");
4681fe38e1 1072) p = *valuestart + *valuelen;
4681fe38e1 1085) static int match_placeholder_arg(const char *to_parse, const char *candidate,
4681fe38e1 1088) return match_placeholder_arg_value(to_parse, candidate, end, NULL, NULL);
b755bf6f83 1091) static int match_placeholder_bool_arg(const char *to_parse, const char *candidate,
b755bf6f83 1095) if (!skip_prefix(to_parse, candidate, &p))
b755bf6f83 1096) return 0;
b755bf6f83 1098) if (match_placeholder_arg(p, "=no", end) ||
b755bf6f83 1099)     match_placeholder_arg(p, "=off", end) ||
b755bf6f83 1100)     match_placeholder_arg(p, "=false", end)) {
b755bf6f83 1101) *val = 0;
b755bf6f83 1102) return 1;
b755bf6f83 1105) if (match_placeholder_arg(p, "", end) ||
b755bf6f83 1106)     match_placeholder_arg(p, "=yes", end) ||
b755bf6f83 1107)     match_placeholder_arg(p, "=on", end) ||
b755bf6f83 1108)     match_placeholder_arg(p, "=true", end)) {
b755bf6f83 1109) *val = 1;
b755bf6f83 1110) return 1;
4681fe38e1 1112) return 0;
4681fe38e1 1115) static int format_trailer_match_cb(const struct strbuf *key, void *ud)
4681fe38e1 1117) const struct string_list *list = ud;
4681fe38e1 1120) for_each_string_list_item (item, list) {
4681fe38e1 1121) if (key->len == (uintptr_t)item->util &&
4681fe38e1 1122)     !strncasecmp (item->string, key->buf, key->len))
4681fe38e1 1123) return 1;
b755bf6f83 1125) return 0;
18f8e81091 1143) return res;
4681fe38e1 1369) struct string_list filter_list = STRING_LIST_INIT_NODUP;
ced45aab72 1370) struct strbuf sepbuf = STRBUF_INIT;
ffd7cae405 1371) size_t ret = 0;
4681fe38e1 1381) if (match_placeholder_arg_value(arg, "key", &arg, &argval, &arglen)) {
4681fe38e1 1382) uintptr_t len = arglen;
4681fe38e1 1383) if (len && argval[len - 1] == ':')
4681fe38e1 1384) len--;
4681fe38e1 1385) string_list_append(&filter_list, argval)->util = (char *)len;
4681fe38e1 1387) opts.filter = format_trailer_match_cb;
4681fe38e1 1388) opts.filter_data = &filter_list;
ced45aab72 1390) } else if (match_placeholder_arg_value(arg, "separator", &arg, &argval, &arglen)) {
ced45aab72 1393) strbuf_reset(&sepbuf);
ced45aab72 1394) fmt = xstrndup(argval, arglen);
ced45aab72 1395) strbuf_expand(&sepbuf, fmt, strbuf_expand_literal_cb, NULL);
ced45aab72 1396) free(fmt);
ced45aab72 1397) opts.separator = &sepbuf;
4681fe38e1 1398) } else if (!match_placeholder_bool_arg(arg, "only", &arg, &opts.only_trailers) &&
e9da5de761 1399)    !match_placeholder_bool_arg(arg, "unfold", &arg, &opts.unfold) &&
e9da5de761 1400)    !match_placeholder_bool_arg(arg, "valueonly", &arg, &opts.value_only))
ffd7cae405 1406) ret = arg - placeholder + 1;
4681fe38e1 1408) string_list_clear (&filter_list, 0);
ced45aab72 1409) strbuf_release(&sepbuf);
ffd7cae405 1410) return ret;

protocol.c
6da1f1a920  31) return protocol_v0_string;
6da1f1a920  33) return protocol_v1_string;
6da1f1a920  37) die(_("Unrecognized protocol version"));
6da1f1a920  39) die(_("Unrecognized protocol_version"));
6da1f1a920  76) return;
6da1f1a920 112) ALLOC_ARRAY(tmp_allowed_versions, tmp_nr);
6da1f1a920 113) copy_array(tmp_allowed_versions, allowed_versions, tmp_nr,
6da1f1a920 122) for (i = 1; i < nr_allowed_versions; i++)
6da1f1a920 123) if (tmp_allowed_versions[i] == config_version) {
6da1f1a920 124) SWAP(tmp_allowed_versions[0],
6da1f1a920 131) strbuf_addf(advert, ":version=%s",
6da1f1a920 132)     format_protocol_version(tmp_allowed_versions[i]));

rebase-interactive.c
c27b32f0ec  15) static enum missing_commit_check_level get_missing_commit_check_level(void)
c27b32f0ec  19) if (git_config_get_value("rebase.missingcommitscheck", &value) ||
c27b32f0ec  20) !strcasecmp("ignore", value))
c27b32f0ec  21) return MISSING_COMMIT_CHECK_IGNORE;
c27b32f0ec  22) if (!strcasecmp("warn", value))
c27b32f0ec  23) return MISSING_COMMIT_CHECK_WARN;
c27b32f0ec  24) if (!strcasecmp("error", value))
c27b32f0ec  25) return MISSING_COMMIT_CHECK_ERROR;
c27b32f0ec  26) warning(_("unrecognized setting %s for option "
c27b32f0ec  28) return MISSING_COMMIT_CHECK_IGNORE;
2dd989a694  31) void append_todo_help(unsigned keep_empty, int command_count,
2dd989a694  52) unsigned edit_todo = !(shortrevisions && shortonto);
2dd989a694  54) if (!edit_todo) {
2dd989a694  55) strbuf_addch(buf, '\n');
2dd989a694  56) strbuf_commented_addf(buf, Q_("Rebase %s onto %s (%d command)",
e5b1c9d929  90) int edit_todo_list(struct repository *r, struct todo_list *todo_list,
e5b1c9d929  95) unsigned initial = shortrevisions && shortonto;
e5b1c9d929  97) if (initial) {
e5b1c9d929  98) todo_list_write_to_file(r, todo_list, todo_file, shortrevisions, shortonto,
e5b1c9d929 101) if (copy_file(rebase_path_todo_backup(), todo_file, 0666))
e5b1c9d929 102) return error(_("could not copy '%s' to '%s'."), todo_file,
e5b1c9d929 105) todo_list_parse_insn_buffer(r, todo_list->buf.buf, todo_list);
e5b1c9d929 106) todo_list_write_to_file(r, todo_list, todo_file, NULL, NULL, -1,
e5b1c9d929 110) if (launch_sequence_editor(todo_file, &new_todo->buf, NULL))
e5b1c9d929 111) return -2;
e5b1c9d929 113) strbuf_stripspace(&new_todo->buf, 1);
e5b1c9d929 114) if (initial && new_todo->buf.len == 0)
e5b1c9d929 115) return -3;
e5b1c9d929 117) if (!initial)
e5b1c9d929 118) todo_list_parse_insn_buffer(r, new_todo->buf.buf, new_todo);
e5b1c9d929 120) return 0;
c27b32f0ec 123) define_commit_slab(commit_seen, unsigned char);
c27b32f0ec 130) int todo_list_check(struct todo_list *old_todo, struct todo_list *new_todo)
c27b32f0ec 132) enum missing_commit_check_level check_level = get_missing_commit_check_level();
c27b32f0ec 133) struct strbuf missing = STRBUF_INIT;
c27b32f0ec 134) int res = 0, i;
c27b32f0ec 137) init_commit_seen(&commit_seen);
c27b32f0ec 139) if (check_level == MISSING_COMMIT_CHECK_IGNORE)
c27b32f0ec 140) goto leave_check;
c27b32f0ec 143) for (i = 0; i < new_todo->nr; i++) {
c27b32f0ec 144) struct commit *commit = new_todo->items[i].commit;
c27b32f0ec 145) if (commit)
c27b32f0ec 146) *commit_seen_at(&commit_seen, commit) = 1;
c27b32f0ec 150) for (i = old_todo->nr - 1; i >= 0; i--) {
c27b32f0ec 151) struct todo_item *item = old_todo->items + i;
c27b32f0ec 152) struct commit *commit = item->commit;
c27b32f0ec 153) if (commit && !*commit_seen_at(&commit_seen, commit)) {
c27b32f0ec 154) strbuf_addf(&missing, " - %s %.*s\n",
c27b32f0ec 155)     find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV),
c27b32f0ec 157)     old_todo->buf.buf + item->arg_offset);
c27b32f0ec 158) *commit_seen_at(&commit_seen, commit) = 1;
c27b32f0ec 163) if (!missing.len)
c27b32f0ec 164) goto leave_check;
c27b32f0ec 166) if (check_level == MISSING_COMMIT_CHECK_ERROR)
c27b32f0ec 167) res = 1;
c27b32f0ec 169) fprintf(stderr,
c27b32f0ec 174) fputs(missing.buf, stderr);
c27b32f0ec 175) strbuf_release(&missing);
c27b32f0ec 177) fprintf(stderr, _("To avoid this message, use \"drop\" to "
c27b32f0ec 184) clear_commit_seen(&commit_seen);
c27b32f0ec 185) return res;

remote-curl.c
6da1f1a920  344) return 0;
34a9469d6a  363) return;
34a9469d6a  373) die("invalid server response; expected service, got flush packet");
240fb9b7a0  392) } else if (!strcmp(line, "version 2")) {
34a9469d6a  397) d->proto_git = 1;
e586e7df7c  399) } else if (skip_prefix(line, "ERR ", &p)) {
e586e7df7c  400) die(_("remote error: %s"), p);

repository.c
rerere.c
e1ff0a32e4  598) if (repo_read_index(r) < 0)
3a95f31d1c  708) repo_hold_locked_index(r, &index_lock, LOCK_DIE_ON_ERROR);
e1ff0a32e4 1110) if (repo_read_index(r) < 0)

revision.c
d5d2e93577  109) static int path_and_oids_cmp(const void *hashmap_cmp_fn_data,
d5d2e93577  114) return strcmp(e1->path, e2->path);
d5d2e93577  117) static void paths_and_oids_init(struct hashmap *map)
d5d2e93577  119) hashmap_init(map, (hashmap_cmp_fn) path_and_oids_cmp, NULL, 0);
d5d2e93577  120) }
d5d2e93577  122) static void paths_and_oids_clear(struct hashmap *map)
d5d2e93577  126) hashmap_iter_init(map, &iter);
d5d2e93577  128) while ((entry = (struct path_and_oids_entry *)hashmap_iter_next(&iter))) {
d5d2e93577  129) oidset_clear(&entry->trees);
d5d2e93577  130) free(entry->path);
d5d2e93577  133) hashmap_free(map, 1);
d5d2e93577  134) }
d5d2e93577  136) static void paths_and_oids_insert(struct hashmap *map,
d5d2e93577  140) int hash = strhash(path);
d5d2e93577  144) hashmap_entry_init(&key, hash);
d5d2e93577  147) key.path = (char *)path;
d5d2e93577  148) oidset_init(&key.trees, 0);
d5d2e93577  150) if (!(entry = (struct path_and_oids_entry *)hashmap_get(map, &key, NULL))) {
d5d2e93577  151) entry = xcalloc(1, sizeof(struct path_and_oids_entry));
d5d2e93577  152) hashmap_entry_init(entry, hash);
d5d2e93577  153) entry->path = xstrdup(key.path);
d5d2e93577  154) oidset_init(&entry->trees, 16);
d5d2e93577  155) hashmap_put(map, entry);
d5d2e93577  158) oidset_insert(&entry->trees, oid);
d5d2e93577  159) }
d5d2e93577  161) static void add_children_by_path(struct repository *r,
d5d2e93577  168) if (!tree)
d5d2e93577  169) return;
d5d2e93577  171) if (parse_tree_gently(tree, 1) < 0)
d5d2e93577  172) return;
d5d2e93577  174) init_tree_desc(&desc, tree->buffer, tree->size);
d5d2e93577  175) while (tree_entry(&desc, &entry)) {
d5d2e93577  176) switch (object_type(entry.mode)) {
5dde8fc6df  178) paths_and_oids_insert(map, entry.path, &entry.oid);
d5d2e93577  180) if (tree->object.flags & UNINTERESTING) {
5dde8fc6df  181) struct tree *child = lookup_tree(r, &entry.oid);
d5d2e93577  182) if (child)
d5d2e93577  183) child->object.flags |= UNINTERESTING;
d5d2e93577  185) break;
d5d2e93577  187) if (tree->object.flags & UNINTERESTING) {
5dde8fc6df  188) struct blob *child = lookup_blob(r, &entry.oid);
d5d2e93577  189) if (child)
d5d2e93577  190) child->object.flags |= UNINTERESTING;
d5d2e93577  192) break;
d5d2e93577  195) break;
d5d2e93577  199) free_tree_buffer(tree);
f1f5de442f  202) void mark_trees_uninteresting_sparse(struct repository *r,
d5d2e93577  205) unsigned has_interesting = 0, has_uninteresting = 0;
f1f5de442f  212) oidset_iter_init(trees, &iter);
d5d2e93577  213) while ((!has_interesting || !has_uninteresting) &&
f1f5de442f  215) struct tree *tree = lookup_tree(r, oid);
f1f5de442f  217) if (!tree)
f1f5de442f  218) continue;
d5d2e93577  220) if (tree->object.flags & UNINTERESTING)
d5d2e93577  221) has_uninteresting = 1;
d5d2e93577  223) has_interesting = 1;
d5d2e93577  227) if (!has_uninteresting || !has_interesting)
d5d2e93577  228) return;
d5d2e93577  230) paths_and_oids_init(&map);
d5d2e93577  232) oidset_iter_init(trees, &iter);
d5d2e93577  233) while ((oid = oidset_iter_next(&iter))) {
d5d2e93577  234) struct tree *tree = lookup_tree(r, oid);
d5d2e93577  235) add_children_by_path(r, tree, &map);
d5d2e93577  238) hashmap_iter_init(&map, &map_iter);
d5d2e93577  239) while ((entry = hashmap_iter_next(&map_iter)))
d5d2e93577  240) mark_trees_uninteresting_sparse(r, &entry->trees);
d5d2e93577  242) paths_and_oids_clear(&map);
e1ff0a32e4 1690) repo_read_index(revs->repo);
3a7a698e93 1749) if (get_oid_with_context(revs->repo, a_name, oc_flags, &a_oid, a_oc) ||
3a7a698e93 1750)     get_oid_with_context(revs->repo, b_name, oc_flags, &b_oid, b_oc))

sequencer.c
e5b1c9d929   58) GIT_PATH_FUNC(rebase_path_todo_backup, "rebase-merge/git-rebase-todo.backup")
e1ff0a32e4  449) static int error_dirty_index(struct repository *repo, struct replay_opts *opts)
e1ff0a32e4  451) if (repo_read_index_unmerged(repo))
e1ff0a32e4  486) repo_read_index(r);
1d18d7581c 1118) void commit_post_rewrite(struct repository *r,
1d18d7581c 1128) finish_copy_notes_for_rewrite(r, cfg, "Notes added by 'git commit --amend'");
1d18d7581c 1409) commit_post_rewrite(r, current_head, oid);
e1ff0a32e4 1745) return error_dirty_index(r, opts);
5d94d54564 1996) void todo_list_release(struct todo_list *todo_list)
d836079ec2 2024) item->arg_offset = bol - buf;
d836079ec2 2051) item->arg_offset = bol - buf;
d836079ec2 2063) item->arg_offset = bol - buf;
d836079ec2 2077) item->arg_offset = bol - buf;
d836079ec2 2089) bol = end_of_object_name + strspn(end_of_object_name, " \t");
d836079ec2 2090) item->arg_offset = bol - buf;
d836079ec2 2091) item->arg_len = (int)(eol - bol);
5d94d54564 2100) int todo_list_parse_insn_buffer(struct repository *r, char *buf,
2b71595d47 2107) todo_list->current = todo_list->nr = 0;
d836079ec2 2119) if (parse_insn_line(r, item, buf, p, eol)) {
2b71595d47 2122) item->command = TODO_COMMENT + 1;
d836079ec2 2123) item->arg_offset = p - buf;
2b71595d47 2124) item->arg_len = (int)(eol - p);
2b71595d47 2125) item->commit = NULL;
5d94d54564 2200) res = todo_list_parse_insn_buffer(r, todo_list->buf.buf, todo_list);
5d94d54564 2231)     !todo_list_parse_insn_buffer(r, done.buf.buf, &done))
d836079ec2 2468) item->arg_offset = 0;
e1ff0a32e4 2829) if (discard_index(r->index) < 0 || repo_read_index(r) < 0)
3a95f31d1c 2953) if (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0)
e1ff0a32e4 2998) if (repo_read_index_unmerged(r)) {
3a95f31d1c 3071) if (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0) {
e1ff0a32e4 3252)      repo_read_index(r) < 0))
e1ff0a32e4 3274) repo_read_index(r);
0d6caa2d08 3275) init_merge_options(&o, r);
d836079ec2 3507) const char *arg = todo_list->buf.buf + item->arg_offset;
d836079ec2 3595) char *end_of_arg = (char *)(arg + item->arg_len);
d836079ec2 3600) res = do_exec(r, arg);
d836079ec2 3618) if ((res = do_label(r, arg, item->arg_len)))
d836079ec2 3621) if ((res = do_reset(r, arg, item->arg_len, opts)))
e1ff0a32e4 3950) res = error_dirty_index(r, opts);
0566a4f68e 4372) strbuf_addf(out, "%s onto\n", cmd_label);
0566a4f68e 4382) strbuf_addf(out, "\n%c Branch %s\n", comment_line_char, entry->string);
0566a4f68e 4384) strbuf_addch(out, '\n');
0566a4f68e 4397) strbuf_addf(out, "%s %s\n", cmd_reset,
0566a4f68e 4411) strbuf_addf(out, "%s onto\n", cmd_reset);
0566a4f68e 4415) strbuf_addf(out, "%s %s # %s\n",
0566a4f68e 4425) strbuf_addf(out, "%s\n", entry->string);
0566a4f68e 4428) strbuf_addf(out, "%s %s\n",
0566a4f68e 4429)     cmd_label, entry->string);
0566a4f68e 4451) int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
0566a4f68e 4499) strbuf_addf(out, "%c ", comment_line_char);
0566a4f68e 4500) strbuf_addf(out, "%s %s ", insn,
0566a4f68e 4502) pretty_print_commit(&pp, commit, out);
0566a4f68e 4503) strbuf_addch(out, '\n');
8414c890aa 4508) static void todo_list_add_exec_commands(struct todo_list *todo_list,
8414c890aa 4511) struct strbuf *buf = &todo_list->buf;
8414c890aa 4512) size_t base_offset = buf->len;
8414c890aa 4513) int i, insert, nr = 0, alloc = 0;
8414c890aa 4514) struct todo_item *items = NULL, *base_items = NULL;
8414c890aa 4516) base_items = xcalloc(commands->nr, sizeof(struct todo_item));
8414c890aa 4517) for (i = 0; i < commands->nr; ++i) {
8414c890aa 4518) size_t command_len = strlen(commands->items[i].string);
8414c890aa 4520) strbuf_addstr(buf, commands->items[i].string);
8414c890aa 4521) strbuf_addch(buf, '\n');
8414c890aa 4523) base_items[i].command = TODO_EXEC;
8414c890aa 4524) base_items[i].offset_in_buf = base_offset;
8414c890aa 4525) base_items[i].arg_offset = base_offset + strlen("exec ");
8414c890aa 4526) base_items[i].arg_len = command_len - strlen("exec ");
8414c890aa 4528) base_offset += command_len + 1;
8414c890aa 4537) for (i = 0; i < todo_list->nr; i++) {
8414c890aa 4538) enum todo_command command = todo_list->items[i].command;
8414c890aa 4539) if (insert >= 0 && command != TODO_COMMENT && !is_fixup(command)) {
8414c890aa 4540) ALLOC_GROW(items, nr + commands->nr, alloc);
8414c890aa 4541) COPY_ARRAY(items + nr, base_items, commands->nr);
8414c890aa 4542) nr += commands->nr;
8414c890aa 4546) ALLOC_GROW(items, nr + 1, alloc);
8414c890aa 4547) items[nr++] = todo_list->items[i];
8414c890aa 4549) if (command == TODO_PICK || command == TODO_MERGE || is_fixup(command))
8414c890aa 4554) if (insert >= 0 || nr == todo_list->nr) {
8414c890aa 4555) ALLOC_GROW(items, nr + commands->nr, alloc);
8414c890aa 4556) COPY_ARRAY(items + nr, base_items, commands->nr);
8414c890aa 4557) nr += commands->nr;
8414c890aa 4560) free(base_items);
8414c890aa 4561) FREE_AND_NULL(todo_list->items);
8414c890aa 4562) todo_list->items = items;
8414c890aa 4563) todo_list->nr = nr;
8414c890aa 4564) todo_list->alloc = alloc;
8414c890aa 4571) int sequencer_add_exec_commands(struct repository *r,
8414c890aa 4579) return error_errno(_("could not read '%s'."), todo_file);
8414c890aa 4581) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, &todo_list)) {
8414c890aa 4586) todo_list_add_exec_commands(&todo_list, commands);
8414c890aa 4587) res = todo_list_write_to_file(r, &todo_list, todo_file, NULL, NULL, -1, 0);
0cce4a2756 4588) todo_list_release(&todo_list);
8414c890aa 4590) if (res)
8414c890aa 4591) return error_errno(_("could not write '%s'."), todo_file);
8414c890aa 4592) return 0;
cf18b3f6c9 4595) static void todo_list_to_strbuf(struct repository *r, struct todo_list *todo_list,
cf18b3f6c9 4599) int i, max = todo_list->nr;
cf18b3f6c9 4601) if (num > 0 && num < max)
cf18b3f6c9 4602) max = num;
cf18b3f6c9 4604) for (item = todo_list->items, i = 0; i < max; i++, item++) {
cf18b3f6c9 4607) strbuf_addf(buf, "%.*s\n", item->arg_len,
3ebafef416 4608)     todo_list->buf.buf + item->arg_offset);
cf18b3f6c9 4614) strbuf_addch(buf, command_to_char(item->command));
cf18b3f6c9 4616) strbuf_addstr(buf, command_to_string(item->command));
cf18b3f6c9 4626) strbuf_addstr(buf, " -c");
cf18b3f6c9 4628) strbuf_addstr(buf, " -C");
cf18b3f6c9 4631) strbuf_addf(buf, " %s", oid);
cf18b3f6c9 4636) strbuf_addch(buf, '\n');
cf18b3f6c9 4638) strbuf_addf(buf, " %.*s\n", item->arg_len,
3ebafef416 4639)     todo_list->buf.buf + item->arg_offset);
cf18b3f6c9 4643) int todo_list_write_to_file(struct repository *r, struct todo_list *todo_list,
cf18b3f6c9 4648) struct strbuf buf = STRBUF_INIT;
cf18b3f6c9 4650) todo_list_to_strbuf(r, todo_list, &buf, num, flags);
2dd989a694 4651) if (flags & TODO_LIST_APPEND_TODO_HELP)
2dd989a694 4652) append_todo_help(flags & TODO_LIST_KEEP_EMPTY, count_commands(todo_list),
cf18b3f6c9 4655) res = write_message(buf.buf, buf.len, file, 0);
3ebafef416 4656) strbuf_release(&buf);
cf18b3f6c9 4658) return res;
c27b32f0ec 4667) int check_todo_list_from_file(struct repository *r)
c27b32f0ec 4669) struct todo_list old_todo = TODO_LIST_INIT, new_todo = TODO_LIST_INIT;
c27b32f0ec 4670) int res = 0;
c27b32f0ec 4672) if (strbuf_read_file_or_whine(&new_todo.buf, rebase_path_todo()) < 0) {
878056005e 4673) res = -1;
c27b32f0ec 4674) goto out;
c27b32f0ec 4677) if (strbuf_read_file_or_whine(&old_todo.buf, rebase_path_todo_backup()) < 0) {
c27b32f0ec 4679) goto out;
c27b32f0ec 4682) res = todo_list_parse_insn_buffer(r, old_todo.buf.buf, &old_todo);
c27b32f0ec 4683) if (!res)
c27b32f0ec 4684) res = todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo);
c27b32f0ec 4685) if (!res)
c27b32f0ec 4686) res = todo_list_check(&old_todo, &new_todo);
c27b32f0ec 4687) if (res)
c27b32f0ec 4688) fprintf(stderr, _(edit_todo_list_advice));
c27b32f0ec 4690) todo_list_release(&old_todo);
c27b32f0ec 4691) todo_list_release(&new_todo);
98b29e0607 4697) static int skip_unnecessary_picks(struct repository *r,
98b29e0607 4704) for (i = 0; i < todo_list->nr; i++) {
98b29e0607 4705) struct todo_item *item = todo_list->items + i;
98b29e0607 4727) if (todo_list_write_to_file(r, todo_list, done_path, NULL, NULL, i, 0)) {
98b29e0607 4732) MOVE_ARRAY(todo_list->items, todo_list->items + i, todo_list->nr - i);
98b29e0607 4733) todo_list->nr -= i;
98b29e0607 4734) todo_list->current = 0;
98b29e0607 4736) if (is_fixup(peek_command(todo_list, 0)))
98b29e0607 4737) record_in_rewritten(output_oid, peek_command(todo_list, 0));
c1c074e0cc 4751) struct todo_list new_todo = TODO_LIST_INIT;
c1c074e0cc 4752) struct strbuf *buf = &todo_list->buf;
c1c074e0cc 4759) if (buf->len == 0) {
c1c074e0cc 4760) struct todo_item *item = append_new_todo(todo_list);
c1c074e0cc 4761) item->command = TODO_NOOP;
c1c074e0cc 4762) item->commit = NULL;
c1c074e0cc 4763) item->arg_len = item->arg_offset = item->flags = item->offset_in_buf = 0;
c1c074e0cc 4766) if (autosquash && todo_list_rearrange_squash(todo_list))
8414c890aa 4769) if (commands->nr)
c1c074e0cc 4770) todo_list_add_exec_commands(todo_list, commands);
c1c074e0cc 4772) if (count_commands(todo_list) == 0) {
33bc1844f7 4779) res = edit_todo_list(r, todo_list, &new_todo, shortrevisions,
33bc1844f7 4781) if (res == -1)
33bc1844f7 4783) else if (res == -2) {
33bc1844f7 4788) } else if (res == -3) {
c1c074e0cc 4791) todo_list_release(&new_todo);
c1c074e0cc 4796) if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo) ||
c1c074e0cc 4797)     todo_list_check(todo_list, &new_todo)) {
c1c074e0cc 4798) fprintf(stderr, _(edit_todo_list_advice));
c1c074e0cc 4800) todo_list_release(&new_todo);
98b29e0607 4805) if (opts->allow_ff && skip_unnecessary_picks(r, &new_todo, &oid)) {
98b29e0607 4806) todo_list_release(&new_todo);
c1c074e0cc 4810) if (todo_list_write_to_file(r, &new_todo, todo_file, NULL, NULL, -1,
c1c074e0cc 4812) todo_list_release(&new_todo);
c1c074e0cc 4813) return error_errno(_("could not write '%s'"), todo_file);
c1c074e0cc 4816) todo_list_release(&new_todo);
febebd99b6 4851) static int todo_list_rearrange_squash(struct todo_list *todo_list)
febebd99b6 4854) int rearranged = 0, *next, *tail, i, nr = 0, alloc = 0;
febebd99b6 4857) struct todo_item *items = NULL;
febebd99b6 4870)      NULL, todo_list->nr);
febebd99b6 4871) ALLOC_ARRAY(next, todo_list->nr);
febebd99b6 4872) ALLOC_ARRAY(tail, todo_list->nr);
febebd99b6 4873) ALLOC_ARRAY(subjects, todo_list->nr);
febebd99b6 4874) for (i = 0; i < todo_list->nr; i++) {
febebd99b6 4876) struct todo_item *item = todo_list->items + i;
febebd99b6 4923) - todo_list->items;
febebd99b6 4936) todo_list->items[i].command =
febebd99b6 4954) for (i = 0; i < todo_list->nr; i++) {
febebd99b6 4955) enum todo_command command = todo_list->items[i].command;
febebd99b6 4966) ALLOC_GROW(items, nr + 1, alloc);
febebd99b6 4967) items[nr++] = todo_list->items[cur];
febebd99b6 4972) FREE_AND_NULL(todo_list->items);
febebd99b6 4973) todo_list->items = items;
febebd99b6 4974) todo_list->nr = nr;
febebd99b6 4975) todo_list->alloc = alloc;
febebd99b6 4980) for (i = 0; i < todo_list->nr; i++)
febebd99b6 4987) return 0;
febebd99b6 4990) int rearrange_squash_in_todo_file(struct repository *r)
febebd99b6 4992) const char *todo_file = rebase_path_todo();
febebd99b6 4993) struct todo_list todo_list = TODO_LIST_INIT;
febebd99b6 4994) int res = 0;
febebd99b6 4996) if (strbuf_read_file_or_whine(&todo_list.buf, todo_file) < 0)
febebd99b6 4997) return -1;
febebd99b6 4998) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, &todo_list) < 0) {
febebd99b6 4999) todo_list_release(&todo_list);
febebd99b6 5000) return -1;
febebd99b6 5003) res = todo_list_rearrange_squash(&todo_list);
febebd99b6 5004) if (!res)
febebd99b6 5005) res = todo_list_write_to_file(r, &todo_list, todo_file, NULL, NULL, -1, 0);
febebd99b6 5007) todo_list_release(&todo_list);
febebd99b6 5009) if (res)
febebd99b6 5010) return error_errno(_("could not write '%s'."), todo_file);
febebd99b6 5011) return 0;

sha1-name.c
4e763fae87 sha1-name.c 1523) int get_oidf(struct object_id *oid, const char *fmt, ...)
4e763fae87 sha1-name.c 1527) struct strbuf sb = STRBUF_INIT;
4e763fae87 sha1-name.c 1529) va_start(ap, fmt);
4e763fae87 sha1-name.c 1530) strbuf_vaddf(&sb, fmt, ap);
4e763fae87 sha1-name.c 1531) va_end(ap);
4e763fae87 sha1-name.c 1533) ret = get_oid(sb.buf, oid);
4e763fae87 sha1-name.c 1534) strbuf_release(&sb);
4e763fae87 sha1-name.c 1536) return ret;
3a7a698e93 sha1-name.c 1624) static void diagnose_invalid_index_path(struct index_state *istate,
3a7a698e93 sha1-name.c 1638) pos = index_name_pos(istate, filename, namelen);
3a7a698e93 sha1-name.c 1641) if (pos < istate->cache_nr) {
3a7a698e93 sha1-name.c 1642) ce = istate->cache[pos];
3a7a698e93 sha1-name.c 1654) pos = index_name_pos(istate, fullname.buf, fullname.len);
3a7a698e93 sha1-name.c 1657) if (pos < istate->cache_nr) {
3a7a698e93 sha1-name.c 1658) ce = istate->cache[pos];
3a7a698e93 sha1-name.c 1771) diagnose_invalid_index_path(repo->index, stage, prefix, cp);

strbuf.c
bfc3fe33f6  252) void strbuf_vinsertf(struct strbuf *sb, size_t pos, const char *fmt, va_list ap)
bfc3fe33f6  258) if (pos > sb->len)
bfc3fe33f6  259) die("`pos' is too far after the end of the buffer");
bfc3fe33f6  260) va_copy(cp, ap);
bfc3fe33f6  261) len = vsnprintf(sb->buf + sb->len, 0, fmt, cp);
bfc3fe33f6  262) va_end(cp);
bfc3fe33f6  263) if (len < 0)
bfc3fe33f6  265) if (!len)
bfc3fe33f6  266) return; /* nothing to do */
bfc3fe33f6  267) if (unsigned_add_overflows(sb->len, len))
bfc3fe33f6  268) die("you want to use way too much memory");
bfc3fe33f6  269) strbuf_grow(sb, len);
bfc3fe33f6  270) memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos);
bfc3fe33f6  272) save = sb->buf[pos + len];
bfc3fe33f6  273) len2 = vsnprintf(sb->buf + pos, sb->alloc - sb->len, fmt, ap);
bfc3fe33f6  274) sb->buf[pos + len] = save;
bfc3fe33f6  275) if (len2 != len)
bfc3fe33f6  277) strbuf_setlen(sb, sb->len + len);
bfc3fe33f6  280) void strbuf_insertf(struct strbuf *sb, size_t pos, const char *fmt, ...)
bfc3fe33f6  283) va_start(ap, fmt);
bfc3fe33f6  284) strbuf_vinsertf(sb, pos, fmt, ap);
bfc3fe33f6  285) va_end(ap);
bfc3fe33f6  286) }
0c1599c33c  307) const char *strbuf_join_argv(struct strbuf *buf,
0c1599c33c  310) if (!argc)
0c1599c33c  311) return buf->buf;
0c1599c33c  313) strbuf_addstr(buf, *argv);
0c1599c33c  314) while (--argc) {
0c1599c33c  315) strbuf_addch(buf, delim);
0c1599c33c  316) strbuf_addstr(buf, *(++argv));
0c1599c33c  319) return buf->buf;
18f8e81091  442) strbuf_addch(sb, '\n');
18f8e81091  443) return 1;
18f8e81091  446) ch = hex2chr(placeholder + 1);
18f8e81091  447) if (ch < 0)
18f8e81091  448) return 0;
18f8e81091  449) strbuf_addch(sb, ch);
18f8e81091  450) return 3;

trailer.c
ced45aab72 1132) size_t origlen = out->len;
ced45aab72 1136) if (!opts->only_trailers && !opts->unfold && !opts->filter && !opts->separator) {
4681fe38e1 1151) if (!opts->filter || opts->filter(&tok, opts->filter_data)) {
4681fe38e1 1152) if (opts->unfold)
4681fe38e1 1153) unfold_value(&val);
ced45aab72 1155) if (opts->separator && out->len != origlen)
ced45aab72 1156) strbuf_addbuf(out, opts->separator);
e9da5de761 1157) if (!opts->value_only)
e9da5de761 1158) strbuf_addf(out, "%s: ", tok.buf);
e9da5de761 1159) strbuf_addbuf(out, &val);
ced45aab72 1160) if (!opts->separator)
ced45aab72 1161) strbuf_addch(out, '\n');
ced45aab72 1167) if (opts->separator && out->len != origlen) {
ced45aab72 1168) strbuf_addbuf(out, opts->separator);
ced45aab72 1171) if (opts->separator) {
ced45aab72 1172) strbuf_rtrim(out);

worktree.c
2ec5633ff4 587) char *get_worktree_config(struct repository *r)
2ec5633ff4 589) struct worktree **worktrees = get_worktrees(0);
2ec5633ff4 592) if (repository_format_worktree_config)
2ec5633ff4 593) path = repo_git_path(r, "config.worktree");
2ec5633ff4 594) else if (worktrees[0] && worktrees[1])
2ec5633ff4 595) path = NULL;
2ec5633ff4 597) path = repo_git_path(r, "config");
2ec5633ff4 599) free_worktrees(worktrees);
2ec5633ff4 600) return path;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate %" PRIuMAX " bytes)",

wt-status.c
3a95f31d1c 2378) fd = repo_hold_locked_index(r, &lock_file, 0);
1b0d968b34 2381) repo_update_index_if_able(r, &lock_file);

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      97b202471: commit-graph write: use pack order when finding commits
Alban Gruin      0566a4f68: sequencer: make sequencer_make_script() write its script to a strbuf
Alban Gruin      2b71595d4: sequencer: changes in parse_insn_buffer()
Alban Gruin      2dd989a69: rebase-interactive: append_todo_help() changes
Alban Gruin      33bc1844f: sequencer: use edit_todo_list() in complete_action()
Alban Gruin      3ebafef41: sequencer: refactor transform_todos() to work on a todo_list
Alban Gruin      4d55dfd76: rebase-interactive: move transform_todo_file() to rebase--interactive.c
Alban Gruin      5d94d5456: sequencer: make the todo_list structure public
Alban Gruin      8414c890a: sequencer: refactor sequencer_add_exec_commands() to work on a todo_list
Alban Gruin      98b29e060: sequencer: refactor skip_unnecessary_picks() to work on a todo_list
Alban Gruin      c1c074e0c: sequencer: change complete_action() to use the refactored functions
Alban Gruin      c27b32f0e: sequencer: refactor check_todo_list() to work on a todo_list
Alban Gruin      cf18b3f6c: sequencer: introduce todo_list_write_to_file()
Alban Gruin      d836079ec: sequencer: remove the 'arg' field from todo_item
Alban Gruin      e5b1c9d92: rebase-interactive: rewrite edit_todo_list() to handle the initial edit
Alban Gruin      febebd99b: sequencer: refactor rearrange_squash() to work on a todo_list
Anders Waldenborg      18f8e8109: strbuf: separate callback for strbuf_expand:ing literals
Anders Waldenborg      4681fe38e: pretty: allow showing specific trailers
Anders Waldenborg      b755bf6f8: pretty: allow %(trailers) options with explicit value
Anders Waldenborg      ced45aab7: pretty: add support for separator option in %(trailers)
Anders Waldenborg      e9da5de76: pretty: add support for "valueonly" option in %(trailers)
Anders Waldenborg      ffd7cae40: pretty: single return path in %(trailers) handling
Barret Rhoden      07d04b919: blame: add a config option to mark ignored lines
Barret Rhoden      e7973c851: blame: add the ability to ignore commits and their changes
Barret Rhoden      ef644c415: Move init_skiplist() outside of fsck
Derrick Stolee      3d036eb0d: pack-objects: create pack.useSparse setting
Derrick Stolee      4f6d26b16: list-objects: consume sparse tree walk
Derrick Stolee      d5d2e9357: revision: implement sparse algorithm
Derrick Stolee      f1f5de442: revision: add mark_tree_uninteresting_sparse
Jeff King      240fb9b7a: remote-curl: tighten "version 2" check for smart-http
Jeff King      34a9469d6: remote-curl: refactor smart-http discovery
Jiang Xin      a338d1039: pack-redundant: consistent sort method
Jiang Xin      cb7e0336f: pack-redundant: rename pack_list.all_objects
Joel Teichroeb      cdca49bc4: stash: convert drop and clear to builtin
Joel Teichroeb      e1d01876a: stash: convert pop to builtin
Joel Teichroeb      f596f3366: stash: convert branch to builtin
Joel Teichroeb      f6bbd7812: stash: convert apply to builtin
Johannes Schindelin      26799a208: stash: optionally use the scripted version again
Johannes Schindelin      97f56073c: ident: add the ability to provide a "fallback identity"
Johannes Schindelin      bec65d5b7: tests: add a special setup where stash.useBuiltin is off
Josh Steadmon      6da1f1a92: protocol: advertise multiple supported versions
Josh Steadmon      e586e7df7: remote-curl: die on server-side errors
Junio C Hamano      5dde8fc6d: Merge branch 'ds/push-sparse-tree-walk' into pu
Junio C Hamano      b6b4172bf: Merge branch 'nd/the-index-final' into pu
Liam Beguin      0cce4a275: rebase -i -x: add exec commands via the rebase--helper
Linus Torvalds      acdd37769: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Matthew Kraai      ed5d77f7d: stash: fix segmentation fault when files were added with intent
Nguyễn Thái Ngọc Duy      059343267: diff.c: convert --no-prefix
Nguyễn Thái Ngọc Duy      06800238c: config.c: avoid git_path() in do_git_config_sequence()
Nguyễn Thái Ngọc Duy      08339886b: parse-options: avoid magic return codes
Nguyễn Thái Ngọc Duy      08d080bf7: diff.c: convert --word-diff
Nguyễn Thái Ngọc Duy      0d6caa2d0: merge-recursive.c: remove implicit dependency on the_index
Nguyễn Thái Ngọc Duy      0eb03c4cd: diff.c: convert --stat*
Nguyễn Thái Ngọc Duy      10e07ecc0: diff.c: convert -M|--find-renames
Nguyễn Thái Ngọc Duy      150fe065f: read-cache.c: remove the_* from index_has_changes()
Nguyễn Thái Ngọc Duy      1b0d968b3: read-cache.c: replace update_index_if_able with repo_&
Nguyễn Thái Ngọc Duy      1d18d7581: notes-utils.c: remove the_repository references
Nguyễn Thái Ngọc Duy      1d2890f4f: diff.c: convert --submodule
Nguyễn Thái Ngọc Duy      1d8598834: diff.c: convert --textconv
Nguyễn Thái Ngọc Duy      1efc2689d: diff.c: convert --diff-algorithm
Nguyễn Thái Ngọc Duy      2156b1fd0: diff.c: convert --patience
Nguyễn Thái Ngọc Duy      221d67669: diff.c: convert --color-moved
Nguyễn Thái Ngọc Duy      26c50430d: range-diff: use parse_options() instead of diff_opt_parse()
Nguyễn Thái Ngọc Duy      2ec5633ff: worktree.c: add get_worktree_config()
Nguyễn Thái Ngọc Duy      350a71f2f: diff.c: convert --relative
Nguyễn Thái Ngọc Duy      3a7a698e9: sha1-name.c: remove implicit dependency on the_index
Nguyễn Thái Ngọc Duy      3a95f31d1: repository.c: replace hold_locked_index() with repo_hold_locked_index()
Nguyễn Thái Ngọc Duy      3d810d186: diff.c: convert --output-*
Nguyễn Thái Ngọc Duy      447867144: cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch
Nguyễn Thái Ngọc Duy      5866e9ce9: diff.c: convert --find-object
Nguyễn Thái Ngọc Duy      58c7ef398: diff.c: convert --[no-]compact-summary
Nguyễn Thái Ngọc Duy      6643eb7bb: diff.c: convert -U|--unified
Nguyễn Thái Ngọc Duy      6c0ec4f72: diff.c: convert --line-prefix
Nguyễn Thái Ngọc Duy      6d0300b2e: diff.c: convert --binary
Nguyễn Thái Ngọc Duy      6f11fd5ed: config: add --move-to
Nguyễn Thái Ngọc Duy      7c33a67a2: diff.c: convert --color-moved-ws
Nguyễn Thái Ngọc Duy      8b70e4177: diff.c: convert --ws-error-highlight
Nguyễn Thái Ngọc Duy      8f7c7f555: config.c: add repo_config_set_worktree_gently()
Nguyễn Thái Ngọc Duy      8fc6b47cd: diff.c: convert --[no-]abbrev
Nguyễn Thái Ngọc Duy      963389f6e: diff --no-index: use parse_options() instead of diff_opt_parse()
Nguyễn Thái Ngọc Duy      97e53999c: diff.c: convert -C|--find-copies
Nguyễn Thái Ngọc Duy      9b4ae5190: parse-options: allow ll_callback with OPTION_CALLBACK
Nguyễn Thái Ngọc Duy      a12c1ff3a: config: factor out set_config_source_file()
Nguyễn Thái Ngọc Duy      afe77a4dd: diff.c: convert --word-diff-regex
Nguyễn Thái Ngọc Duy      b065b6607: diff.c: convert --anchored
Nguyễn Thái Ngọc Duy      b74a81799: diff.c: convert --diff-filter
Nguyễn Thái Ngọc Duy      b9b760ed1: diff.c: convert -B|--break-rewrites
Nguyễn Thái Ngọc Duy      c2dcec4fd: diff.c: convert --[no-]follow
Nguyễn Thái Ngọc Duy      d071ebcc8: diff.c: convert -S|-G
Nguyễn Thái Ngọc Duy      d7cf3a96e: merge-recursive.c: remove implicit dependency on the_repository
Nguyễn Thái Ngọc Duy      da9db54b3: diff.c: allow --no-color-moved-ws
Nguyễn Thái Ngọc Duy      dba093ddc: grep: use grep_opt->repo instead of explict repo argument
Nguyễn Thái Ngọc Duy      e1ff0a32e: read-cache.c: kill read_index()
Nguyễn Thái Ngọc Duy      f3b49b7f9: diff.c: convert --color-words
Nguyễn Thái Ngọc Duy      f8d10810d: diff.c: convert --dirstat and friends
Paul-Sebastian Ungureanu      0c1599c33: strbuf.c: add `strbuf_join_argv()`
Paul-Sebastian Ungureanu      168e6cff5: stash: optimize `get_untracked_files()` and `check_changes()`
Paul-Sebastian Ungureanu      1f5a011d9: stash: convert create to builtin
Paul-Sebastian Ungureanu      4e763fae8: sha1-name.c: add `get_oidf()` which acts like `get_oid()`
Paul-Sebastian Ungureanu      51809c70c: stash: convert `stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      559edead8: stash: replace all `write-tree` child processes with API calls
Paul-Sebastian Ungureanu      847eb0b0a: stash: convert store to builtin
Paul-Sebastian Ungureanu      9a95010a1: stash: make push -q quiet
Paul-Sebastian Ungureanu      9b77b07ba: stash: convert list to builtin
Paul-Sebastian Ungureanu      b4493f269: stash: convert show to builtin
Paul-Sebastian Ungureanu      bfc3fe33f: strbuf.c: add `strbuf_insertf()` and `strbuf_vinsertf()`
Paul-Sebastian Ungureanu      cf5b27d69: stash: convert save to builtin
Paul-Sebastian Ungureanu      fa38428f7: stash: convert push to builtin
René Scharfe      878056005: sequencer: factor out strbuf_read_file_or_whine()
Stephen P. Smith      6943bd42f: Add `human` format to test-tool
Stephen P. Smith      86177eb5c: Remove the proposed use of auto as secondary way to specify human
Sun Chao      e4e2c2884: pack-redundant: new algorithm to find min packs



Uncovered code in 'jch' not in 'next'
----------------------------------------

builtin/archive.c
01f9ec64c8 builtin/archive.c  63) if (starts_with(reader.line, "NACK "))
01f9ec64c8 builtin/archive.c  64) die(_("git archive: NACK %s"), reader.line + 5);

builtin/bisect--helper.c
5e82c3dd22 builtin/bisect--helper.c 162) if (get_oid_commit(commit, &oid))
5e82c3dd22 builtin/bisect--helper.c 163) return error(_("'%s' is not a valid commit"), commit);
5e82c3dd22 builtin/bisect--helper.c 164) strbuf_addstr(&branch, commit);
5e82c3dd22 builtin/bisect--helper.c 172) strbuf_release(&branch);
5e82c3dd22 builtin/bisect--helper.c 173) argv_array_clear(&argv);
5e82c3dd22 builtin/bisect--helper.c 174) return error(_("could not check out original"
0f30233a11 builtin/bisect--helper.c 215) retval = error(_("Bad bisect_write argument: %s"), state);
0f30233a11 builtin/bisect--helper.c 216) goto finish;
0f30233a11 builtin/bisect--helper.c 220) retval = error(_("couldn't get the oid of the rev '%s'"), rev);
0f30233a11 builtin/bisect--helper.c 221) goto finish;
0f30233a11 builtin/bisect--helper.c 226) retval = -1;
0f30233a11 builtin/bisect--helper.c 227) goto finish;
0f30233a11 builtin/bisect--helper.c 232) retval = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
0f30233a11 builtin/bisect--helper.c 233) goto finish;
129a6cf344 builtin/bisect--helper.c 329) yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
129a6cf344 builtin/bisect--helper.c 330) if (starts_with(yesno, "N") || starts_with(yesno, "n"))
129a6cf344 builtin/bisect--helper.c 331) retval = -1;
129a6cf344 builtin/bisect--helper.c 332) goto finish;
129a6cf344 builtin/bisect--helper.c 338) retval = error(_(need_bisect_start_warning),
450ebb7359 builtin/bisect--helper.c 389) return error(_("invalid argument %s for 'git bisect terms'.\n"
06f5608c14 builtin/bisect--helper.c 404) return -1;
06f5608c14 builtin/bisect--helper.c 407) retval = -1;
06f5608c14 builtin/bisect--helper.c 408) goto finish;
06f5608c14 builtin/bisect--helper.c 413) retval = -1;
06f5608c14 builtin/bisect--helper.c 452) no_checkout = 1;
06f5608c14 builtin/bisect--helper.c 474)  !one_of(arg, "--term-good", "--term-bad", NULL)) {
06f5608c14 builtin/bisect--helper.c 475) return error(_("unrecognized option: '%s'"), arg);
06f5608c14 builtin/bisect--helper.c 510) if (get_oid("HEAD", &head_oid))
06f5608c14 builtin/bisect--helper.c 511) return error(_("bad HEAD - I need a HEAD"));
06f5608c14 builtin/bisect--helper.c 526) retval = error(_("checking out '%s' failed."
06f5608c14 builtin/bisect--helper.c 547) return error(_("won't bisect on cg-seek'ed tree"));
06f5608c14 builtin/bisect--helper.c 550) return error(_("bad HEAD - strange symbolic ref"));
06f5608c14 builtin/bisect--helper.c 558) return -1;
06f5608c14 builtin/bisect--helper.c 576) retval = -1;
06f5608c14 builtin/bisect--helper.c 577) goto finish;
06f5608c14 builtin/bisect--helper.c 588) retval = -1;
06f5608c14 builtin/bisect--helper.c 589) goto finish;
06f5608c14 builtin/bisect--helper.c 600) retval = -1;
5e82c3dd22 builtin/bisect--helper.c 677) return error(_("--bisect-reset requires either no argument or a commit"));
0f30233a11 builtin/bisect--helper.c 681) return error(_("--bisect-write requires either 4 or 5 arguments"));
4fbdbd5bff builtin/bisect--helper.c 687) return error(_("--check-and-set-terms requires 3 arguments"));
129a6cf344 builtin/bisect--helper.c 693) return error(_("--bisect-next-check requires 2 or 3 arguments"));

builtin/branch.c
711d28e2e4 builtin/branch.c 370) strbuf_addf(&local, "%s%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)%%(worktreepath) %%(end)%%(end)%s",
0ecb1fc726 builtin/branch.c 460) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 466) die(_("HEAD (%s) points outside of refs/heads/"), refname);

builtin/multi-pack-index.c
334e9745a6 49) die(_("--batch-size option is only for 'repack' subcommand"));

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

builtin/rebase.c
21853626ea  258) write_file(state_dir_path("verbose", opts), "%s", "");
21853626ea  260) write_file(state_dir_path("strategy", opts), "%s",
21853626ea  263) write_file(state_dir_path("strategy_opts", opts), "%s",
21853626ea  270) write_file(state_dir_path("gpg_sign_opt", opts), "%s",
21853626ea  273) write_file(state_dir_path("strategy", opts), "--signoff");
c5233708c5  396) ret = -1;
c5233708c5  397) goto leave_reset_head;
c5233708c5  401) ret = error(_("could not determine HEAD revision"));
c5233708c5  402) goto leave_reset_head;
c5233708c5  423) ret = error(_("could not read index"));
c5233708c5  424) goto leave_reset_head;
c5233708c5  428) ret = error(_("failed to find tree of %s"),
c5233708c5  430) goto leave_reset_head;
c5233708c5  434) ret = error(_("failed to find tree of %s"), oid_to_hex(oid));
c5233708c5  435) goto leave_reset_head;
c5233708c5  447) ret = error(_("could not write index"));
c5233708c5  448) goto leave_reset_head;
c5233708c5  466) } else if (old_orig)
c5233708c5  467) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
21853626ea  542) argv_array_push(&am.args, opts->gpg_sign_opt);
21853626ea  574) status = error_errno(_("could not open '%s' for writing"),
21853626ea  576) free(rebased_patches);
21853626ea  577) argv_array_clear(&am.args);
21853626ea  578) return status;
21853626ea  587) argv_array_split(&format_patch.args,
21853626ea  588)  opts->git_format_patch_opt.buf);
21853626ea  596) unlink(rebased_patches);
21853626ea  597) free(rebased_patches);
21853626ea  598) argv_array_clear(&am.args);
21853626ea  600) reset_head(&opts->orig_head, "checkout", opts->head_name, 0,
21853626ea  602) error(_("\ngit encountered an error while preparing the "
21853626ea  609) strbuf_release(&revisions);
21853626ea  610) return status;
21853626ea  616) status = error_errno(_("could not open '%s' for reading"),
21853626ea  618) free(rebased_patches);
21853626ea  619) argv_array_clear(&am.args);
21853626ea  620) return status;

builtin/receive-pack.c
01f9ec64c8 builtin/receive-pack.c 1587)     reader->line + 8);
01f9ec64c8 builtin/receive-pack.c 1621) die("protocol error: got an unexpected packet");

builtin/remote.c
f39a9c6547 builtin/remote.c 1551) die(_("--save-to-push cannot be used with other options"));
f39a9c6547 builtin/remote.c 1575) die(_("--save-to-push can only be used when only one url is defined"));

commit-graph.c
aa658574bf  127) return NULL;
aa658574bf  130) return NULL;
aa658574bf  186) free(graph);
aa658574bf  187) return NULL;
aa658574bf  222) free(graph);
aa658574bf  223) return NULL;
64415806e8  933) display_progress(oids.progress, approx_nr_objects);

config.c
7e43b32b58 1488) return git_ident_config(var, value, cb);
7e43b32b58 1491) return git_ident_config(var, value, cb);

fetch-pack.c
01f9ec64c8  154) die(_("git fetch-pack: expected a flush packet after shallow list"));
01f9ec64c8  358) die(_("invalid shallow line: %s"), reader.line);
01f9ec64c8  364) die(_("invalid unshallow line: %s"), reader.line);
01f9ec64c8  366) die(_("object not found: %s"), reader.line);
01f9ec64c8  369) die(_("error in object: %s"), reader.line);
01f9ec64c8  371) die(_("no shallow found: %s"), reader.line);
01f9ec64c8  374) die(_("expected shallow/unshallow, got %s"), reader.line);
0bbc0bc574 1128) packet_buf_write(&req_buf, "sideband-all");
0bbc0bc574 1350) reader.use_sideband = 1;
0bbc0bc574 1351) reader.me = "fetch-pack";

http-walker.c
514c5fdd03 http-walker.c 550) loose_object_path(the_repository, &buf, &req->oid);

ident.c
7e43b32b58 373) email = git_author_email.buf;
7e43b32b58 375) email = git_committer_email.buf;
7e43b32b58 394) name = git_author_name.buf;
7e43b32b58 396) name = git_committer_name.buf;
7e43b32b58 504) if (!value)
7e43b32b58 505) return config_error_nonbool(var);
7e43b32b58 506) strbuf_reset(&git_author_name);
7e43b32b58 507) strbuf_addstr(&git_author_name, value);
7e43b32b58 508) author_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b58 509) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b58 510) return 0;
7e43b32b58 514) if (!value)
7e43b32b58 515) return config_error_nonbool(var);
7e43b32b58 516) strbuf_reset(&git_author_email);
7e43b32b58 517) strbuf_addstr(&git_author_email, value);
7e43b32b58 518) author_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b58 519) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b58 520) return 0;
7e43b32b58 524) if (!value)
7e43b32b58 525) return config_error_nonbool(var);
7e43b32b58 526) strbuf_reset(&git_committer_name);
7e43b32b58 527) strbuf_addstr(&git_committer_name, value);
7e43b32b58 528) committer_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b58 529) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b58 530) return 0;
7e43b32b58 534) if (!value)
7e43b32b58 535) return config_error_nonbool(var);
7e43b32b58 536) strbuf_reset(&git_committer_email);
7e43b32b58 537) strbuf_addstr(&git_committer_email, value);
7e43b32b58 538) committer_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b58 539) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b58 540) return 0;

midx.c
e7a330ee26  428) close_pack(packs->info[packs->nr].p);
e7a330ee26  429) FREE_AND_NULL(packs->info[packs->nr].p);
14b7185175  815) error(_("did not see pack-file %s to drop"),
14b7185175  817) drop_index++;
14b7185175  818) missing_drops++;
14b7185175  819) i--;
14b7185175  826) result = 1;
14b7185175  827) goto cleanup;
14b7185175 1073) return 0;
14b7185175 1088) continue;
14b7185175 1091) continue;
17d0bf5a7d 1142) return 0;
17d0bf5a7d 1151) continue;
17d0bf5a7d 1164) continue;
17d0bf5a7d 1187) error(_("could not start pack-objects"));
17d0bf5a7d 1188) result = 1;
17d0bf5a7d 1189) goto cleanup;
17d0bf5a7d 1206) error(_("could not finish pack-objects"));
17d0bf5a7d 1207) result = 1;
17d0bf5a7d 1208) goto cleanup;

packfile.c
9133688752  369) strbuf_release(&buf);
9133688752  370) return;

pkt-line.c
0bbc0bc574 505) if (demultiplex_sideband(reader->me, reader->buffer,
0bbc0bc574 508) break;
0bbc0bc574 509) }

read-cache.c
ee70c12820 1736) if (advice_unknown_index_extension) {
ee70c12820 1737) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1738) advise(_("This is likely due to the file having been written by a newer\n"

ref-filter.c
a9fb549b1d  467) return 0;

remote-curl.c
01f9ec64c8  427) die("invalid server response; got '%s'", reader.line);
01f9ec64c8  439) }

send-pack.c
01f9ec64c8 143) return error(_("unable to parse remote unpack status: %s"), reader->line);
01f9ec64c8 162) error("invalid ref status from remote: %s", reader->line);
01f9ec64c8 579) receive_unpack_status(&reader);

sequencer.c
899b49c446 2394) opts->quiet = 1;

sha1-file.c
514c5fdd03 sha1-file.c 1291) status = error(_("unable to parse %s header"), oid_to_hex(oid));
00a7760e81 sha1-file.c 2305) the_hash_algo->final_fn(real_oid.hash, &c);
00a7760e81 sha1-file.c 2306) if (!oideq(expected_oid, &real_oid)) {

sideband.c
fbd76cd450 128) suffix = ANSI_SUFFIX;
fbd76cd450 138) strbuf_addf(scratch,
fbd76cd450 140)     scratch->len ? "\n" : "", me);
fbd76cd450 141) *sideband_type = SIDEBAND_PROTOCOL_ERROR;
fbd76cd450 142) goto cleanup;
0bbc0bc574 150) die("remote error: %s", buf + 1);
fbd76cd450 195) strbuf_addf(scratch, "%s%s: protocol error: bad band #%d",
fbd76cd450 196)     scratch->len ? "\n" : "", me, band);
fbd76cd450 197) *sideband_type = SIDEBAND_PROTOCOL_ERROR;
fbd76cd450 198) break;
0bbc0bc574 203) die("%s", scratch->buf);

upload-pack.c
01f9ec64c8  432) die("git upload-pack: expected SHA1 list, got '%s'", reader->line);
0bbc0bc574 1066) allow_sideband_all = git_config_bool(var, value);
07c3c2aa16 1306)      allow_sideband_all) &&
07c3c2aa16 1307)     !strcmp(arg, "sideband-all")) {
0bbc0bc574 1308) data->writer.use_sideband = 1;
0bbc0bc574 1309) continue;
bc2e795cea 1441) deepen(&data->writer, INFINITE_DEPTH, data->deepen_relative,
07c3c2aa16 1544)    &allow_sideband_all_value) &&

worktree.c
ebefff3c73 465) clear_repository_format(&format);

wrapper.c
e3b1e3bdc0 701) die_errno(_("could not stat %s"), filename);

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      64415806e: commit-graph write: show progress for object search
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current display option
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Denton Liu      f39a9c654: remote: add --save-to-push option to git remote set-url
Derrick Stolee      14b718517: multi-pack-index: implement 'expire' subcommand
Derrick Stolee      17d0bf5a7: midx: implement midx_repack()
Derrick Stolee      334e9745a: multi-pack-index: prepare 'repack' subcommand
Derrick Stolee      913368875: repack: refactor pack deletion for future use
Derrick Stolee      e7a330ee2: midx: refactor permutation logic and pack sorting
Elijah Newren      899b49c44: git-rebase, sequencer: extend --quiet option for the interactive machinery
Jeff King      00a7760e8: sha1-file: modernize loose header/stream functions
Jeff King      514c5fdd0: sha1-file: modernize loose object file functions
Johannes Schindelin      21853626e: built-in rebase: call `git am` directly
Johannes Schindelin      c5233708c: rebase: move `reset_head()` into a better spot
Jonathan Nieder      ee70c1282: index: offer advice for unknown index extensions
Jonathan Tan      07c3c2aa1: tests: define GIT_TEST_SIDEBAND_ALL
Jonathan Tan      0bbc0bc57: {fetch,upload}-pack: sideband v2 fetch response
Jonathan Tan      bc2e795ce: pkt-line: introduce struct packet_writer
Jonathan Tan      fbd76cd45: sideband: reverse its dependency on pkt-line
Josh Steadmon      aa658574b: commit-graph, fuzz: add fuzzer for commit-graph
Martin Ågren      ebefff3c7: setup: add `clear_repository_format()`
Masaya Suzuki      01f9ec64c: Use packet_reader instead of packet_read_line
Nickolai Belakovski      711d28e2e: branch: add an extra verbose output displaying worktree path for checked out branch
Nickolai Belakovski      a9fb549b1: ref-filter: add worktreepath atom
Pranit Bauva      06f5608c1: bisect--helper: `bisect_start` shell function partially in C
Pranit Bauva      0f30233a1: bisect--helper: `bisect_write` shell function in C
Pranit Bauva      129a6cf34: bisect--helper: `bisect_next_check` shell function in C
Pranit Bauva      450ebb735: bisect--helper: `get_terms` & `bisect_terms` shell function in C
Pranit Bauva      4fbdbd5bf: bisect--helper: `check_and_set_terms` shell function in C
Pranit Bauva      5e82c3dd2: bisect--helper: `bisect_reset` shell function in C
Pranit Bauva      e3b1e3bdc: wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()
William Hubbs      7e43b32b5: Add author and committer configuration settings



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/checkout.c
091e04bc8c builtin/checkout.c  302) return;
091e04bc8c builtin/checkout.c 1268) die(_("'%s' cannot be used with switching branches"),

builtin/fetch-pack.c
4316ff3068 builtin/fetch-pack.c 226) get_remote_refs(fd[1], &reader, &ref, 0, NULL, NULL);
4316ff3068 builtin/fetch-pack.c 227) break;

builtin/fetch.c
e01378753d builtin/fetch.c 1479) die(_("--filter can only be used with the remote "
e01378753d builtin/fetch.c 1648) die(_("--filter can only be used with the remote "

builtin/rebase.c
81ef8ee75d  773) return -1;
d421afa0c6 1258) die(_("--reschedule-failed-exec requires an interactive rebase"));
d421afa0c6 1296) die(_("error: cannot combine '--preserve-merges' with "

diff.c
b73bcbac4a  308) ret = 0;
21536d077f  812)        (s[off] == '\r' && off < len - 1))
21536d077f  813) off++;
b73bcbac4a 5112) options->color_moved_ws_handling = 0;

entry.c
hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, &hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

http-push.c
ea82b2a085 1314) p = process_tree(lookup_tree(the_repository, &entry.oid),

http.c
e6cf87b12d 1999) if (fflush(result)) {
e6cf87b12d 2000) error_errno("unable to flush a file");
e6cf87b12d 2001) return HTTP_START_FAILED;
e6cf87b12d 2003) rewind(result);
e6cf87b12d 2004) if (ftruncate(fileno(result), 0) < 0) {
e6cf87b12d 2005) error_errno("unable to truncate a file");
e6cf87b12d 2006) return HTTP_START_FAILED;
e6cf87b12d 2008) break;

list-objects-filter.c
c813a7c35f 199) return;

match-trees.c
f55ac4311a 231) hashcpy(tree_oid.hash, rewrite_here);
f55ac4311a 232) status = splice_tree(&tree_oid, subpath, oid2, &subtree);

pretty.c
ad6f028f06 1204) return 0;

remote-curl.c
b79bdd8c12  566) return size;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

submodule.c
26f80ccfc1 1398) strbuf_release(&gitdir);
be76c21282 1521) struct fetch_task *task = task_cb;
be76c21282 1525) fetch_task_release(task);

tree-walk.c
0a3faa45b1  530) oidcpy(result, &oid);

tree.c
60c38b9e4a 104) commit = lookup_commit(r, &entry.oid);

upload-pack.c
87c2d9d310  147) sq_quote_buf(&buf, expanded_filter_spec.buf);

Commits introducing uncovered code:
brian m. carlson      0a3faa45b: tree-walk: copy object ID before use
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print arbitrary hashes
brian m. carlson      ea82b2a08: tree-walk: store object_id in a separate member
brian m. carlson      f55ac4311: match-trees: use hashcpy to splice trees
Christian Couder      e01378753: fetch: fix extensions.partialclone name in error message
Issac Trotts      ad6f028f0: log: add %S option (like --source) to log --format
Johannes Schindelin      81ef8ee75: rebase: introduce a shortcut for --reschedule-failed-exec
Johannes Schindelin      d421afa0c: rebase: introduce --reschedule-failed-exec
Jonathan Tan      4316ff306: fetch-pack: support protocol version 2
Josh Steadmon      87c2d9d31: filter-options: expand scaled numbers
Junio C Hamano      60c38b9e4: Merge branch 'bc/tree-walk-oid' into next
Masaya Suzuki      b79bdd8c1: remote-curl: unset CURLOPT_FAILONERROR
Masaya Suzuki      e6cf87b12: http: enable keep_error for HTTP requests
Matthew DeVore      c813a7c35: list-objects-filter: teach tree:# how to handle >0
Phillip Wood      21536d077: diff --color-moved-ws: modify allow-indentation-change
Phillip Wood      b73bcbac4: diff: allow --no-color-moved-ws
Stefan Beller      26f80ccfc: submodule: migrate get_next_submodule to use repository structs
Stefan Beller      be76c2128: fetch: ensure submodule objects fetched
Thomas Gummerer      091e04bc8: checkout: introduce --{,no-}overlay option



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/submodule--helper.c
builtin/worktree.c
00a6d4d1d2 752) found_submodules = 1;
00a6d4d1d2 753) break;

commit-graph.c
ref-filter.c
1867ce6cbe  236) oi_deref.info.sizep = &oi_deref.size;
1867ce6cbe  245) return strbuf_addf_ret(err, -1, _("unrecognized %%(objectsize) argument: %s"), arg);
33311fa1ad  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does not take arguments"));

setup.c
07098b81a4 1093) if (!nongit_ok)
07098b81a4 1094) die(_("not a git repository (or any parent up to mount point %s)\n"
07098b81a4 1097) *nongit_ok = 1;
07098b81a4 1098) break;

transport-helper.c
3b3357626e 1029) static int has_attribute(const char *attrs, const char *attr)

Commits introducing uncovered code:
Erin Dahlgren      07098b81a: Simplify handling of setup_git_directory_gently() failure cases.
Nguyễn Thái Ngọc Duy      00a6d4d1d: worktree: allow to (re)move worktrees with uninitialized submodules
Nguyễn Thái Ngọc Duy      3b3357626: style: the opening '{' of a function is in a separate line
Olga Telezhnaya      1867ce6cb: ref-filter: add objectsize:disk option
Olga Telezhnaya      33311fa1a: ref-filter: add deltabase option

^ permalink raw reply	[relevance 1%]

* [PATCH 01/11] grep: use grep_opt->repo instead of explict repo argument
  @ 2019-01-24  8:29 10% ` Nguyễn Thái Ngọc Duy
  0 siblings, 0 replies; 200+ results
From: Nguyễn Thái Ngọc Duy @ 2019-01-24  8:29 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy,
	Stefan Beller

This command is probably the first one that operates on a repository
other than the_repository, in f9ee2fcdfa (grep: recurse in-process
using 'struct repository' - 2017-08-02). An explicit 'struct
repository *' was added in that commit to pass around the repository
that we're supposed to grep from.

Since 38bbc2ea39 (grep.c: remove implicit dependency on the_index -
2018-09-21). 'struct grep_opt *' carries in itself a repository
parameter for grepping. We should now be able to reuse grep_opt to
hold the submodule repo instead of a separate argument, which is just
room for mistakes.

While at there, use the right reference instead of the_repository and
the_index in this code. I was a bit careless in my attempt to kick
the_repository / the_index out of library code. It's normally safe to
just stick the_repository / the_index in bultin/ code, but it's not
the case for grep.

Reviewed-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/grep.c | 41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index bad9c0a3d5..0cc671f7d6 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -393,18 +393,20 @@ static void run_pager(struct grep_opt *opt, const char *prefix)
 		exit(status);
 }
 
-static int grep_cache(struct grep_opt *opt, struct repository *repo,
+static int grep_cache(struct grep_opt *opt,
 		      const struct pathspec *pathspec, int cached);
 static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 		     struct tree_desc *tree, struct strbuf *base, int tn_len,
-		     int check_attr, struct repository *repo);
+		     int check_attr);
 
-static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
+static int grep_submodule(struct grep_opt *opt,
 			  const struct pathspec *pathspec,
 			  const struct object_id *oid,
 			  const char *filename, const char *path)
 {
+	struct repository *superproject = opt->repo;
 	struct repository submodule;
+	struct grep_opt subopt;
 	int hit;
 
 	/*
@@ -440,6 +442,9 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 	add_to_alternates_memory(submodule.objects->odb->path);
 	grep_read_unlock();
 
+	memcpy(&subopt, opt, sizeof(subopt));
+	subopt.repo = &submodule;
+
 	if (oid) {
 		struct object *object;
 		struct tree_desc tree;
@@ -461,21 +466,22 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 		strbuf_addch(&base, '/');
 
 		init_tree_desc(&tree, data, size);
-		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-				object->type == OBJ_COMMIT, &submodule);
+		hit = grep_tree(&subopt, pathspec, &tree, &base, base.len,
+				object->type == OBJ_COMMIT);
 		strbuf_release(&base);
 		free(data);
 	} else {
-		hit = grep_cache(opt, &submodule, pathspec, 1);
+		hit = grep_cache(&subopt, pathspec, 1);
 	}
 
 	repo_clear(&submodule);
 	return hit;
 }
 
-static int grep_cache(struct grep_opt *opt, struct repository *repo,
+static int grep_cache(struct grep_opt *opt,
 		      const struct pathspec *pathspec, int cached)
 {
+	struct repository *repo = opt->repo;
 	int hit = 0;
 	int nr;
 	struct strbuf name = STRBUF_INIT;
@@ -513,7 +519,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
 			}
 		} else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
 			   submodule_path_match(repo->index, pathspec, name.buf, NULL)) {
-			hit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name);
+			hit |= grep_submodule(opt, pathspec, NULL, ce->name, ce->name);
 		} else {
 			continue;
 		}
@@ -535,8 +541,9 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
 
 static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 		     struct tree_desc *tree, struct strbuf *base, int tn_len,
-		     int check_attr, struct repository *repo)
+		     int check_attr)
 {
+	struct repository *repo = opt->repo;
 	int hit = 0;
 	enum interesting match = entry_not_interesting;
 	struct name_entry entry;
@@ -582,10 +589,10 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 			strbuf_addch(base, '/');
 			init_tree_desc(&sub, data, size);
 			hit |= grep_tree(opt, pathspec, &sub, base, tn_len,
-					 check_attr, repo);
+					 check_attr);
 			free(data);
 		} else if (recurse_submodules && S_ISGITLINK(entry.mode)) {
-			hit |= grep_submodule(opt, repo, pathspec, entry.oid,
+			hit |= grep_submodule(opt, pathspec, entry.oid,
 					      base->buf, base->buf + tn_len);
 		}
 
@@ -627,7 +634,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
 		}
 		init_tree_desc(&tree, data, size);
 		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-				obj->type == OBJ_COMMIT, the_repository);
+				obj->type == OBJ_COMMIT);
 		strbuf_release(&base);
 		free(data);
 		return hit;
@@ -644,12 +651,12 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
 
 	for (i = 0; i < nr; i++) {
 		struct object *real_obj;
-		real_obj = deref_tag(the_repository, list->objects[i].item,
+		real_obj = deref_tag(opt->repo, list->objects[i].item,
 				     NULL, 0);
 
 		/* load the gitmodules file for this rev */
 		if (recurse_submodules) {
-			submodule_free(the_repository);
+			submodule_free(opt->repo);
 			gitmodules_config_oid(&real_obj->oid);
 		}
 		if (grep_object(opt, pathspec, real_obj, list->objects[i].name,
@@ -674,9 +681,9 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
 	if (exc_std)
 		setup_standard_excludes(&dir);
 
-	fill_directory(&dir, &the_index, pathspec);
+	fill_directory(&dir, opt->repo->index, pathspec);
 	for (i = 0; i < dir.nr; i++) {
-		if (!dir_path_match(&the_index, dir.entries[i], pathspec, 0, NULL))
+		if (!dir_path_match(opt->repo->index, dir.entries[i], pathspec, 0, NULL))
 			continue;
 		hit |= grep_file(opt, dir.entries[i]->name);
 		if (hit && opt->status_only)
@@ -1117,7 +1124,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 		if (!cached)
 			setup_work_tree();
 
-		hit = grep_cache(&opt, the_repository, &pathspec, cached);
+		hit = grep_cache(&opt, &pathspec, cached);
 	} else {
 		if (cached)
 			die(_("both --cached and trees are given"));
-- 
2.20.1.560.g70ca8b83ee


^ permalink raw reply related	[relevance 10%]

* Git Test Coverage Report (Sat Jan 19)
@ 2019-01-20  1:07  1% Derrick Stolee
    0 siblings, 1 reply; 200+ results
From: Derrick Stolee @ 2019-01-20  1:07 UTC (permalink / raw)
  To: git@vger.kernel.org

Here is today's test coverage report.

Also, there has been some feedback that it can be hard to manually match 
up uncovered lines with names at the bottom of the summary. The 
suggestion was to auto-generate an HTML report that could be posted to a 
public page and referenced in this mail for those who prefer that. Any 
suggestions for how that should look before we start building it?

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=307

---

pu: 32ea0d952e6add9269432e6e2b31fd552e5478c0
jch: bc1fa105c1c1d5870a7e2800526f0a7ebf17d064
next: aa96b0ce6b0fa4fa4cc6870f1a3aff3878967bfa
master: 16a465bc018d09e9d7bbbdc5f40a7fb99c21f8ef
master@{1}: 77556354bb7ac50450e3b28999e3576969869068

Uncovered code in 'pu' not in 'jch'
--------------------------------------

bisect.c
4f6d26b167  661) mark_edges_uninteresting(revs, NULL, 0);

blame.c
e1ff0a32e4  191) repo_read_index(r);
e1ff0a32e4  273) repo_read_index(r);
07d04b919e  482)     ent->s_lno + ent->num_lines == next->s_lno &&
07d04b919e  483)     ent->ignored == next->ignored) {
07d04b919e  735) split[0].ignored = split[1].ignored = split[2].ignored 
= e->ignored;
e7973c8519  859) struct blame_entry *samep = NULL, *diffp = NULL, 
*ignoredp = NULL;
07d04b919e  873) n->ignored = e->ignored;
07d04b919e  928) n->ignored = e->ignored;
e7973c8519  938) if (ignore_diffs) {
e7973c8519  940) blame_origin_decref(e->suspect);
e7973c8519  941) e->suspect = blame_origin_incref(parent);
e7973c8519  942) e->s_lno += offset;
07d04b919e  943) e->ignored = 1;
e7973c8519  944) e->next = ignoredp;
e7973c8519  945) ignoredp = e;
e7973c8519  947) e->next = diffp;
e7973c8519  948) diffp = e;
e7973c8519  952) if (ignoredp) {
e7973c8519  953) **dstq = reverse_blame(ignoredp, **dstq);
e7973c8519  954) *dstq = &ignoredp->next;
e7973c8519 1001) d.ignore_diffs = ignore_diffs;
e7973c8519 1013) blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, 
INT_MAX, parent, 0);
e7973c8519 1518) pass_blame_to_parent(sb, origin, porigin, 0);
e7973c8519 1526) if (oidset_contains(&sb->ignore_list, 
&commit->object.oid)) {
e7973c8519 1527) for (i = 0, sg = first_scapegoat(revs, commit, 
sb->reverse);
e7973c8519 1528)      i < num_sg && sg;
e7973c8519 1529)      sg = sg->next, i++) {
e7973c8519 1530) struct blame_origin *porigin = sg_origin[i];
e7973c8519 1532) if (!porigin)
e7973c8519 1533) continue;
e7973c8519 1534) pass_blame_to_parent(sb, origin, porigin, 1);
e7973c8519 1535) if (!origin->suspects)
e7973c8519 1536) goto finish;

builtin/am.c
1d18d7581c  515) finish_copy_notes_for_rewrite(the_repository, c, msg);
150fe065f7 1765)     !repo_index_has_changes(the_repository, NULL, NULL)) {
150fe065f7 1819) if (!repo_index_has_changes(the_repository, NULL, NULL)) {

builtin/blame.c
07d04b919e builtin/blame.c    484) if (mark_ignored_lines && ent->ignored) {
07d04b919e builtin/blame.c    485) length--;
07d04b919e builtin/blame.c    486) putchar('*');
e7973c8519 builtin/blame.c    704) if (!strcmp(var, "blame.ignorerevsfile"))
e7973c8519 builtin/blame.c    705) return 
git_config_pathname(&ignore_revs_file, var, value);
07d04b919e builtin/blame.c    706) if (!strcmp(var, 
"blame.markignoredlines")) {
07d04b919e builtin/blame.c    707) mark_ignored_lines = 
git_config_bool(var, value);
07d04b919e builtin/blame.c    708) return 0;
e7973c8519 builtin/blame.c    789) static void build_ignorelist(struct 
blame_scoreboard *sb,
e7973c8519 builtin/blame.c    795) oidset_init(&sb->ignore_list, 0);
e7973c8519 builtin/blame.c    796) if (ignore_revs_file)
e7973c8519 builtin/blame.c    797) oidset_parse_file(&sb->ignore_list, 
ignore_revs_file);
e7973c8519 builtin/blame.c    798) for_each_string_list_item(i, 
ignore_rev_list) {
e7973c8519 builtin/blame.c    799) if (get_oid_committish(i->string, &oid))
e7973c8519 builtin/blame.c    800) die(_("Can't find revision '%s' to 
ignore"), i->string);
e7973c8519 builtin/blame.c    801) oidset_insert(&sb->ignore_list, &oid);
e7973c8519 builtin/blame.c    803) }
acdd37769d builtin/blame.c    961) blame_date_width = sizeof("Thu Oct 19 
16:00");
acdd37769d builtin/blame.c    962) break;
e7973c8519 builtin/blame.c   1033) build_ignorelist(&sb, &ignore_rev_list);
e7973c8519 builtin/blame.c   1034) string_list_clear(&ignore_rev_list, 0);
4478671442 builtin/blame.c   1048) the_repository->index))

builtin/checkout.c
0d6caa2d08 builtin/checkout.c  751) init_merge_options(&o, the_repository);

builtin/commit.c
1d18d7581c builtin/commit.c 1689) commit_post_rewrite(the_repository, 
current_head, &oid);

builtin/config.c
a12c1ff3a5 builtin/config.c       85) die(_("only one config file at a 
time"));
a12c1ff3a5 builtin/config.c       88) die(_("--local can only be used 
inside a git repository"));
a12c1ff3a5 builtin/config.c       91) die(_("--blob can only be used 
inside a git repository"));
a12c1ff3a5 builtin/config.c       95) given_config_source.file = NULL;
a12c1ff3a5 builtin/config.c       96) given_config_source.use_stdin = 1;
a12c1ff3a5 builtin/config.c      110) die(_("$HOME not set"));
a12c1ff3a5 builtin/config.c      114) given_config_source.file = xdg_config;
a12c1ff3a5 builtin/config.c      115) free(user_config);
a12c1ff3a5 builtin/config.c      122) given_config_source.file = 
git_etc_gitconfig();
a12c1ff3a5 builtin/config.c      126) given_config_source.file = 
get_worktree_config(the_repository);
a12c1ff3a5 builtin/config.c      127) if (!given_config_source.file)
a12c1ff3a5 builtin/config.c      128) die(_("--worktree cannot be used 
with multiple "
6f11fd5edb builtin/config.c      185) static int option_move_cb(const 
struct option *opt,
6f11fd5edb builtin/config.c      188) BUG_ON_OPT_NEG(unset);
6f11fd5edb builtin/config.c      189) BUG_ON_OPT_ARG(arg);
6f11fd5edb builtin/config.c      191) set_config_source_file();
6f11fd5edb builtin/config.c      192) memcpy(&move_source, 
&given_config_source, sizeof(move_source));
6f11fd5edb builtin/config.c      194) memset(&given_config_source, 0, 
sizeof(given_config_source));
6f11fd5edb builtin/config.c      195) use_global_config = 0;
6f11fd5edb builtin/config.c      196) use_system_config = 0;
6f11fd5edb builtin/config.c      197) use_local_config = 0;
6f11fd5edb builtin/config.c      198) use_worktree_config = 0;
6f11fd5edb builtin/config.c      200) actions = opt->defval;
6f11fd5edb builtin/config.c      201) return 0;
6f11fd5edb builtin/config.c      471) static int 
collect_move_config(const char *key, const char *value, void *cb)
6f11fd5edb builtin/config.c      473) struct move_config_cb *data = cb;
6f11fd5edb builtin/config.c      475) switch (actions) {
6f11fd5edb builtin/config.c      477) if (strcasecmp(data->key, key))
6f11fd5edb builtin/config.c      478) return 0;
6f11fd5edb builtin/config.c      479) break;
6f11fd5edb builtin/config.c      481) if (regexec(&data->key_re, key, 0, 
NULL, 0))
6f11fd5edb builtin/config.c      482) return 0;
6f11fd5edb builtin/config.c      483) break;
6f11fd5edb builtin/config.c      485) if (wildmatch(data->key, key, 
WM_CASEFOLD))
6f11fd5edb builtin/config.c      486) return 0;
6f11fd5edb builtin/config.c      487) break;
6f11fd5edb builtin/config.c      492) string_list_append(&data->keys, 
key)->util = xstrdup(value);
6f11fd5edb builtin/config.c      493) return 0;
6f11fd5edb builtin/config.c      496) static int move_config(const char 
*key)
6f11fd5edb builtin/config.c      499) int i, ret = 0;
6f11fd5edb builtin/config.c      501) config_options.respect_includes = 0;
6f11fd5edb builtin/config.c      502) if (!move_source.file && 
!move_source.use_stdin && !move_source.blob)
6f11fd5edb builtin/config.c      503) die(_("unknown config source"));
6f11fd5edb builtin/config.c      505) string_list_init(&cb.keys, 1);
6f11fd5edb builtin/config.c      506) cb.key = key;
6f11fd5edb builtin/config.c      507) if (actions == ACTION_MOVE_REGEXP &&
6f11fd5edb builtin/config.c      508) regcomp(&cb.key_re, key, 
REG_EXTENDED | REG_ICASE))
6f11fd5edb builtin/config.c      509) die(_("invalid key pattern: %s"), 
key);
6f11fd5edb builtin/config.c      511) 
config_with_options(collect_move_config, &cb,
6f11fd5edb builtin/config.c      514) for (i = 0; i < cb.keys.nr && 
!ret; i++) {
6f11fd5edb builtin/config.c      515) const char *key = 
cb.keys.items[i].string;
6f11fd5edb builtin/config.c      516) const char *value = 
cb.keys.items[i].util;
6f11fd5edb builtin/config.c      517) const char *dest = 
given_config_source.file;
6f11fd5edb builtin/config.c      519) ret = 
git_config_set_multivar_in_file_gently(
6f11fd5edb builtin/config.c      527) if (!ret && move_source.file) {
6f11fd5edb builtin/config.c      528) for (i = 0; i < cb.keys.nr; i++) {
6f11fd5edb builtin/config.c      529) const char *key = 
cb.keys.items[i].string;
6f11fd5edb builtin/config.c      530) const char *src = move_source.file;
6f11fd5edb builtin/config.c      532) 
git_config_set_multivar_in_file_gently(
6f11fd5edb builtin/config.c      537) string_list_clear(&cb.keys, 1);
6f11fd5edb builtin/config.c      538) if (actions == ACTION_MOVE_REGEXP)
6f11fd5edb builtin/config.c      539) regfree(&cb.key_re);
6f11fd5edb builtin/config.c      540) return ret;
6f11fd5edb builtin/config.c      979) else if (actions == ACTION_MOVE ||
6f11fd5edb builtin/config.c      980)  actions == ACTION_MOVE_REGEXP ||
6f11fd5edb builtin/config.c      981)  actions == ACTION_MOVE_GLOB) {
6f11fd5edb builtin/config.c      982) check_write();
6f11fd5edb builtin/config.c      983) check_argc(argc, 1, 1);
6f11fd5edb builtin/config.c      984) return move_config(argv[0]);

builtin/describe.c
1b0d968b34 builtin/describe.c 638) 
repo_update_index_if_able(the_repository, &index_lock);

builtin/diff-tree.c
e1ff0a32e4 builtin/diff-tree.c 169) repo_read_index(the_repository);

builtin/grep.c
dba093ddc0 builtin/grep.c  403) static int grep_submodule(struct 
grep_opt *opt,
dba093ddc0 builtin/grep.c  409) struct repository *superproject = opt->repo;
dba093ddc0 builtin/grep.c  448) memcpy(&subopt, opt, sizeof(subopt));
b6b4172bfb builtin/grep.c  449) subopt.repo = &subrepo;
dba093ddc0 builtin/grep.c  472) hit = grep_tree(&subopt, pathspec, 
&tree, &base, base.len,
dba093ddc0 builtin/grep.c  473) object->type == OBJ_COMMIT);
dba093ddc0 builtin/grep.c  477) hit = grep_cache(&subopt, pathspec, 1);
dba093ddc0 builtin/grep.c  484) static int grep_cache(struct grep_opt *opt,
dba093ddc0 builtin/grep.c  487) struct repository *repo = opt->repo;
dba093ddc0 builtin/grep.c  525) hit |= grep_submodule(opt, pathspec, 
NULL, ce->name, ce->name);
dba093ddc0 builtin/grep.c  549) struct repository *repo = opt->repo;
b6b4172bfb builtin/grep.c  599) hit |= grep_submodule(opt, pathspec, 
&entry.oid,
dba093ddc0 builtin/grep.c  641) obj->type == OBJ_COMMIT);
dba093ddc0 builtin/grep.c  658) real_obj = deref_tag(opt->repo, 
list->objects[i].item,
dba093ddc0 builtin/grep.c  663) submodule_free(opt->repo);
dba093ddc0 builtin/grep.c  688) fill_directory(&dir, opt->repo->index, 
pathspec);
dba093ddc0 builtin/grep.c  690) if (!dir_path_match(opt->repo->index, 
dir.entries[i], pathspec, 0, NULL))
3a7a698e93 builtin/grep.c 1028) if (get_oid_with_context(the_repository, 
arg,
dba093ddc0 builtin/grep.c 1132) hit = grep_cache(&opt, &pathspec, cached);

builtin/log.c
3a7a698e93 builtin/log.c  513) if (get_oid_with_context(the_repository, 
obj_name,

builtin/merge-tree.c
4478671442 builtin/merge-tree.c  80) return 
merge_blobs(the_repository->index, path,

builtin/merge.c
08339886b9 builtin/merge.c  120) static enum parse_opt_result 
option_read_message(struct parse_opt_ctx_t *ctx,
9b4ae5190a builtin/merge.c  128) BUG_ON_OPT_ARG(arg_not_used);

builtin/notes.c
1d18d7581c builtin/notes.c  333) commit_notes(the_repository, t, msg);
1d18d7581c builtin/notes.c  336) 
finish_copy_notes_for_rewrite(the_repository, c, msg);
1d18d7581c builtin/notes.c  472) commit_notes(the_repository, t,
1d18d7581c builtin/notes.c  478) commit_notes(the_repository, t,
1d18d7581c builtin/notes.c  557) commit_notes(the_repository, t,
1d18d7581c builtin/notes.c  642) commit_notes(the_repository, t, logmsg);
1d18d7581c builtin/notes.c  943) commit_notes(the_repository, t,
1d18d7581c builtin/notes.c  972) commit_notes(the_repository, t,

builtin/pack-objects.c
3d036eb0d2 builtin/pack-objects.c 2716) sparse = git_config_bool(k, v);
3d036eb0d2 builtin/pack-objects.c 2717) return 0;

builtin/pack-redundant.c
a338d10395 builtin/pack-redundant.c 339) static int 
cmp_remaining_objects(const void *a, const void *b)
e4e2c2884e builtin/pack-redundant.c 341) struct pack_list *pl_a = 
*((struct pack_list **)a);
e4e2c2884e builtin/pack-redundant.c 342) struct pack_list *pl_b = 
*((struct pack_list **)b);
a338d10395 builtin/pack-redundant.c 344) if 
(pl_a->remaining_objects->size == pl_b->remaining_objects->size) {
a338d10395 builtin/pack-redundant.c 346) if (pl_a->all_objects_size == 
pl_b->all_objects_size)
a338d10395 builtin/pack-redundant.c 347) return 0;
a338d10395 builtin/pack-redundant.c 348) else if (pl_a->all_objects_size 
< pl_b->all_objects_size)
a338d10395 builtin/pack-redundant.c 349) return 1;
a338d10395 builtin/pack-redundant.c 351) return -1;
a338d10395 builtin/pack-redundant.c 352) } else if 
(pl_a->remaining_objects->size < pl_b->remaining_objects->size) {
e4e2c2884e builtin/pack-redundant.c 354) return 1;
e4e2c2884e builtin/pack-redundant.c 356) return -1;
e4e2c2884e builtin/pack-redundant.c 361) static void 
sort_pack_list(struct pack_list **pl)
e4e2c2884e builtin/pack-redundant.c 365) size_t n = pack_list_size(*pl);
e4e2c2884e builtin/pack-redundant.c 367) if (n < 2)
e4e2c2884e builtin/pack-redundant.c 368) return;
e4e2c2884e builtin/pack-redundant.c 371) ary = xcalloc(n, sizeof(struct 
pack_list *));
e4e2c2884e builtin/pack-redundant.c 372) for (n = 0, p = *pl; p; p = 
p->next)
e4e2c2884e builtin/pack-redundant.c 373) ary[n++] = p;
a338d10395 builtin/pack-redundant.c 375) QSORT(ary, n, 
cmp_remaining_objects);
e4e2c2884e builtin/pack-redundant.c 378) for (i = 0; i < n - 1; i++)
e4e2c2884e builtin/pack-redundant.c 379) ary[i]->next = ary[i + 1];
e4e2c2884e builtin/pack-redundant.c 380) ary[n - 1]->next = NULL;
e4e2c2884e builtin/pack-redundant.c 381) *pl = ary[0];
e4e2c2884e builtin/pack-redundant.c 383) free(ary);
e4e2c2884e builtin/pack-redundant.c 389) struct pack_list *pl, *unique = 
NULL, *non_unique = NULL;
cb7e0336fc builtin/pack-redundant.c 404) 
llist_sorted_difference_inplace(missing, pl->remaining_objects);
e4e2c2884e builtin/pack-redundant.c 408) *min = unique;
e4e2c2884e builtin/pack-redundant.c 416) unique_pack_objects = 
llist_copy(all_objects);
e4e2c2884e builtin/pack-redundant.c 417) 
llist_sorted_difference_inplace(unique_pack_objects, missing);
e4e2c2884e builtin/pack-redundant.c 420) pl = non_unique;
cb7e0336fc builtin/pack-redundant.c 422) 
llist_sorted_difference_inplace(pl->remaining_objects, unique_pack_objects);
e4e2c2884e builtin/pack-redundant.c 426) while (non_unique) {
e4e2c2884e builtin/pack-redundant.c 428) sort_pack_list(&non_unique);
cb7e0336fc builtin/pack-redundant.c 429) if 
(non_unique->remaining_objects->size == 0)
e4e2c2884e builtin/pack-redundant.c 430) break;
e4e2c2884e builtin/pack-redundant.c 432) pack_list_insert(min, non_unique);
cb7e0336fc builtin/pack-redundant.c 434) for (pl = non_unique->next; pl 
&& pl->remaining_objects->size > 0;  pl = pl->next)
cb7e0336fc builtin/pack-redundant.c 435) 
llist_sorted_difference_inplace(pl->remaining_objects, 
non_unique->remaining_objects);
e4e2c2884e builtin/pack-redundant.c 437) non_unique = non_unique->next;
cb7e0336fc builtin/pack-redundant.c 450) l = pl->remaining_objects->front;
cb7e0336fc builtin/pack-redundant.c 461) 
llist_sorted_difference_inplace(all_objects, pl->remaining_objects);
cb7e0336fc builtin/pack-redundant.c 490) 
llist_sorted_difference_inplace(all_objects, alt->remaining_objects);
cb7e0336fc builtin/pack-redundant.c 505) llist_init(&l.remaining_objects);
cb7e0336fc builtin/pack-redundant.c 514) 
llist_insert_back(l.remaining_objects, (const struct object_id *)(base + 
off));
a338d10395 builtin/pack-redundant.c 517) l.all_objects_size = 
l.remaining_objects->size;
cb7e0336fc builtin/pack-redundant.c 519) l.unique_objects = 
llist_copy(l.remaining_objects);
cb7e0336fc builtin/pack-redundant.c 615) 
llist_sorted_difference_inplace(pl->remaining_objects, ignore);

builtin/range-diff.c
26c50430dc 78) FREE_AND_NULL(options);

builtin/rebase--interactive.c
e5b1c9d929 builtin/rebase--interactive.c   17) static int 
edit_todo_file(unsigned flags)
e5b1c9d929 builtin/rebase--interactive.c   19) const char *todo_file = 
rebase_path_todo();
e5b1c9d929 builtin/rebase--interactive.c   20) struct todo_list 
todo_list = TODO_LIST_INIT,
e5b1c9d929 builtin/rebase--interactive.c   21) new_todo = TODO_LIST_INIT;
e5b1c9d929 builtin/rebase--interactive.c   23) if 
(strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
e5b1c9d929 builtin/rebase--interactive.c   24) return 
error_errno(_("could not read '%s'."), todo_file);
e5b1c9d929 builtin/rebase--interactive.c   26) 
strbuf_stripspace(&todo_list.buf, 1);
e5b1c9d929 builtin/rebase--interactive.c   27) if 
(!edit_todo_list(the_repository, &todo_list,
e5b1c9d929 builtin/rebase--interactive.c   28) &new_todo, NULL, NULL, 
flags) &&
e5b1c9d929 builtin/rebase--interactive.c   29) 
todo_list_write_to_file(the_repository, &new_todo, todo_file, NULL, NULL,
e5b1c9d929 builtin/rebase--interactive.c   31) return 
error_errno(_("could not write '%s'"), todo_file);
e5b1c9d929 builtin/rebase--interactive.c   33) 
todo_list_release(&todo_list);
e5b1c9d929 builtin/rebase--interactive.c   34) todo_list_release(&new_todo);
e5b1c9d929 builtin/rebase--interactive.c   36) return 0;
4d55dfd767 builtin/rebase--interactive.c   39) static int 
transform_todo_file(unsigned flags)
4d55dfd767 builtin/rebase--interactive.c   41) const char *todo_file = 
rebase_path_todo();
4d55dfd767 builtin/rebase--interactive.c   42) struct todo_list 
todo_list = TODO_LIST_INIT;
4d55dfd767 builtin/rebase--interactive.c   45) if 
(strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
4d55dfd767 builtin/rebase--interactive.c   46) return 
error_errno(_("could not read '%s'."), todo_file);
4d55dfd767 builtin/rebase--interactive.c   48) if 
(todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
4d55dfd767 builtin/rebase--interactive.c   50) 
todo_list_release(&todo_list);
4d55dfd767 builtin/rebase--interactive.c   51) return error(_("unusable 
todo list: '%s'"), todo_file);
4d55dfd767 builtin/rebase--interactive.c   54) res = 
todo_list_write_to_file(the_repository, &todo_list, todo_file,
4d55dfd767 builtin/rebase--interactive.c   56) 
todo_list_release(&todo_list);
4d55dfd767 builtin/rebase--interactive.c   58) if (res)
4d55dfd767 builtin/rebase--interactive.c   59) return 
error_errno(_("could not write '%s'."), todo_file);
4d55dfd767 builtin/rebase--interactive.c   60) return 0;
0566a4f68e builtin/rebase--interactive.c  121) struct todo_list 
todo_list = TODO_LIST_INIT;
0566a4f68e builtin/rebase--interactive.c  147) ret = 
sequencer_make_script(the_repository, &todo_list.buf,
c1c074e0cc builtin/rebase--interactive.c  155) if 
(todo_list_parse_insn_buffer(the_repository, todo_list.buf.buf,
c1c074e0cc builtin/rebase--interactive.c  159) ret = 
complete_action(the_repository, opts, flags, shortrevisions, onto_name,
0566a4f68e builtin/rebase--interactive.c  165) 
todo_list_release(&todo_list);
8414c890aa builtin/rebase--interactive.c  269) if (cmd && *cmd) {
8414c890aa builtin/rebase--interactive.c  270) 
string_list_split(&commands, cmd, '\n', -1);
8414c890aa builtin/rebase--interactive.c  271) if 
(strlen(commands.items[commands.nr - 1].string) == 0)
8414c890aa builtin/rebase--interactive.c  272) --commands.nr;
e5b1c9d929 builtin/rebase--interactive.c  294) ret = edit_todo_file(flags);
4d55dfd767 builtin/rebase--interactive.c  307) ret = 
transform_todo_file(flags);
c27b32f0ec builtin/rebase--interactive.c  310) ret = 
check_todo_list_from_file(the_repository);
febebd99b6 builtin/rebase--interactive.c  313) ret = 
rearrange_squash_in_todo_file(the_repository);
8414c890aa builtin/rebase--interactive.c  316) ret = 
sequencer_add_exec_commands(the_repository, &commands);

builtin/rebase.c
b6b4172bfb  423) if (repo_read_index_unmerged(the_repository) < 0) {
e1ff0a32e4 1236) if (repo_read_index(the_repository) < 0)
1b0d968b34 1241) repo_update_index_if_able(the_repository, &lock_file);
e1ff0a32e4 1593) if (repo_read_index(the_repository) < 0)
1b0d968b34 1603) repo_update_index_if_able(the_repository, &lock_file);
e1ff0a32e4 1648) repo_read_index(the_repository) < 0)

builtin/replace.c
4478671442 builtin/replace.c 298) if (index_fd(the_repository->index, 
oid, fd, &st, type, NULL, flags) < 0)

builtin/stash.c
f6bbd78127 builtin/stash--helper.c  117) static void 
free_stash_info(struct stash_info *info)
f6bbd78127 builtin/stash--helper.c  119) strbuf_release(&info->revision);
f6bbd78127 builtin/stash--helper.c  120) }
f6bbd78127 builtin/stash--helper.c  122) static void 
assert_stash_like(struct stash_info *info, const char *revision)
f6bbd78127 builtin/stash--helper.c  124) if (get_oidf(&info->b_commit, 
"%s^1", revision) ||
f6bbd78127 builtin/stash--helper.c  125) get_oidf(&info->w_tree, "%s:", 
revision) ||
f6bbd78127 builtin/stash--helper.c  126) get_oidf(&info->b_tree, 
"%s^1:", revision) ||
f6bbd78127 builtin/stash--helper.c  127) get_oidf(&info->i_tree, 
"%s^2:", revision))
f6bbd78127 builtin/stash--helper.c  128) die(_("'%s' is not a stash-like 
commit"), revision);
f6bbd78127 builtin/stash--helper.c  129) }
f6bbd78127 builtin/stash--helper.c  131) static int 
get_stash_info(struct stash_info *info, int argc, const char **argv)
f6bbd78127 builtin/stash--helper.c  137) const char *commit = NULL;
f6bbd78127 builtin/stash--helper.c  139) struct strbuf symbolic = 
STRBUF_INIT;
f6bbd78127 builtin/stash--helper.c  141) if (argc > 1) {
f6bbd78127 builtin/stash--helper.c  143) struct strbuf refs_msg = 
STRBUF_INIT;
f6bbd78127 builtin/stash--helper.c  145) for (i = 0; i < argc; i++)
f6bbd78127 builtin/stash--helper.c  146) strbuf_addf(&refs_msg, " '%s'", 
argv[i]);
f6bbd78127 builtin/stash--helper.c  148) fprintf_ln(stderr, _("Too many 
revisions specified:%s"),
f6bbd78127 builtin/stash--helper.c  150) strbuf_release(&refs_msg);
f6bbd78127 builtin/stash--helper.c  152) return -1;
f6bbd78127 builtin/stash--helper.c  155) if (argc == 1)
f6bbd78127 builtin/stash--helper.c  156) commit = argv[0];
f6bbd78127 builtin/stash--helper.c  158) strbuf_init(&info->revision, 0);
f6bbd78127 builtin/stash--helper.c  159) if (!commit) {
f6bbd78127 builtin/stash--helper.c  160) if (!ref_exists(ref_stash)) {
f6bbd78127 builtin/stash--helper.c  161) free_stash_info(info);
f6bbd78127 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
f6bbd78127 builtin/stash--helper.c  163) return -1;
f6bbd78127 builtin/stash--helper.c  166) strbuf_addf(&info->revision, 
"%s@{0}", ref_stash);
f6bbd78127 builtin/stash--helper.c  167) } else if (strspn(commit, 
"0123456789") == strlen(commit)) {
f6bbd78127 builtin/stash--helper.c  168) strbuf_addf(&info->revision, 
"%s@{%s}", ref_stash, commit);
f6bbd78127 builtin/stash--helper.c  170) strbuf_addstr(&info->revision, 
commit);
f6bbd78127 builtin/stash--helper.c  173) revision = info->revision.buf;
f6bbd78127 builtin/stash--helper.c  175) if (get_oid(revision, 
&info->w_commit)) {
f6bbd78127 builtin/stash--helper.c  176) error(_("%s is not a valid 
reference"), revision);
f6bbd78127 builtin/stash--helper.c  177) free_stash_info(info);
f6bbd78127 builtin/stash--helper.c  178) return -1;
f6bbd78127 builtin/stash--helper.c  181) assert_stash_like(info, revision);
f6bbd78127 builtin/stash--helper.c  183) info->has_u = 
!get_oidf(&info->u_tree, "%s^3:", revision);
f6bbd78127 builtin/stash--helper.c  185) end_of_rev = 
strchrnul(revision, '@');
f6bbd78127 builtin/stash--helper.c  186) strbuf_add(&symbolic, revision, 
end_of_rev - revision);
f6bbd78127 builtin/stash--helper.c  188) ret = dwim_ref(symbolic.buf, 
symbolic.len, &dummy, &expanded_ref);
f6bbd78127 builtin/stash--helper.c  189) strbuf_release(&symbolic);
f6bbd78127 builtin/stash--helper.c  190) switch (ret) {
f6bbd78127 builtin/stash--helper.c  192) info->is_stash_ref = 0;
f6bbd78127 builtin/stash--helper.c  193) break;
f6bbd78127 builtin/stash--helper.c  195) info->is_stash_ref = 
!strcmp(expanded_ref, ref_stash);
f6bbd78127 builtin/stash--helper.c  196) break;
f6bbd78127 builtin/stash--helper.c  198) free_stash_info(info);
f6bbd78127 builtin/stash--helper.c  201) free(expanded_ref);
f6bbd78127 builtin/stash--helper.c  202) return !(ret == 0 || ret == 1);
cdca49bc4c builtin/stash--helper.c  205) static int do_clear_stash(void)
cdca49bc4c builtin/stash--helper.c  208) if (get_oid(ref_stash, &obj))
cdca49bc4c builtin/stash--helper.c  209) return 0;
cdca49bc4c builtin/stash--helper.c  211) return delete_ref(NULL, 
ref_stash, &obj, 0);
cdca49bc4c builtin/stash--helper.c  214) static int clear_stash(int 
argc, const char **argv, const char *prefix)
cdca49bc4c builtin/stash--helper.c  216) struct option options[] = {
cdca49bc4c builtin/stash--helper.c  220) argc = parse_options(argc, 
argv, prefix, options,
cdca49bc4c builtin/stash--helper.c  224) if (argc)
cdca49bc4c builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
cdca49bc4c builtin/stash--helper.c  228) return do_clear_stash();
f6bbd78127 builtin/stash--helper.c  231) static int reset_tree(struct 
object_id *i_tree, int update, int reset)
f6bbd78127 builtin/stash--helper.c  233) int nr_trees = 1;
f6bbd78127 builtin/stash--helper.c  237) struct lock_file lock_file = 
LOCK_INIT;
f6bbd78127 builtin/stash--helper.c  239) read_cache_preload(NULL);
f6bbd78127 builtin/stash--helper.c  240) if (refresh_cache(REFRESH_QUIET))
f6bbd78127 builtin/stash--helper.c  241) return -1;
f6bbd78127 builtin/stash--helper.c  243) hold_locked_index(&lock_file, 
LOCK_DIE_ON_ERROR);
f6bbd78127 builtin/stash--helper.c  245) memset(&opts, 0, sizeof(opts));
f6bbd78127 builtin/stash--helper.c  247) tree = parse_tree_indirect(i_tree);
f6bbd78127 builtin/stash--helper.c  248) if (parse_tree(tree))
f6bbd78127 builtin/stash--helper.c  249) return -1;
f6bbd78127 builtin/stash--helper.c  251) init_tree_desc(t, tree->buffer, 
tree->size);
f6bbd78127 builtin/stash--helper.c  253) opts.head_idx = 1;
f6bbd78127 builtin/stash--helper.c  254) opts.src_index = &the_index;
f6bbd78127 builtin/stash--helper.c  255) opts.dst_index = &the_index;
f6bbd78127 builtin/stash--helper.c  256) opts.merge = 1;
f6bbd78127 builtin/stash--helper.c  257) opts.reset = reset;
f6bbd78127 builtin/stash--helper.c  258) opts.update = update;
f6bbd78127 builtin/stash--helper.c  259) opts.fn = oneway_merge;
f6bbd78127 builtin/stash--helper.c  261) if (unpack_trees(nr_trees, t, 
&opts))
f6bbd78127 builtin/stash--helper.c  262) return -1;
f6bbd78127 builtin/stash--helper.c  264) if 
(write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
f6bbd78127 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
f6bbd78127 builtin/stash--helper.c  267) return 0;
f6bbd78127 builtin/stash--helper.c  270) static int 
diff_tree_binary(struct strbuf *out, struct object_id *w_commit)
f6bbd78127 builtin/stash--helper.c  272) struct child_process cp = 
CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  273) const char *w_commit_hex = 
oid_to_hex(w_commit);
f6bbd78127 builtin/stash--helper.c  279) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  280) argv_array_pushl(&cp.args, 
"diff-tree", "--binary", NULL);
f6bbd78127 builtin/stash--helper.c  281) argv_array_pushf(&cp.args, 
"%s^2^..%s^2", w_commit_hex, w_commit_hex);
f6bbd78127 builtin/stash--helper.c  283) return pipe_command(&cp, NULL, 
0, out, 0, NULL, 0);
f6bbd78127 builtin/stash--helper.c  286) static int apply_cached(struct 
strbuf *out)
f6bbd78127 builtin/stash--helper.c  288) struct child_process cp = 
CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  295) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  296) argv_array_pushl(&cp.args, 
"apply", "--cached", NULL);
f6bbd78127 builtin/stash--helper.c  297) return pipe_command(&cp, 
out->buf, out->len, NULL, 0, NULL, 0);
f6bbd78127 builtin/stash--helper.c  300) static int reset_head(void)
f6bbd78127 builtin/stash--helper.c  302) struct child_process cp = 
CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  308) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  309) argv_array_push(&cp.args, "reset");
f6bbd78127 builtin/stash--helper.c  311) return run_command(&cp);
1f5a011d90 builtin/stash--helper.c  314) static void 
add_diff_to_buf(struct diff_queue_struct *q,
1f5a011d90 builtin/stash--helper.c  320) for (i = 0; i < q->nr; i++) {
1f5a011d90 builtin/stash--helper.c  321) strbuf_addstr(data, 
q->queue[i]->one->path);
1f5a011d90 builtin/stash--helper.c  328) strbuf_addch(data, '\0');
1f5a011d90 builtin/stash--helper.c  330) }
f6bbd78127 builtin/stash--helper.c  332) static int 
get_newly_staged(struct strbuf *out, struct object_id *c_tree)
f6bbd78127 builtin/stash--helper.c  334) struct child_process cp = 
CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  335) const char *c_tree_hex = 
oid_to_hex(c_tree);
f6bbd78127 builtin/stash--helper.c  341) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  342) argv_array_pushl(&cp.args, 
"diff-index", "--cached", "--name-only",
f6bbd78127 builtin/stash--helper.c  344) argv_array_push(&cp.args, 
c_tree_hex);
f6bbd78127 builtin/stash--helper.c  345) return pipe_command(&cp, NULL, 
0, out, 0, NULL, 0);
f6bbd78127 builtin/stash--helper.c  348) static int update_index(struct 
strbuf *out)
f6bbd78127 builtin/stash--helper.c  350) struct child_process cp = 
CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  356) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  357) argv_array_pushl(&cp.args, 
"update-index", "--add", "--stdin", NULL);
f6bbd78127 builtin/stash--helper.c  358) return pipe_command(&cp, 
out->buf, out->len, NULL, 0, NULL, 0);
f6bbd78127 builtin/stash--helper.c  361) static int 
restore_untracked(struct object_id *u_tree)
f6bbd78127 builtin/stash--helper.c  364) struct child_process cp = 
CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  371) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  372) argv_array_push(&cp.args, 
"read-tree");
f6bbd78127 builtin/stash--helper.c  373) argv_array_push(&cp.args, 
oid_to_hex(u_tree));
f6bbd78127 builtin/stash--helper.c  374) argv_array_pushf(&cp.env_array, 
"GIT_INDEX_FILE=%s",
f6bbd78127 builtin/stash--helper.c  376) if (run_command(&cp)) {
f6bbd78127 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
f6bbd78127 builtin/stash--helper.c  378) return -1;
f6bbd78127 builtin/stash--helper.c  381) child_process_init(&cp);
f6bbd78127 builtin/stash--helper.c  382) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  383) argv_array_pushl(&cp.args, 
"checkout-index", "--all", NULL);
f6bbd78127 builtin/stash--helper.c  384) argv_array_pushf(&cp.env_array, 
"GIT_INDEX_FILE=%s",
f6bbd78127 builtin/stash--helper.c  387) res = run_command(&cp);
f6bbd78127 builtin/stash--helper.c  388) remove_path(stash_index_path.buf);
f6bbd78127 builtin/stash--helper.c  389) return res;
f6bbd78127 builtin/stash--helper.c  392) static int do_apply_stash(const 
char *prefix, struct stash_info *info,
f6bbd78127 builtin/stash--helper.c  396) int has_index = index;
f6bbd78127 builtin/stash--helper.c  403) read_cache_preload(NULL);
f6bbd78127 builtin/stash--helper.c  404) if (refresh_cache(REFRESH_QUIET))
f6bbd78127 builtin/stash--helper.c  405) return -1;
f6bbd78127 builtin/stash--helper.c  407) if 
(write_cache_as_tree(&c_tree, 0, NULL) || reset_tree(&c_tree, 0, 0))
f6bbd78127 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
f6bbd78127 builtin/stash--helper.c  410) if (index) {
f6bbd78127 builtin/stash--helper.c  411) if (oideq(&info->b_tree, 
&info->i_tree) ||
f6bbd78127 builtin/stash--helper.c  412)     oideq(&c_tree, 
&info->i_tree)) {
f6bbd78127 builtin/stash--helper.c  413) has_index = 0;
f6bbd78127 builtin/stash--helper.c  415) struct strbuf out = STRBUF_INIT;
f6bbd78127 builtin/stash--helper.c  417) if (diff_tree_binary(&out, 
&info->w_commit)) {
f6bbd78127 builtin/stash--helper.c  418) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  419) return error(_("could not 
generate diff %s^!."),
f6bbd78127 builtin/stash--helper.c  423) ret = apply_cached(&out);
f6bbd78127 builtin/stash--helper.c  424) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  425) if (ret)
f6bbd78127 builtin/stash--helper.c  426) return error(_("conflicts in 
index."
f6bbd78127 builtin/stash--helper.c  429) discard_cache();
f6bbd78127 builtin/stash--helper.c  430) read_cache();
f6bbd78127 builtin/stash--helper.c  431) if 
(write_cache_as_tree(&index_tree, 0, NULL))
f6bbd78127 builtin/stash--helper.c  432) return error(_("could not save 
index tree"));
f6bbd78127 builtin/stash--helper.c  434) reset_head();
f6bbd78127 builtin/stash--helper.c  438) if (info->has_u && 
restore_untracked(&info->u_tree))
f6bbd78127 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
b6b4172bfb builtin/stash.c          441) init_merge_options(&o, 
the_repository);
f6bbd78127 builtin/stash--helper.c  443) o.branch1 = "Updated upstream";
f6bbd78127 builtin/stash--helper.c  444) o.branch2 = "Stashed changes";
f6bbd78127 builtin/stash--helper.c  446) if (oideq(&info->b_tree, &c_tree))
f6bbd78127 builtin/stash--helper.c  447) o.branch1 = "Version stash was 
based on";
f6bbd78127 builtin/stash--helper.c  449) if (quiet)
f6bbd78127 builtin/stash--helper.c  450) o.verbosity = 0;
f6bbd78127 builtin/stash--helper.c  452) if (o.verbosity >= 3)
f6bbd78127 builtin/stash--helper.c  453) printf_ln(_("Merging %s with 
%s"), o.branch1, o.branch2);
f6bbd78127 builtin/stash--helper.c  455) bases[0] = &info->b_tree;
f6bbd78127 builtin/stash--helper.c  457) ret = 
merge_recursive_generic(&o, &c_tree, &info->w_tree, 1, bases,
f6bbd78127 builtin/stash--helper.c  459) if (ret) {
f6bbd78127 builtin/stash--helper.c  460) rerere(0);
f6bbd78127 builtin/stash--helper.c  462) if (index)
f6bbd78127 builtin/stash--helper.c  463) fprintf_ln(stderr, _("Index was 
not unstashed."));
f6bbd78127 builtin/stash--helper.c  465) return ret;
f6bbd78127 builtin/stash--helper.c  468) if (has_index) {
f6bbd78127 builtin/stash--helper.c  469) if (reset_tree(&index_tree, 0, 0))
f6bbd78127 builtin/stash--helper.c  470) return -1;
f6bbd78127 builtin/stash--helper.c  472) struct strbuf out = STRBUF_INIT;
f6bbd78127 builtin/stash--helper.c  474) if (get_newly_staged(&out, 
&c_tree)) {
f6bbd78127 builtin/stash--helper.c  475) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  476) return -1;
f6bbd78127 builtin/stash--helper.c  479) if (reset_tree(&c_tree, 0, 1)) {
f6bbd78127 builtin/stash--helper.c  480) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  481) return -1;
f6bbd78127 builtin/stash--helper.c  484) ret = update_index(&out);
f6bbd78127 builtin/stash--helper.c  485) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  486) if (ret)
f6bbd78127 builtin/stash--helper.c  487) return -1;
f6bbd78127 builtin/stash--helper.c  489) discard_cache();
f6bbd78127 builtin/stash--helper.c  492) if (quiet) {
f6bbd78127 builtin/stash--helper.c  493) if (refresh_cache(REFRESH_QUIET))
f6bbd78127 builtin/stash--helper.c  494) warning("could not refresh index");
f6bbd78127 builtin/stash--helper.c  496) struct child_process cp = 
CHILD_PROCESS_INIT;
f6bbd78127 builtin/stash--helper.c  503) cp.git_cmd = 1;
f6bbd78127 builtin/stash--helper.c  504) cp.dir = prefix;
f6bbd78127 builtin/stash--helper.c  505) argv_array_push(&cp.args, 
"status");
f6bbd78127 builtin/stash--helper.c  506) run_command(&cp);
f6bbd78127 builtin/stash--helper.c  509) return 0;
f6bbd78127 builtin/stash--helper.c  512) static int apply_stash(int 
argc, const char **argv, const char *prefix)
f6bbd78127 builtin/stash--helper.c  515) int quiet = 0;
f6bbd78127 builtin/stash--helper.c  516) int index = 0;
f6bbd78127 builtin/stash--helper.c  518) struct option options[] = {
f6bbd78127 builtin/stash--helper.c  525) argc = parse_options(argc, 
argv, prefix, options,
f6bbd78127 builtin/stash--helper.c  528) if (get_stash_info(&info, argc, 
argv))
f6bbd78127 builtin/stash--helper.c  529) return -1;
f6bbd78127 builtin/stash--helper.c  531) ret = do_apply_stash(prefix, 
&info, index, quiet);
f6bbd78127 builtin/stash--helper.c  532) free_stash_info(&info);
f6bbd78127 builtin/stash--helper.c  533) return ret;
cdca49bc4c builtin/stash--helper.c  536) static int do_drop_stash(const 
char *prefix, struct stash_info *info, int quiet)
cdca49bc4c builtin/stash--helper.c  539) struct child_process cp_reflog 
= CHILD_PROCESS_INIT;
cdca49bc4c builtin/stash--helper.c  540) struct child_process cp = 
CHILD_PROCESS_INIT;
cdca49bc4c builtin/stash--helper.c  547) cp_reflog.git_cmd = 1;
cdca49bc4c builtin/stash--helper.c  548) 
argv_array_pushl(&cp_reflog.args, "reflog", "delete", "--updateref",
cdca49bc4c builtin/stash--helper.c  550) 
argv_array_push(&cp_reflog.args, info->revision.buf);
cdca49bc4c builtin/stash--helper.c  551) ret = run_command(&cp_reflog);
cdca49bc4c builtin/stash--helper.c  552) if (!ret) {
cdca49bc4c builtin/stash--helper.c  553) if (!quiet)
cdca49bc4c builtin/stash--helper.c  554) printf_ln(_("Dropped %s (%s)"), 
info->revision.buf,
cdca49bc4c builtin/stash--helper.c  555) oid_to_hex(&info->w_commit));
cdca49bc4c builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
cdca49bc4c builtin/stash--helper.c  565) cp.git_cmd = 1;
cdca49bc4c builtin/stash--helper.c  567) cp.no_stdout = 1;
cdca49bc4c builtin/stash--helper.c  568) argv_array_pushl(&cp.args, 
"rev-parse", "--verify", "--quiet", NULL);
cdca49bc4c builtin/stash--helper.c  569) argv_array_pushf(&cp.args, 
"%s@{0}", ref_stash);
cdca49bc4c builtin/stash--helper.c  570) ret = run_command(&cp);
cdca49bc4c builtin/stash--helper.c  573) if (ret)
cdca49bc4c builtin/stash--helper.c  574) do_clear_stash();
cdca49bc4c builtin/stash--helper.c  576) return 0;
cdca49bc4c builtin/stash--helper.c  579) static void 
assert_stash_ref(struct stash_info *info)
cdca49bc4c builtin/stash--helper.c  581) if (!info->is_stash_ref) {
cdca49bc4c builtin/stash--helper.c  582) free_stash_info(info);
cdca49bc4c builtin/stash--helper.c  583) error(_("'%s' is not a stash 
reference"), info->revision.buf);
cdca49bc4c builtin/stash--helper.c  584) exit(128);
cdca49bc4c builtin/stash--helper.c  586) }
cdca49bc4c builtin/stash--helper.c  588) static int drop_stash(int argc, 
const char **argv, const char *prefix)
cdca49bc4c builtin/stash--helper.c  591) int quiet = 0;
cdca49bc4c builtin/stash--helper.c  593) struct option options[] = {
cdca49bc4c builtin/stash--helper.c  598) argc = parse_options(argc, 
argv, prefix, options,
cdca49bc4c builtin/stash--helper.c  601) if (get_stash_info(&info, argc, 
argv))
cdca49bc4c builtin/stash--helper.c  602) return -1;
cdca49bc4c builtin/stash--helper.c  604) assert_stash_ref(&info);
cdca49bc4c builtin/stash--helper.c  606) ret = do_drop_stash(prefix, 
&info, quiet);
cdca49bc4c builtin/stash--helper.c  607) free_stash_info(&info);
cdca49bc4c builtin/stash--helper.c  608) return ret;
e1d01876a4 builtin/stash--helper.c  611) static int pop_stash(int argc, 
const char **argv, const char *prefix)
e1d01876a4 builtin/stash--helper.c  614) int index = 0;
e1d01876a4 builtin/stash--helper.c  615) int quiet = 0;
e1d01876a4 builtin/stash--helper.c  617) struct option options[] = {
e1d01876a4 builtin/stash--helper.c  624) argc = parse_options(argc, 
argv, prefix, options,
e1d01876a4 builtin/stash--helper.c  627) if (get_stash_info(&info, argc, 
argv))
e1d01876a4 builtin/stash--helper.c  628) return -1;
e1d01876a4 builtin/stash--helper.c  630) assert_stash_ref(&info);
e1d01876a4 builtin/stash--helper.c  631) if ((ret = 
do_apply_stash(prefix, &info, index, quiet)))
e1d01876a4 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
e1d01876a4 builtin/stash--helper.c  635) ret = do_drop_stash(prefix, 
&info, quiet);
e1d01876a4 builtin/stash--helper.c  637) free_stash_info(&info);
e1d01876a4 builtin/stash--helper.c  638) return ret;
f596f3366c builtin/stash--helper.c  641) static int branch_stash(int 
argc, const char **argv, const char *prefix)
f596f3366c builtin/stash--helper.c  644) const char *branch = NULL;
f596f3366c builtin/stash--helper.c  646) struct child_process cp = 
CHILD_PROCESS_INIT;
f596f3366c builtin/stash--helper.c  647) struct option options[] = {
f596f3366c builtin/stash--helper.c  651) argc = parse_options(argc, 
argv, prefix, options,
f596f3366c builtin/stash--helper.c  654) if (!argc) {
f596f3366c builtin/stash--helper.c  655) fprintf_ln(stderr, _("No branch 
name specified"));
f596f3366c builtin/stash--helper.c  656) return -1;
f596f3366c builtin/stash--helper.c  659) branch = argv[0];
f596f3366c builtin/stash--helper.c  661) if (get_stash_info(&info, argc 
- 1, argv + 1))
f596f3366c builtin/stash--helper.c  662) return -1;
f596f3366c builtin/stash--helper.c  664) cp.git_cmd = 1;
f596f3366c builtin/stash--helper.c  665) argv_array_pushl(&cp.args, 
"checkout", "-b", NULL);
f596f3366c builtin/stash--helper.c  666) argv_array_push(&cp.args, branch);
f596f3366c builtin/stash--helper.c  667) argv_array_push(&cp.args, 
oid_to_hex(&info.b_commit));
f596f3366c builtin/stash--helper.c  668) ret = run_command(&cp);
f596f3366c builtin/stash--helper.c  669) if (!ret)
f596f3366c builtin/stash--helper.c  670) ret = do_apply_stash(prefix, 
&info, 1, 0);
f596f3366c builtin/stash--helper.c  671) if (!ret && info.is_stash_ref)
f596f3366c builtin/stash--helper.c  672) ret = do_drop_stash(prefix, 
&info, 0);
f596f3366c builtin/stash--helper.c  674) free_stash_info(&info);
f596f3366c builtin/stash--helper.c  676) return ret;
9b77b07ba4 builtin/stash--helper.c  679) static int list_stash(int argc, 
const char **argv, const char *prefix)
9b77b07ba4 builtin/stash--helper.c  681) struct child_process cp = 
CHILD_PROCESS_INIT;
9b77b07ba4 builtin/stash--helper.c  682) struct option options[] = {
9b77b07ba4 builtin/stash--helper.c  686) argc = parse_options(argc, 
argv, prefix, options,
9b77b07ba4 builtin/stash--helper.c  690) if (!ref_exists(ref_stash))
9b77b07ba4 builtin/stash--helper.c  691) return 0;
9b77b07ba4 builtin/stash--helper.c  693) cp.git_cmd = 1;
9b77b07ba4 builtin/stash--helper.c  694) argv_array_pushl(&cp.args, 
"log", "--format=%gd: %gs", "-g",
9b77b07ba4 builtin/stash--helper.c  696) argv_array_pushv(&cp.args, argv);
9b77b07ba4 builtin/stash--helper.c  697) argv_array_push(&cp.args, 
ref_stash);
9b77b07ba4 builtin/stash--helper.c  698) argv_array_push(&cp.args, "--");
9b77b07ba4 builtin/stash--helper.c  699) return run_command(&cp);
b4493f269e builtin/stash--helper.c  705) static int 
git_stash_config(const char *var, const char *value, void *cb)
b4493f269e builtin/stash--helper.c  707) if (!strcmp(var, 
"stash.showstat")) {
b4493f269e builtin/stash--helper.c  708) show_stat = 
git_config_bool(var, value);
b4493f269e builtin/stash--helper.c  709) return 0;
b4493f269e builtin/stash--helper.c  711) if (!strcmp(var, 
"stash.showpatch")) {
b4493f269e builtin/stash--helper.c  712) show_patch = 
git_config_bool(var, value);
b4493f269e builtin/stash--helper.c  713) return 0;
b4493f269e builtin/stash--helper.c  715) return git_default_config(var, 
value, cb);
b4493f269e builtin/stash--helper.c  718) static int show_stash(int argc, 
const char **argv, const char *prefix)
b4493f269e builtin/stash--helper.c  721) int opts = 0;
b4493f269e builtin/stash--helper.c  722) int ret = 0;
b4493f269e builtin/stash--helper.c  725) struct argv_array stash_args = 
ARGV_ARRAY_INIT;
b4493f269e builtin/stash--helper.c  726) struct option options[] = {
b4493f269e builtin/stash--helper.c  730) init_diff_ui_defaults();
b4493f269e builtin/stash--helper.c  731) git_config(git_diff_ui_config, 
NULL);
b4493f269e builtin/stash--helper.c  732) init_revisions(&rev, prefix);
b4493f269e builtin/stash--helper.c  734) for (i = 1; i < argc; i++) {
b4493f269e builtin/stash--helper.c  735) if (argv[i][0] != '-')
b4493f269e builtin/stash--helper.c  736) argv_array_push(&stash_args, 
argv[i]);
b4493f269e builtin/stash--helper.c  738) opts++;
b4493f269e builtin/stash--helper.c  741) ret = get_stash_info(&info, 
stash_args.argc, stash_args.argv);
b4493f269e builtin/stash--helper.c  742) argv_array_clear(&stash_args);
b4493f269e builtin/stash--helper.c  743) if (ret)
b4493f269e builtin/stash--helper.c  744) return -1;
b4493f269e builtin/stash--helper.c  750) if (!opts) {
b4493f269e builtin/stash--helper.c  751) git_config(git_stash_config, NULL);
b4493f269e builtin/stash--helper.c  752) if (show_stat)
b4493f269e builtin/stash--helper.c  753) rev.diffopt.output_format = 
DIFF_FORMAT_DIFFSTAT;
b4493f269e builtin/stash--helper.c  755) if (show_patch)
b4493f269e builtin/stash--helper.c  756) rev.diffopt.output_format |= 
DIFF_FORMAT_PATCH;
b4493f269e builtin/stash--helper.c  758) if (!show_stat && !show_patch) {
b4493f269e builtin/stash--helper.c  759) free_stash_info(&info);
b4493f269e builtin/stash--helper.c  760) return 0;
b4493f269e builtin/stash--helper.c  764) argc = setup_revisions(argc, 
argv, &rev, NULL);
b4493f269e builtin/stash--helper.c  765) if (argc > 1) {
b4493f269e builtin/stash--helper.c  766) free_stash_info(&info);
51809c70ca builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
b4493f269e builtin/stash--helper.c  770) rev.diffopt.flags.recursive = 1;
b4493f269e builtin/stash--helper.c  771) setup_diff_pager(&rev.diffopt);
b4493f269e builtin/stash--helper.c  772) diff_tree_oid(&info.b_commit, 
&info.w_commit, "", &rev.diffopt);
b4493f269e builtin/stash--helper.c  773) log_tree_diff_flush(&rev);
b4493f269e builtin/stash--helper.c  775) free_stash_info(&info);
b4493f269e builtin/stash--helper.c  776) return 
diff_result_code(&rev.diffopt, 0);
847eb0b0a8 builtin/stash--helper.c  779) static int do_store_stash(const 
struct object_id *w_commit, const char *stash_msg,
847eb0b0a8 builtin/stash--helper.c  782) if (!stash_msg)
847eb0b0a8 builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
847eb0b0a8 builtin/stash--helper.c  785) if (update_ref(stash_msg, 
ref_stash, w_commit, NULL,
847eb0b0a8 builtin/stash--helper.c  789) if (!quiet) {
847eb0b0a8 builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
847eb0b0a8 builtin/stash--helper.c  793) return -1;
847eb0b0a8 builtin/stash--helper.c  796) return 0;
847eb0b0a8 builtin/stash--helper.c  799) static int store_stash(int 
argc, const char **argv, const char *prefix)
847eb0b0a8 builtin/stash--helper.c  801) int quiet = 0;
847eb0b0a8 builtin/stash--helper.c  802) const char *stash_msg = NULL;
847eb0b0a8 builtin/stash--helper.c  805) struct option options[] = {
847eb0b0a8 builtin/stash--helper.c  812) argc = parse_options(argc, 
argv, prefix, options,
847eb0b0a8 builtin/stash--helper.c  816) if (argc != 1) {
847eb0b0a8 builtin/stash--helper.c  817) if (!quiet)
847eb0b0a8 builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
847eb0b0a8 builtin/stash--helper.c  820) return -1;
b6b4172bfb builtin/stash.c          823) if 
(get_oid_with_context(the_repository,
847eb0b0a8 builtin/stash--helper.c  826) if (!quiet)
847eb0b0a8 builtin/stash--helper.c  827) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
847eb0b0a8 builtin/stash--helper.c  829) return -1;
847eb0b0a8 builtin/stash--helper.c  832) return do_store_stash(&obj, 
stash_msg, quiet);
1f5a011d90 builtin/stash--helper.c  835) static void 
add_pathspecs(struct argv_array *args,
1f5a011d90 builtin/stash--helper.c  839) for (i = 0; i < ps.nr; i++)
1f5a011d90 builtin/stash--helper.c  840) argv_array_push(args, 
ps.items[i].match);
1f5a011d90 builtin/stash--helper.c  841) }
1f5a011d90 builtin/stash--helper.c  850) static int 
get_untracked_files(struct pathspec ps, int include_untracked,
1f5a011d90 builtin/stash--helper.c  855) int found = 0;
1f5a011d90 builtin/stash--helper.c  859) memset(&dir, 0, sizeof(dir));
1f5a011d90 builtin/stash--helper.c  860) if (include_untracked != 
INCLUDE_ALL_FILES)
1f5a011d90 builtin/stash--helper.c  861) setup_standard_excludes(&dir);
1f5a011d90 builtin/stash--helper.c  863) seen = xcalloc(ps.nr, 1);
1f5a011d90 builtin/stash--helper.c  865) max_len = fill_directory(&dir, 
the_repository->index, &ps);
1f5a011d90 builtin/stash--helper.c  866) for (i = 0; i < dir.nr; i++) {
1f5a011d90 builtin/stash--helper.c  867) struct dir_entry *ent = 
dir.entries[i];
1f5a011d90 builtin/stash--helper.c  868) if (dir_path_match(&the_index, 
ent, &ps, max_len, seen)) {
1f5a011d90 builtin/stash--helper.c  869) found++;
1f5a011d90 builtin/stash--helper.c  870) strbuf_addstr(untracked_files, 
ent->name);
1f5a011d90 builtin/stash--helper.c  872) strbuf_addch(untracked_files, 0);
1f5a011d90 builtin/stash--helper.c  874) free(ent);
1f5a011d90 builtin/stash--helper.c  877) free(seen);
1f5a011d90 builtin/stash--helper.c  878) free(dir.entries);
1f5a011d90 builtin/stash--helper.c  879) free(dir.ignored);
1f5a011d90 builtin/stash--helper.c  880) clear_directory(&dir);
1f5a011d90 builtin/stash--helper.c  881) return found;
168e6cff5e builtin/stash--helper.c  892) static int 
check_changes_tracked_files(struct pathspec ps)
1f5a011d90 builtin/stash--helper.c  899) if (get_oid("HEAD", &dummy))
1f5a011d90 builtin/stash--helper.c  900) return -1;
1f5a011d90 builtin/stash--helper.c  902) if (read_cache() < 0)
1f5a011d90 builtin/stash--helper.c  903) return -1;
1f5a011d90 builtin/stash--helper.c  905) init_revisions(&rev, NULL);
1f5a011d90 builtin/stash--helper.c  906) rev.prune_data = ps;
1f5a011d90 builtin/stash--helper.c  908) rev.diffopt.flags.quick = 1;
1f5a011d90 builtin/stash--helper.c  909) 
rev.diffopt.flags.ignore_submodules = 1;
1f5a011d90 builtin/stash--helper.c  910) rev.abbrev = 0;
1f5a011d90 builtin/stash--helper.c  912) add_head_to_pending(&rev);
1f5a011d90 builtin/stash--helper.c  913) diff_setup_done(&rev.diffopt);
1f5a011d90 builtin/stash--helper.c  915) result = run_diff_index(&rev, 1);
1f5a011d90 builtin/stash--helper.c  916) if 
(diff_result_code(&rev.diffopt, result))
1f5a011d90 builtin/stash--helper.c  917) return 1;
1f5a011d90 builtin/stash--helper.c  919) object_array_clear(&rev.pending);
1f5a011d90 builtin/stash--helper.c  920) result = run_diff_files(&rev, 0);
1f5a011d90 builtin/stash--helper.c  921) if 
(diff_result_code(&rev.diffopt, result))
1f5a011d90 builtin/stash--helper.c  922) return 1;
168e6cff5e builtin/stash--helper.c  924) return 0;
168e6cff5e builtin/stash--helper.c  932) static int check_changes(struct 
pathspec ps, int include_untracked,
168e6cff5e builtin/stash--helper.c  935) int ret = 0;
168e6cff5e builtin/stash--helper.c  936) if 
(check_changes_tracked_files(ps))
168e6cff5e builtin/stash--helper.c  937) ret = 1;
1f5a011d90 builtin/stash--helper.c  939) if (include_untracked && 
get_untracked_files(ps, include_untracked,
168e6cff5e builtin/stash--helper.c  941) ret = 1;
168e6cff5e builtin/stash--helper.c  943) return ret;
1f5a011d90 builtin/stash--helper.c  946) static int 
save_untracked_files(struct stash_info *info, struct strbuf *msg,
1f5a011d90 builtin/stash--helper.c  949) int ret = 0;
1f5a011d90 builtin/stash--helper.c  950) struct strbuf untracked_msg = 
STRBUF_INIT;
1f5a011d90 builtin/stash--helper.c  951) struct child_process 
cp_upd_index = CHILD_PROCESS_INIT;
559edead8f builtin/stash--helper.c  952) struct index_state istate = { 
NULL };
1f5a011d90 builtin/stash--helper.c  954) cp_upd_index.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c  955) 
argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
1f5a011d90 builtin/stash--helper.c  957) 
argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
1f5a011d90 builtin/stash--helper.c  960) strbuf_addf(&untracked_msg, 
"untracked files on %s\n", msg->buf);
1f5a011d90 builtin/stash--helper.c  961) if (pipe_command(&cp_upd_index, 
files.buf, files.len, NULL, 0,
1f5a011d90 builtin/stash--helper.c  963) ret = -1;
1f5a011d90 builtin/stash--helper.c  964) goto done;
559edead8f builtin/stash--helper.c  967) if 
(write_index_as_tree(&info->u_tree, &istate, stash_index_path.buf, 0,
1f5a011d90 builtin/stash--helper.c  969) ret = -1;
1f5a011d90 builtin/stash--helper.c  970) goto done;
1f5a011d90 builtin/stash--helper.c  973) if 
(commit_tree(untracked_msg.buf, untracked_msg.len,
1f5a011d90 builtin/stash--helper.c  974) &info->u_tree, NULL, 
&info->u_commit, NULL, NULL)) {
1f5a011d90 builtin/stash--helper.c  975) ret = -1;
1f5a011d90 builtin/stash--helper.c  976) goto done;
559edead8f builtin/stash--helper.c  980) discard_index(&istate);
1f5a011d90 builtin/stash--helper.c  981) strbuf_release(&untracked_msg);
1f5a011d90 builtin/stash--helper.c  982) remove_path(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c  983) return ret;
1f5a011d90 builtin/stash--helper.c  986) static int stash_patch(struct 
stash_info *info, struct pathspec ps,
1f5a011d90 builtin/stash--helper.c  989) int ret = 0;
1f5a011d90 builtin/stash--helper.c  990) struct child_process 
cp_read_tree = CHILD_PROCESS_INIT;
1f5a011d90 builtin/stash--helper.c  991) struct child_process cp_add_i = 
CHILD_PROCESS_INIT;
1f5a011d90 builtin/stash--helper.c  992) struct child_process 
cp_diff_tree = CHILD_PROCESS_INIT;
559edead8f builtin/stash--helper.c  993) struct index_state istate = { 
NULL };
1f5a011d90 builtin/stash--helper.c  995) remove_path(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c  997) cp_read_tree.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c  998) 
argv_array_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL);
1f5a011d90 builtin/stash--helper.c  999) 
argv_array_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s",
1f5a011d90 builtin/stash--helper.c 1001) if (run_command(&cp_read_tree)) {
1f5a011d90 builtin/stash--helper.c 1002) ret = -1;
1f5a011d90 builtin/stash--helper.c 1003) goto done;
1f5a011d90 builtin/stash--helper.c 1007) cp_add_i.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c 1008) 
argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash",
1f5a011d90 builtin/stash--helper.c 1010) add_pathspecs(&cp_add_i.args, ps);
1f5a011d90 builtin/stash--helper.c 1011) 
argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s",
1f5a011d90 builtin/stash--helper.c 1013) if (run_command(&cp_add_i)) {
1f5a011d90 builtin/stash--helper.c 1014) ret = -1;
1f5a011d90 builtin/stash--helper.c 1015) goto done;
559edead8f builtin/stash--helper.c 1019) if 
(write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0,
1f5a011d90 builtin/stash--helper.c 1021) ret = -1;
1f5a011d90 builtin/stash--helper.c 1022) goto done;
1f5a011d90 builtin/stash--helper.c 1025) cp_diff_tree.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c 1026) 
argv_array_pushl(&cp_diff_tree.args, "diff-tree", "-p", "HEAD",
1f5a011d90 builtin/stash--helper.c 1027) oid_to_hex(&info->w_tree), 
"--", NULL);
1f5a011d90 builtin/stash--helper.c 1028) if (pipe_command(&cp_diff_tree, 
NULL, 0, out_patch, 0, NULL, 0)) {
1f5a011d90 builtin/stash--helper.c 1029) ret = -1;
1f5a011d90 builtin/stash--helper.c 1030) goto done;
1f5a011d90 builtin/stash--helper.c 1033) if (!out_patch->len) {
9a95010a11 builtin/stash--helper.c 1034) if (!quiet)
9a95010a11 builtin/stash--helper.c 1035) fprintf_ln(stderr, _("No 
changes selected"));
1f5a011d90 builtin/stash--helper.c 1036) ret = 1;
559edead8f builtin/stash--helper.c 1040) discard_index(&istate);
1f5a011d90 builtin/stash--helper.c 1041) remove_path(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c 1042) return ret;
1f5a011d90 builtin/stash--helper.c 1045) static int 
stash_working_tree(struct stash_info *info, struct pathspec ps)
1f5a011d90 builtin/stash--helper.c 1047) int ret = 0;
1f5a011d90 builtin/stash--helper.c 1049) struct child_process 
cp_upd_index = CHILD_PROCESS_INIT;
1f5a011d90 builtin/stash--helper.c 1050) struct strbuf diff_output = 
STRBUF_INIT;
559edead8f builtin/stash--helper.c 1051) struct index_state istate = { 
NULL };
ed5d77f7d3 builtin/stash.c         1053) init_revisions(&rev, NULL);
1f5a011d90 builtin/stash--helper.c 1055) 
set_alternate_index_output(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c 1056) if (reset_tree(&info->i_tree, 
0, 0)) {
1f5a011d90 builtin/stash--helper.c 1057) ret = -1;
1f5a011d90 builtin/stash--helper.c 1058) goto done;
1f5a011d90 builtin/stash--helper.c 1060) set_alternate_index_output(NULL);
1f5a011d90 builtin/stash--helper.c 1062) rev.prune_data = ps;
1f5a011d90 builtin/stash--helper.c 1063) rev.diffopt.output_format = 
DIFF_FORMAT_CALLBACK;
1f5a011d90 builtin/stash--helper.c 1064) rev.diffopt.format_callback = 
add_diff_to_buf;
1f5a011d90 builtin/stash--helper.c 1065) 
rev.diffopt.format_callback_data = &diff_output;
1f5a011d90 builtin/stash--helper.c 1067) if 
(read_cache_preload(&rev.diffopt.pathspec) < 0) {
1f5a011d90 builtin/stash--helper.c 1068) ret = -1;
1f5a011d90 builtin/stash--helper.c 1069) goto done;
1f5a011d90 builtin/stash--helper.c 1072) add_pending_object(&rev, 
parse_object(the_repository, &info->b_commit),
1f5a011d90 builtin/stash--helper.c 1074) if (run_diff_index(&rev, 0)) {
1f5a011d90 builtin/stash--helper.c 1075) ret = -1;
1f5a011d90 builtin/stash--helper.c 1076) goto done;
1f5a011d90 builtin/stash--helper.c 1079) cp_upd_index.git_cmd = 1;
1f5a011d90 builtin/stash--helper.c 1080) 
argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
1f5a011d90 builtin/stash--helper.c 1082) 
argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
1f5a011d90 builtin/stash--helper.c 1085) if (pipe_command(&cp_upd_index, 
diff_output.buf, diff_output.len,
1f5a011d90 builtin/stash--helper.c 1087) ret = -1;
1f5a011d90 builtin/stash--helper.c 1088) goto done;
559edead8f builtin/stash--helper.c 1091) if 
(write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0,
1f5a011d90 builtin/stash--helper.c 1093) ret = -1;
1f5a011d90 builtin/stash--helper.c 1094) goto done;
559edead8f builtin/stash--helper.c 1098) discard_index(&istate);
1f5a011d90 builtin/stash--helper.c 1100) object_array_clear(&rev.pending);
1f5a011d90 builtin/stash--helper.c 1101) strbuf_release(&diff_output);
1f5a011d90 builtin/stash--helper.c 1102) remove_path(stash_index_path.buf);
1f5a011d90 builtin/stash--helper.c 1103) return ret;
1f5a011d90 builtin/stash--helper.c 1106) static int 
do_create_stash(struct pathspec ps, struct strbuf *stash_msg_buf,
1f5a011d90 builtin/stash--helper.c 1111) int ret = 0;
1f5a011d90 builtin/stash--helper.c 1112) int flags = 0;
1f5a011d90 builtin/stash--helper.c 1113) int untracked_commit_option = 0;
1f5a011d90 builtin/stash--helper.c 1114) const char *head_short_sha1 = NULL;
1f5a011d90 builtin/stash--helper.c 1115) const char *branch_ref = NULL;
1f5a011d90 builtin/stash--helper.c 1116) const char *branch_name = "(no 
branch)";
1f5a011d90 builtin/stash--helper.c 1117) struct commit *head_commit = NULL;
1f5a011d90 builtin/stash--helper.c 1118) struct commit_list *parents = NULL;
1f5a011d90 builtin/stash--helper.c 1119) struct strbuf msg = STRBUF_INIT;
1f5a011d90 builtin/stash--helper.c 1120) struct strbuf commit_tree_label 
= STRBUF_INIT;
1f5a011d90 builtin/stash--helper.c 1121) struct strbuf untracked_files = 
STRBUF_INIT;
1f5a011d90 builtin/stash--helper.c 1123) prepare_fallback_ident("git 
stash", "git@stash");
1f5a011d90 builtin/stash--helper.c 1125) read_cache_preload(NULL);
1f5a011d90 builtin/stash--helper.c 1126) refresh_cache(REFRESH_QUIET);
1f5a011d90 builtin/stash--helper.c 1128) if (get_oid("HEAD", 
&info->b_commit)) {
9a95010a11 builtin/stash--helper.c 1129) if (!quiet)
9a95010a11 builtin/stash--helper.c 1130) fprintf_ln(stderr, _("You do 
not have "
1f5a011d90 builtin/stash--helper.c 1132) ret = -1;
1f5a011d90 builtin/stash--helper.c 1133) goto done;
1f5a011d90 builtin/stash--helper.c 1135) head_commit = 
lookup_commit(the_repository, &info->b_commit);
168e6cff5e builtin/stash--helper.c 1138) if (!check_changes(ps, 
include_untracked, &untracked_files)) {
1f5a011d90 builtin/stash--helper.c 1139) ret = 1;
1f5a011d90 builtin/stash--helper.c 1140) goto done;
1f5a011d90 builtin/stash--helper.c 1143) branch_ref = 
resolve_ref_unsafe("HEAD", 0, NULL, &flags);
1f5a011d90 builtin/stash--helper.c 1144) if (flags & REF_ISSYMREF)
1f5a011d90 builtin/stash--helper.c 1145) branch_name = 
strrchr(branch_ref, '/') + 1;
1f5a011d90 builtin/stash--helper.c 1146) head_short_sha1 = 
find_unique_abbrev(&head_commit->object.oid,
1f5a011d90 builtin/stash--helper.c 1148) strbuf_addf(&msg, "%s: %s ", 
branch_name, head_short_sha1);
1f5a011d90 builtin/stash--helper.c 1149) 
pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg);
1f5a011d90 builtin/stash--helper.c 1151) strbuf_addf(&commit_tree_label, 
"index on %s\n", msg.buf);
1f5a011d90 builtin/stash--helper.c 1152) commit_list_insert(head_commit, 
&parents);
1f5a011d90 builtin/stash--helper.c 1153) if 
(write_cache_as_tree(&info->i_tree, 0, NULL) ||
1f5a011d90 builtin/stash--helper.c 1154) 
commit_tree(commit_tree_label.buf, commit_tree_label.len,
1f5a011d90 builtin/stash--helper.c 1155) &info->i_tree, parents, 
&info->i_commit, NULL, NULL)) {
9a95010a11 builtin/stash--helper.c 1156) if (!quiet)
9a95010a11 builtin/stash--helper.c 1157) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1159) ret = -1;
1f5a011d90 builtin/stash--helper.c 1160) goto done;
168e6cff5e builtin/stash--helper.c 1163) if (include_untracked) {
1f5a011d90 builtin/stash--helper.c 1164) if (save_untracked_files(info, 
&msg, untracked_files)) {
9a95010a11 builtin/stash--helper.c 1165) if (!quiet)
9a95010a11 builtin/stash--helper.c 1166) fprintf_ln(stderr, _("Cannot save "
1f5a011d90 builtin/stash--helper.c 1168) ret = -1;
1f5a011d90 builtin/stash--helper.c 1169) goto done;
1f5a011d90 builtin/stash--helper.c 1171) untracked_commit_option = 1;
1f5a011d90 builtin/stash--helper.c 1173) if (patch_mode) {
9a95010a11 builtin/stash--helper.c 1174) ret = stash_patch(info, ps, 
patch, quiet);
1f5a011d90 builtin/stash--helper.c 1175) if (ret < 0) {
9a95010a11 builtin/stash--helper.c 1176) if (!quiet)
9a95010a11 builtin/stash--helper.c 1177) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1179) goto done;
1f5a011d90 builtin/stash--helper.c 1180) } else if (ret > 0) {
1f5a011d90 builtin/stash--helper.c 1181) goto done;
1f5a011d90 builtin/stash--helper.c 1184) if (stash_working_tree(info, ps)) {
9a95010a11 builtin/stash--helper.c 1185) if (!quiet)
9a95010a11 builtin/stash--helper.c 1186) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1188) ret = -1;
1f5a011d90 builtin/stash--helper.c 1189) goto done;
1f5a011d90 builtin/stash--helper.c 1193) if (!stash_msg_buf->len)
1f5a011d90 builtin/stash--helper.c 1194) strbuf_addf(stash_msg_buf, "WIP 
on %s", msg.buf);
1f5a011d90 builtin/stash--helper.c 1196) strbuf_insertf(stash_msg_buf, 
0, "On %s: ", branch_name);
1f5a011d90 builtin/stash--helper.c 1202) parents = NULL;
1f5a011d90 builtin/stash--helper.c 1203) if (untracked_commit_option)
1f5a011d90 builtin/stash--helper.c 1204) 
commit_list_insert(lookup_commit(the_repository,
1f5a011d90 builtin/stash--helper.c 1205) &info->u_commit),
1f5a011d90 builtin/stash--helper.c 1207) 
commit_list_insert(lookup_commit(the_repository, &info->i_commit),
1f5a011d90 builtin/stash--helper.c 1209) commit_list_insert(head_commit, 
&parents);
1f5a011d90 builtin/stash--helper.c 1211) if 
(commit_tree(stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree,
9a95010a11 builtin/stash--helper.c 1213) if (!quiet)
9a95010a11 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
1f5a011d90 builtin/stash--helper.c 1216) ret = -1;
1f5a011d90 builtin/stash--helper.c 1217) goto done;
1f5a011d90 builtin/stash--helper.c 1221) strbuf_release(&commit_tree_label);
1f5a011d90 builtin/stash--helper.c 1222) strbuf_release(&msg);
1f5a011d90 builtin/stash--helper.c 1223) strbuf_release(&untracked_files);
1f5a011d90 builtin/stash--helper.c 1224) return ret;
1f5a011d90 builtin/stash--helper.c 1227) static int create_stash(int 
argc, const char **argv, const char *prefix)
1f5a011d90 builtin/stash--helper.c 1229) int ret = 0;
1f5a011d90 builtin/stash--helper.c 1230) struct strbuf stash_msg_buf = 
STRBUF_INIT;
51809c70ca builtin/stash.c         1235) 
strbuf_join_argv(&stash_msg_buf, argc - 1, ++argv, ' ');
1f5a011d90 builtin/stash--helper.c 1237) memset(&ps, 0, sizeof(ps));
168e6cff5e builtin/stash--helper.c 1238) if 
(!check_changes_tracked_files(ps))
168e6cff5e builtin/stash--helper.c 1239) return 0;
168e6cff5e builtin/stash--helper.c 1241) if (!(ret = do_create_stash(ps, 
&stash_msg_buf, 0, 0, &info, NULL, 0)))
1f5a011d90 builtin/stash--helper.c 1242) printf_ln("%s", 
oid_to_hex(&info.w_commit));
1f5a011d90 builtin/stash--helper.c 1244) strbuf_release(&stash_msg_buf);
168e6cff5e builtin/stash--helper.c 1245) return ret;
fa38428f76 builtin/stash--helper.c 1248) static int do_push_stash(struct 
pathspec ps, const char *stash_msg, int quiet,
fa38428f76 builtin/stash--helper.c 1251) int ret = 0;
fa38428f76 builtin/stash--helper.c 1253) struct strbuf patch = STRBUF_INIT;
fa38428f76 builtin/stash--helper.c 1254) struct strbuf stash_msg_buf = 
STRBUF_INIT;
168e6cff5e builtin/stash--helper.c 1255) struct strbuf untracked_files = 
STRBUF_INIT;
fa38428f76 builtin/stash--helper.c 1257) if (patch_mode && keep_index == -1)
fa38428f76 builtin/stash--helper.c 1258) keep_index = 1;
fa38428f76 builtin/stash--helper.c 1260) if (patch_mode && 
include_untracked) {
fa38428f76 builtin/stash--helper.c 1261) fprintf_ln(stderr, _("Can't use 
--patch and --include-untracked"
fa38428f76 builtin/stash--helper.c 1263) ret = -1;
fa38428f76 builtin/stash--helper.c 1264) goto done;
fa38428f76 builtin/stash--helper.c 1267) read_cache_preload(NULL);
fa38428f76 builtin/stash--helper.c 1268) if (!include_untracked && ps.nr) {
fa38428f76 builtin/stash--helper.c 1270) char *ps_matched = 
xcalloc(ps.nr, 1);
fa38428f76 builtin/stash--helper.c 1272) for (i = 0; i < active_nr; i++)
fa38428f76 builtin/stash--helper.c 1273) ce_path_match(&the_index, 
active_cache[i], &ps,
fa38428f76 builtin/stash--helper.c 1276) if 
(report_path_error(ps_matched, &ps, NULL)) {
fa38428f76 builtin/stash--helper.c 1277) fprintf_ln(stderr, _("Did you 
forget to 'git add'?"));
fa38428f76 builtin/stash--helper.c 1278) ret = -1;
fa38428f76 builtin/stash--helper.c 1279) free(ps_matched);
fa38428f76 builtin/stash--helper.c 1280) goto done;
fa38428f76 builtin/stash--helper.c 1282) free(ps_matched);
fa38428f76 builtin/stash--helper.c 1285) if (refresh_cache(REFRESH_QUIET)) {
fa38428f76 builtin/stash--helper.c 1286) ret = -1;
fa38428f76 builtin/stash--helper.c 1287) goto done;
168e6cff5e builtin/stash--helper.c 1290) if (!check_changes(ps, 
include_untracked, &untracked_files)) {
fa38428f76 builtin/stash--helper.c 1291) if (!quiet)
fa38428f76 builtin/stash--helper.c 1292) printf_ln(_("No local changes 
to save"));
fa38428f76 builtin/stash--helper.c 1293) goto done;
fa38428f76 builtin/stash--helper.c 1296) if (!reflog_exists(ref_stash) 
&& do_clear_stash()) {
fa38428f76 builtin/stash--helper.c 1297) ret = -1;
9a95010a11 builtin/stash--helper.c 1298) if (!quiet)
9a95010a11 builtin/stash--helper.c 1299) fprintf_ln(stderr, _("Cannot 
initialize stash"));
fa38428f76 builtin/stash--helper.c 1300) goto done;
fa38428f76 builtin/stash--helper.c 1303) if (stash_msg)
fa38428f76 builtin/stash--helper.c 1304) strbuf_addstr(&stash_msg_buf, 
stash_msg);
fa38428f76 builtin/stash--helper.c 1305) if (do_create_stash(ps, 
&stash_msg_buf, include_untracked, patch_mode,
fa38428f76 builtin/stash--helper.c 1307) ret = -1;
fa38428f76 builtin/stash--helper.c 1308) goto done;
fa38428f76 builtin/stash--helper.c 1311) if 
(do_store_stash(&info.w_commit, stash_msg_buf.buf, 1)) {
fa38428f76 builtin/stash--helper.c 1312) ret = -1;
9a95010a11 builtin/stash--helper.c 1313) if (!quiet)
9a95010a11 builtin/stash--helper.c 1314) fprintf_ln(stderr, _("Cannot 
save the current status"));
fa38428f76 builtin/stash--helper.c 1315) goto done;
9a95010a11 builtin/stash--helper.c 1318) if (!quiet)
9a95010a11 builtin/stash--helper.c 1319) printf_ln(_("Saved working 
directory and index state %s"),
fa38428f76 builtin/stash--helper.c 1322) if (!patch_mode) {
fa38428f76 builtin/stash--helper.c 1323) if (include_untracked && !ps.nr) {
fa38428f76 builtin/stash--helper.c 1324) struct child_process cp = 
CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1326) cp.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1327) argv_array_pushl(&cp.args, 
"clean", "--force",
fa38428f76 builtin/stash--helper.c 1329) if (include_untracked == 
INCLUDE_ALL_FILES)
fa38428f76 builtin/stash--helper.c 1330) argv_array_push(&cp.args, "-x");
fa38428f76 builtin/stash--helper.c 1331) if (run_command(&cp)) {
fa38428f76 builtin/stash--helper.c 1332) ret = -1;
fa38428f76 builtin/stash--helper.c 1333) goto done;
fa38428f76 builtin/stash--helper.c 1336) if (ps.nr) {
fa38428f76 builtin/stash--helper.c 1337) struct child_process cp_add = 
CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1338) struct child_process cp_diff = 
CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1339) struct child_process cp_apply = 
CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1340) struct strbuf out = STRBUF_INIT;
fa38428f76 builtin/stash--helper.c 1342) cp_add.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1343) argv_array_push(&cp_add.args, 
"add");
fa38428f76 builtin/stash--helper.c 1344) if (!include_untracked)
fa38428f76 builtin/stash--helper.c 1345) argv_array_push(&cp_add.args, 
"-u");
fa38428f76 builtin/stash--helper.c 1346) if (include_untracked == 
INCLUDE_ALL_FILES)
fa38428f76 builtin/stash--helper.c 1347) argv_array_push(&cp_add.args, 
"--force");
fa38428f76 builtin/stash--helper.c 1348) argv_array_push(&cp_add.args, 
"--");
fa38428f76 builtin/stash--helper.c 1349) add_pathspecs(&cp_add.args, ps);
fa38428f76 builtin/stash--helper.c 1350) if (run_command(&cp_add)) {
fa38428f76 builtin/stash--helper.c 1351) ret = -1;
fa38428f76 builtin/stash--helper.c 1352) goto done;
fa38428f76 builtin/stash--helper.c 1355) cp_diff.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1356) argv_array_pushl(&cp_diff.args, 
"diff-index", "-p",
fa38428f76 builtin/stash--helper.c 1359) add_pathspecs(&cp_diff.args, ps);
fa38428f76 builtin/stash--helper.c 1360) if (pipe_command(&cp_diff, 
NULL, 0, &out, 0, NULL, 0)) {
fa38428f76 builtin/stash--helper.c 1361) ret = -1;
fa38428f76 builtin/stash--helper.c 1362) goto done;
fa38428f76 builtin/stash--helper.c 1365) cp_apply.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1366) 
argv_array_pushl(&cp_apply.args, "apply", "--index",
fa38428f76 builtin/stash--helper.c 1368) if (pipe_command(&cp_apply, 
out.buf, out.len, NULL, 0,
fa38428f76 builtin/stash--helper.c 1370) ret = -1;
fa38428f76 builtin/stash--helper.c 1371) goto done;
fa38428f76 builtin/stash--helper.c 1374) struct child_process cp = 
CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1375) cp.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1376) argv_array_pushl(&cp.args, 
"reset", "--hard", "-q",
fa38428f76 builtin/stash--helper.c 1378) if (run_command(&cp)) {
fa38428f76 builtin/stash--helper.c 1379) ret = -1;
fa38428f76 builtin/stash--helper.c 1380) goto done;
fa38428f76 builtin/stash--helper.c 1384) if (keep_index == 1 && 
!is_null_oid(&info.i_tree)) {
fa38428f76 builtin/stash--helper.c 1385) struct child_process cp_ls = 
CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1386) struct child_process 
cp_checkout = CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1387) struct strbuf out = STRBUF_INIT;
fa38428f76 builtin/stash--helper.c 1389) if (reset_tree(&info.i_tree, 0, 
1)) {
fa38428f76 builtin/stash--helper.c 1390) ret = -1;
fa38428f76 builtin/stash--helper.c 1391) goto done;
fa38428f76 builtin/stash--helper.c 1394) cp_ls.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1395) argv_array_pushl(&cp_ls.args, 
"ls-files", "-z",
fa38428f76 builtin/stash--helper.c 1398) add_pathspecs(&cp_ls.args, ps);
fa38428f76 builtin/stash--helper.c 1399) if (pipe_command(&cp_ls, NULL, 
0, &out, 0, NULL, 0)) {
fa38428f76 builtin/stash--helper.c 1400) ret = -1;
fa38428f76 builtin/stash--helper.c 1401) goto done;
fa38428f76 builtin/stash--helper.c 1404) cp_checkout.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1405) 
argv_array_pushl(&cp_checkout.args, "checkout-index",
fa38428f76 builtin/stash--helper.c 1407) if (pipe_command(&cp_checkout, 
out.buf, out.len, NULL,
fa38428f76 builtin/stash--helper.c 1409) ret = -1;
fa38428f76 builtin/stash--helper.c 1410) goto done;
fa38428f76 builtin/stash--helper.c 1413) goto done;
fa38428f76 builtin/stash--helper.c 1415) struct child_process cp = 
CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1417) cp.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1418) argv_array_pushl(&cp.args, 
"apply", "-R", NULL);
fa38428f76 builtin/stash--helper.c 1420) if (pipe_command(&cp, 
patch.buf, patch.len, NULL, 0, NULL, 0)) {
9a95010a11 builtin/stash--helper.c 1421) if (!quiet)
9a95010a11 builtin/stash--helper.c 1422) fprintf_ln(stderr, _("Cannot 
remove "
fa38428f76 builtin/stash--helper.c 1424) ret = -1;
fa38428f76 builtin/stash--helper.c 1425) goto done;
fa38428f76 builtin/stash--helper.c 1428) if (keep_index < 1) {
fa38428f76 builtin/stash--helper.c 1429) struct child_process cp = 
CHILD_PROCESS_INIT;
fa38428f76 builtin/stash--helper.c 1431) cp.git_cmd = 1;
fa38428f76 builtin/stash--helper.c 1432) argv_array_pushl(&cp.args, 
"reset", "-q", "--", NULL);
fa38428f76 builtin/stash--helper.c 1433) add_pathspecs(&cp.args, ps);
fa38428f76 builtin/stash--helper.c 1434) if (run_command(&cp)) {
fa38428f76 builtin/stash--helper.c 1435) ret = -1;
fa38428f76 builtin/stash--helper.c 1436) goto done;
fa38428f76 builtin/stash--helper.c 1439) goto done;
fa38428f76 builtin/stash--helper.c 1443) strbuf_release(&stash_msg_buf);
fa38428f76 builtin/stash--helper.c 1444) return ret;
fa38428f76 builtin/stash--helper.c 1447) static int push_stash(int argc, 
const char **argv, const char *prefix)
fa38428f76 builtin/stash--helper.c 1449) int keep_index = -1;
fa38428f76 builtin/stash--helper.c 1450) int patch_mode = 0;
fa38428f76 builtin/stash--helper.c 1451) int include_untracked = 0;
fa38428f76 builtin/stash--helper.c 1452) int quiet = 0;
fa38428f76 builtin/stash--helper.c 1453) const char *stash_msg = NULL;
fa38428f76 builtin/stash--helper.c 1455) struct option options[] = {
51809c70ca builtin/stash.c         1470) if (argc)
51809c70ca builtin/stash.c         1471) argc = parse_options(argc, 
argv, prefix, options,
fa38428f76 builtin/stash--helper.c 1475) parse_pathspec(&ps, 0, 
PATHSPEC_PREFER_FULL, prefix, argv);
fa38428f76 builtin/stash--helper.c 1476) return do_push_stash(ps, 
stash_msg, quiet, keep_index, patch_mode,
cf5b27d699 builtin/stash--helper.c 1480) static int save_stash(int argc, 
const char **argv, const char *prefix)
cf5b27d699 builtin/stash--helper.c 1482) int keep_index = -1;
cf5b27d699 builtin/stash--helper.c 1483) int patch_mode = 0;
cf5b27d699 builtin/stash--helper.c 1484) int include_untracked = 0;
cf5b27d699 builtin/stash--helper.c 1485) int quiet = 0;
cf5b27d699 builtin/stash--helper.c 1486) int ret = 0;
cf5b27d699 builtin/stash--helper.c 1487) const char *stash_msg = NULL;
cf5b27d699 builtin/stash--helper.c 1489) struct strbuf stash_msg_buf = 
STRBUF_INIT;
cf5b27d699 builtin/stash--helper.c 1490) struct option options[] = {
cf5b27d699 builtin/stash--helper.c 1505) argc = parse_options(argc, 
argv, prefix, options,
cf5b27d699 builtin/stash--helper.c 1509) if (argc)
cf5b27d699 builtin/stash--helper.c 1510) stash_msg = 
strbuf_join_argv(&stash_msg_buf, argc, argv, ' ');
cf5b27d699 builtin/stash--helper.c 1512) memset(&ps, 0, sizeof(ps));
cf5b27d699 builtin/stash--helper.c 1513) ret = do_push_stash(ps, 
stash_msg, quiet, keep_index,
cf5b27d699 builtin/stash--helper.c 1516) strbuf_release(&stash_msg_buf);
cf5b27d699 builtin/stash--helper.c 1517) return ret;
bec65d5b78 builtin/stash.c         1527) return env;
26799a208f builtin/stash.c         1537) strbuf_trim(&out);
26799a208f builtin/stash.c         1538) ret = !strcmp("true", out.buf);
26799a208f builtin/stash.c         1539) strbuf_release(&out);
26799a208f builtin/stash.c         1555) const char *path = 
mkpath("%s/git-legacy-stash",
26799a208f builtin/stash.c         1558) if (sane_execvp(path, (char 
**)argv) < 0)
26799a208f builtin/stash.c         1559) die_errno(_("could not exec 
%s"), path);
f6bbd78127 builtin/stash--helper.c 1573) index_file = get_index_file();
f6bbd78127 builtin/stash--helper.c 1574) strbuf_addf(&stash_index_path, 
"%s.stash.%" PRIuMAX, index_file,
51809c70ca builtin/stash.c         1577) if (!argc)
51809c70ca builtin/stash.c         1578) return !!push_stash(0, NULL, 
prefix);
51809c70ca builtin/stash.c         1579) else if (!strcmp(argv[0], "apply"))
f6bbd78127 builtin/stash--helper.c 1580) return !!apply_stash(argc, 
argv, prefix);
cdca49bc4c builtin/stash--helper.c 1581) else if (!strcmp(argv[0], "clear"))
cdca49bc4c builtin/stash--helper.c 1582) return !!clear_stash(argc, 
argv, prefix);
cdca49bc4c builtin/stash--helper.c 1583) else if (!strcmp(argv[0], "drop"))
cdca49bc4c builtin/stash--helper.c 1584) return !!drop_stash(argc, argv, 
prefix);
e1d01876a4 builtin/stash--helper.c 1585) else if (!strcmp(argv[0], "pop"))
e1d01876a4 builtin/stash--helper.c 1586) return !!pop_stash(argc, argv, 
prefix);
f596f3366c builtin/stash--helper.c 1587) else if (!strcmp(argv[0], 
"branch"))
f596f3366c builtin/stash--helper.c 1588) return !!branch_stash(argc, 
argv, prefix);
9b77b07ba4 builtin/stash--helper.c 1589) else if (!strcmp(argv[0], "list"))
9b77b07ba4 builtin/stash--helper.c 1590) return !!list_stash(argc, argv, 
prefix);
b4493f269e builtin/stash--helper.c 1591) else if (!strcmp(argv[0], "show"))
b4493f269e builtin/stash--helper.c 1592) return !!show_stash(argc, argv, 
prefix);
847eb0b0a8 builtin/stash--helper.c 1593) else if (!strcmp(argv[0], "store"))
847eb0b0a8 builtin/stash--helper.c 1594) return !!store_stash(argc, 
argv, prefix);
1f5a011d90 builtin/stash--helper.c 1595) else if (!strcmp(argv[0], 
"create"))
1f5a011d90 builtin/stash--helper.c 1596) return !!create_stash(argc, 
argv, prefix);
fa38428f76 builtin/stash--helper.c 1597) else if (!strcmp(argv[0], "push"))
fa38428f76 builtin/stash--helper.c 1598) return !!push_stash(argc, argv, 
prefix);
cf5b27d699 builtin/stash--helper.c 1599) else if (!strcmp(argv[0], "save"))
cf5b27d699 builtin/stash--helper.c 1600) return !!save_stash(argc, argv, 
prefix);
51809c70ca builtin/stash.c         1601) else if (*argv[0] != '-')
51809c70ca builtin/stash.c         1602) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
51809c70ca builtin/stash.c         1605) if (strcmp(argv[0], "-p")) {
51809c70ca builtin/stash.c         1606) while (++i < argc && 
strcmp(argv[i], "--")) {
51809c70ca builtin/stash.c         1611) if ((strlen(argv[i]) == 2) && 
*argv[i] == '-' &&
51809c70ca builtin/stash.c         1612)     strchr("akpqu", argv[i][1]))
51809c70ca builtin/stash.c         1613) continue;
51809c70ca builtin/stash.c         1615) if (!strcmp(argv[i], "--all") ||
51809c70ca builtin/stash.c         1616)     !strcmp(argv[i], 
"--keep-index") ||
51809c70ca builtin/stash.c         1617)     !strcmp(argv[i], 
"--no-keep-index") ||
51809c70ca builtin/stash.c         1618)     !strcmp(argv[i], "--patch") ||
51809c70ca builtin/stash.c         1619)     !strcmp(argv[i], "--quiet") ||
51809c70ca builtin/stash.c         1620)     !strcmp(argv[i], 
"--include-untracked"))
51809c70ca builtin/stash.c         1621) continue;
51809c70ca builtin/stash.c         1628) if (starts_with(argv[i], "-m") ||
51809c70ca builtin/stash.c         1629) starts_with(argv[i], "--message="))
51809c70ca builtin/stash.c         1630) continue;
51809c70ca builtin/stash.c         1632) 
usage_with_options(git_stash_usage, options);
51809c70ca builtin/stash.c         1636) argv_array_push(&args, "push");
51809c70ca builtin/stash.c         1637) argv_array_pushv(&args, argv);
51809c70ca builtin/stash.c         1638) return !!push_stash(args.argc, 
args.argv, prefix);

builtin/update-index.c
08339886b9 builtin/update-index.c  895) static enum parse_opt_result 
stdin_callback(
9b4ae5190a builtin/update-index.c  902) BUG_ON_OPT_ARG(arg);
08339886b9 builtin/update-index.c  910) static enum parse_opt_result 
unresolve_callback(
9b4ae5190a builtin/update-index.c  918) BUG_ON_OPT_ARG(arg);
08339886b9 builtin/update-index.c  931) static enum parse_opt_result 
reupdate_callback(
9b4ae5190a builtin/update-index.c  939) BUG_ON_OPT_ARG(arg);

builtin/upload-archive.c
6da1f1a920 builtin/upload-archive.c  86) 
register_allowed_protocol_version(protocol_v0);

commit-graph.c
97b202471c  885) for_each_object_in_pack(p, add_packed_commits, &oids,
97b202471c  932) for_each_packed_object(add_packed_commits, &oids,

config.c
06800238c6 1684) worktree_config = mkpathdup("%s/config.worktree", 
opts->git_dir);
06800238c6 1709) ret += git_config_from_file(fn, worktree_config, data);
8f7c7f5555 2147) int repo_config_set_gently(struct repository *r,
8f7c7f5555 2150) char *path = repo_git_path(r, "config");
8f7c7f5555 2151) int ret = git_config_set_multivar_in_file_gently(path, 
key, value, NULL, 0);
8f7c7f5555 2152) free(path);
8f7c7f5555 2153) return ret;
8f7c7f5555 2156) void repo_config_set(struct repository *r, const char 
*key, const char *value)
8f7c7f5555 2158) if (!repo_config_set_gently(r, key, value))
8f7c7f5555 2159) return;
8f7c7f5555 2160) if (value)
8f7c7f5555 2161) die(_("could not set '%s' to '%s'"), key, value);
8f7c7f5555 2163) die(_("could not unset '%s'"), key);
8f7c7f5555 2166) int repo_config_set_worktree_gently(struct repository *r,
8f7c7f5555 2172) path = get_worktree_config(r);
8f7c7f5555 2173) if (!path)
8f7c7f5555 2174) return CONFIG_INVALID_FILE;
8f7c7f5555 2175) ret = git_config_set_multivar_in_file_gently(path, key, 
value, NULL, 0);
8f7c7f5555 2176) free(path);
8f7c7f5555 2177) return ret;

connect.c
6da1f1a920 1085) strbuf_addch(&request, '\0');
6da1f1a920 1086) strbuf_addf(&request, "%s%c", version_advert->buf, '\0');
6da1f1a920 1103) if (variant == VARIANT_SSH) {
6da1f1a920 1106) argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=%s",
6da1f1a920 1194) push_ssh_options(&detect.args, &detect.env_array, 
VARIANT_SSH,
6da1f1a920 1202) push_ssh_options(&conn->args, &conn->env_array, 
variant, port,
6da1f1a920 1241) conn = git_connect_git(fd, hostandport, path, prog,
6da1f1a920 1285) fill_ssh_args(conn, ssh_host, port, &version_advert,

date.c
acdd37769d  113) die("Timestamp too large for this system: %"PRItime, time);
6943bd42fb  137) gettimeofday(now, NULL);
acdd37769d  245) hide.date = 1;
acdd37769d  926) return DATE_HUMAN;
86177eb5c4  943) if (isatty(1) || pager_in_use())
86177eb5c4  944) format = p;
86177eb5c4  946) format = "default";

diff-no-index.c
963389f6e7 268) if (implicit_no_index)
963389f6e7 269) warning(_("Not a git repository. Use --no-index to "
963389f6e7 271) usage_with_options(diff_no_index_usage, options);
963389f6e7 305) return 1;

diff.c
0eb03c4cd0 4745) width = strtoul(value, &end, 10);
0eb03c4cd0 4746) if (*end == ',')
0eb03c4cd0 4747) name_width = strtoul(end+1, &end, 10);
0eb03c4cd0 4748) if (*end == ',')
0eb03c4cd0 4749) count = strtoul(end+1, &end, 10);
0eb03c4cd0 4750) if (*end)
0eb03c4cd0 4751) return error(_("invalid --stat value: %s"), value);
0eb03c4cd0 4753) } else if (!strcmp(opt->long_name, "stat-width")) {
0eb03c4cd0 4754) width = strtoul(value, &end, 10);
0eb03c4cd0 4755) if (*end)
0eb03c4cd0 4756) return error(_("%s expects a numerical value"),
0eb03c4cd0 4758) } else if (!strcmp(opt->long_name, "stat-name-width")) {
0eb03c4cd0 4759) name_width = strtoul(value, &end, 10);
0eb03c4cd0 4760) if (*end)
0eb03c4cd0 4761) return error(_("%s expects a numerical value"),
0eb03c4cd0 4763) } else if (!strcmp(opt->long_name, "stat-graph-width")) {
0eb03c4cd0 4764) graph_width = strtoul(value, &end, 10);
0eb03c4cd0 4765) if (*end)
0eb03c4cd0 4766) return error(_("%s expects a numerical value"),
0eb03c4cd0 4768) } else if (!strcmp(opt->long_name, "stat-count")) {
0eb03c4cd0 4769) count = strtoul(value, &end, 10);
0eb03c4cd0 4770) if (*end)
0eb03c4cd0 4771) return error(_("%s expects a numerical value"),
b74a81799d 4836) static int diff_opt_diff_filter(const struct option 
*option,
b74a81799d 4839) struct diff_options *opt = option->value;
b74a81799d 4842) BUG_ON_OPT_NEG(unset);
b74a81799d 4873) return error(_("unknown change class '%c' in 
--diff-filter=%s"),
8b70e41773 4889) static int diff_opt_ws_error_highlight(const struct 
option *option,
8b70e41773 4892) struct diff_options *opt = option->value;
8b70e41773 4895) BUG_ON_OPT_NEG(unset);
8b70e41773 4896) if (val < 0)
8b70e41773 4897) return error("unknown value after ws-error-highlight=%.*s",
8b70e41773 4900) return 0;
5866e9ce9a 4903) static int diff_opt_find_object(const struct option 
*option,
5866e9ce9a 4906) struct diff_options *opt = option->value;
5866e9ce9a 4909) BUG_ON_OPT_NEG(unset);
5866e9ce9a 4911) return error(_("unable to resolve '%s'"), arg);
5866e9ce9a 4920) return 0;
b065b66077 4923) static int diff_opt_anchored(const struct option *opt,
b065b66077 4926) struct diff_options *options = opt->value;
b065b66077 4928) BUG_ON_OPT_NEG(unset);
b065b66077 4929) options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
b065b66077 4930) ALLOC_GROW(options->anchors, options->anchors_nr + 1,
b065b66077 4932) options->anchors[options->anchors_nr++] = xstrdup(arg);
b065b66077 4933) return 0;
6d0300b2e3 4936) static int diff_opt_binary(const struct option *opt,
6d0300b2e3 4939) struct diff_options *options = opt->value;
6d0300b2e3 4941) BUG_ON_OPT_NEG(unset);
6d0300b2e3 4942) BUG_ON_OPT_ARG(arg);
6d0300b2e3 4943) enable_patch_output(&options->output_format);
6d0300b2e3 4944) options->flags.binary = 1;
6d0300b2e3 4945) return 0;
b9b760ed1c 4948) static int diff_opt_break_rewrites(const struct option 
*opt,
b9b760ed1c 4951) int *break_opt = opt->value;
b9b760ed1c 4954) BUG_ON_OPT_NEG(unset);
b9b760ed1c 4955) if (!arg)
b9b760ed1c 4956) arg = "";
b9b760ed1c 4957) opt1 = parse_rename_score(&arg);
b9b760ed1c 4958) switch (*arg) {
b9b760ed1c 4960) opt2 = 0;
b9b760ed1c 4961) break;
b9b760ed1c 4963) arg++;
b9b760ed1c 4964) opt2 = parse_rename_score(&arg);
b9b760ed1c 4965) break;
b9b760ed1c 4967) if (*arg != 0)
b9b760ed1c 4968) return error(_("%s expects <n>/<m> form"), opt->long_name);
b9b760ed1c 4969) *break_opt = opt1 | (opt2 << 16);
b9b760ed1c 4970) return 0;
3d810d1860 4973) static int diff_opt_char(const struct option *opt,
3d810d1860 4976) char *value = opt->value;
3d810d1860 4978) BUG_ON_OPT_NEG(unset);
3d810d1860 4979) if (arg[1])
3d810d1860 4980) return error(_("%s expects a character, got '%s'"),
3d810d1860 4982) *value = arg[0];
3d810d1860 4983) return 0;
221d676696 4986) static int diff_opt_color_moved(const struct option *opt,
221d676696 4989) struct diff_options *options = opt->value;
221d676696 4991) if (unset) {
221d676696 4992) options->color_moved = COLOR_MOVED_NO;
221d676696 4993) } else if (!arg) {
221d676696 5004) return 0;
7c33a67a2e 5007) static int diff_opt_color_moved_ws(const struct option 
*opt,
7c33a67a2e 5010) struct diff_options *options = opt->value;
da9db54b3e 5013) if (unset) {
da9db54b3e 5015) return 0;
7c33a67a2e 5018) cm = parse_color_moved_ws(arg);
7c33a67a2e 5019) if (cm & COLOR_MOVED_WS_ERROR)
7c33a67a2e 5020) return error(_("invalid mode '%s' in 
--color-moved-ws"), arg);
7c33a67a2e 5021) options->color_moved_ws_handling = cm;
7c33a67a2e 5022) return 0;
f3b49b7f9e 5025) static int diff_opt_color_words(const struct option *opt,
f3b49b7f9e 5028) struct diff_options *options = opt->value;
f3b49b7f9e 5030) BUG_ON_OPT_NEG(unset);
f3b49b7f9e 5031) options->use_color = 1;
f3b49b7f9e 5032) options->word_diff = DIFF_WORDS_COLOR;
f3b49b7f9e 5033) options->word_regex = arg;
f3b49b7f9e 5034) return 0;
58c7ef398e 5037) static int diff_opt_compact_summary(const struct option 
*opt,
58c7ef398e 5040) struct diff_options *options = opt->value;
58c7ef398e 5042) BUG_ON_OPT_ARG(arg);
58c7ef398e 5043) if (unset) {
58c7ef398e 5044) options->flags.stat_with_summary = 0;
58c7ef398e 5046) options->flags.stat_with_summary = 1;
58c7ef398e 5047) options->output_format |= DIFF_FORMAT_DIFFSTAT;
58c7ef398e 5049) return 0;
1efc2689d6 5052) static int diff_opt_diff_algorithm(const struct option 
*opt,
1efc2689d6 5055) struct diff_options *options = opt->value;
1efc2689d6 5056) long value = parse_algorithm_value(arg);
1efc2689d6 5058) BUG_ON_OPT_NEG(unset);
1efc2689d6 5059) if (value < 0)
1efc2689d6 5060) return error(_("option diff-algorithm accepts \"myers\", "
1efc2689d6 5064) DIFF_XDL_CLR(options, NEED_MINIMAL);
1efc2689d6 5065) options->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK;
1efc2689d6 5066) options->xdl_opts |= value;
1efc2689d6 5067) return 0;
f8d10810d3 5070) static int diff_opt_dirstat(const struct option *opt,
f8d10810d3 5073) struct diff_options *options = opt->value;
f8d10810d3 5075) BUG_ON_OPT_NEG(unset);
f8d10810d3 5076) if (!strcmp(opt->long_name, "cumulative")) {
f8d10810d3 5077) if (arg)
f8d10810d3 5079) arg = "cumulative";
f8d10810d3 5080) } else if (!strcmp(opt->long_name, "dirstat-by-file"))
f8d10810d3 5081) parse_dirstat_opt(options, "files");
f8d10810d3 5082) parse_dirstat_opt(options, arg ? arg : "");
f8d10810d3 5083) return 0;
97e53999cd 5086) static int diff_opt_find_copies(const struct option *opt,
97e53999cd 5089) struct diff_options *options = opt->value;
97e53999cd 5091) BUG_ON_OPT_NEG(unset);
97e53999cd 5092) if (!arg)
97e53999cd 5093) arg = "";
97e53999cd 5094) options->rename_score = parse_rename_score(&arg);
97e53999cd 5095) if (*arg != 0)
97e53999cd 5096) return error(_("invalid argument to %s"), opt->long_name);
97e53999cd 5098) if (options->detect_rename == DIFF_DETECT_COPY)
97e53999cd 5099) options->flags.find_copies_harder = 1;
97e53999cd 5101) options->detect_rename = DIFF_DETECT_COPY;
97e53999cd 5103) return 0;
10e07ecc0c 5116) return error(_("invalid argument to %s"), opt->long_name);
c2dcec4fd2 5122) static int diff_opt_follow(const struct option *opt,
c2dcec4fd2 5125) struct diff_options *options = opt->value;
c2dcec4fd2 5127) BUG_ON_OPT_ARG(arg);
c2dcec4fd2 5128) if (unset) {
c2dcec4fd2 5129) options->flags.follow_renames = 0;
c2dcec4fd2 5130) options->flags.default_follow_renames = 0;
c2dcec4fd2 5132) options->flags.follow_renames = 1;
c2dcec4fd2 5134) return 0;
6c0ec4f728 5150) static int diff_opt_line_prefix(const struct option *opt,
6c0ec4f728 5153) struct diff_options *options = opt->value;
6c0ec4f728 5155) BUG_ON_OPT_NEG(unset);
6c0ec4f728 5156) options->line_prefix = optarg;
6c0ec4f728 5157) options->line_prefix_length = strlen(options->line_prefix);
6c0ec4f728 5158) graph_setup_line_prefix(options);
6c0ec4f728 5159) return 0;
059343267e 5162) static int diff_opt_no_prefix(const struct option *opt,
059343267e 5165) struct diff_options *options = opt->value;
059343267e 5167) BUG_ON_OPT_NEG(unset);
059343267e 5168) BUG_ON_OPT_ARG(optarg);
059343267e 5169) options->a_prefix = "";
059343267e 5170) options->b_prefix = "";
059343267e 5171) return 0;
3d810d1860 5174) static enum parse_opt_result diff_opt_output(struct 
parse_opt_ctx_t *ctx,
3d810d1860 5178) struct diff_options *options = opt->value;
3d810d1860 5181) BUG_ON_OPT_NEG(unset);
3d810d1860 5182) path = prefix_filename(ctx->prefix, arg);
3d810d1860 5183) options->file = xfopen(path, "w");
3d810d1860 5184) options->close_file = 1;
3d810d1860 5185) if (options->use_color != GIT_COLOR_ALWAYS)
3d810d1860 5186) options->use_color = GIT_COLOR_NEVER;
3d810d1860 5187) free(path);
3d810d1860 5188) return 0;
2156b1fd0c 5191) static int diff_opt_patience(const struct option *opt,
2156b1fd0c 5194) struct diff_options *options = opt->value;
2156b1fd0c 5197) BUG_ON_OPT_NEG(unset);
2156b1fd0c 5198) BUG_ON_OPT_ARG(arg);
2156b1fd0c 5199) options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
2156b1fd0c 5205) for (i = 0; i < options->anchors_nr; i++)
2156b1fd0c 5206) free(options->anchors[i]);
2156b1fd0c 5207) options->anchors_nr = 0;
2156b1fd0c 5208) return 0;
d071ebcc8a 5211) static int diff_opt_pickaxe_regex(const struct option *opt,
d071ebcc8a 5214) struct diff_options *options = opt->value;
d071ebcc8a 5216) BUG_ON_OPT_NEG(unset);
d071ebcc8a 5217) options->pickaxe = arg;
d071ebcc8a 5218) options->pickaxe_opts |= DIFF_PICKAXE_KIND_G;
d071ebcc8a 5219) return 0;
d071ebcc8a 5222) static int diff_opt_pickaxe_string(const struct option 
*opt,
d071ebcc8a 5225) struct diff_options *options = opt->value;
d071ebcc8a 5227) BUG_ON_OPT_NEG(unset);
d071ebcc8a 5228) options->pickaxe = arg;
d071ebcc8a 5229) options->pickaxe_opts |= DIFF_PICKAXE_KIND_S;
d071ebcc8a 5230) return 0;
350a71f2fc 5233) static int diff_opt_relative(const struct option *opt,
350a71f2fc 5236) struct diff_options *options = opt->value;
350a71f2fc 5238) BUG_ON_OPT_NEG(unset);
350a71f2fc 5239) options->flags.relative_name = 1;
350a71f2fc 5240) if (arg)
350a71f2fc 5241) options->prefix = arg;
350a71f2fc 5242) return 0;
1d2890f4f5 5245) static int diff_opt_submodule(const struct option *opt,
1d2890f4f5 5248) struct diff_options *options = opt->value;
1d2890f4f5 5250) BUG_ON_OPT_NEG(unset);
1d2890f4f5 5251) if (!arg)
1d2890f4f5 5252) arg = "log";
1d2890f4f5 5253) if (parse_submodule_params(options, arg))
1d2890f4f5 5254) return error(_("failed to parse --submodule option 
parameter: '%s'"),
1d2890f4f5 5256) return 0;
1d85988346 5259) static int diff_opt_textconv(const struct option *opt,
1d85988346 5262) struct diff_options *options = opt->value;
1d85988346 5264) BUG_ON_OPT_ARG(arg);
1d85988346 5265) if (unset) {
1d85988346 5266) options->flags.allow_textconv = 0;
1d85988346 5268) options->flags.allow_textconv = 1;
1d85988346 5269) options->flags.textconv_set_via_cmdline = 1;
1d85988346 5271) return 0;
6643eb7bbf 5284) return error(_("%s expects a numerical value"), 
"--unified");
08d080bf7f 5290) static int diff_opt_word_diff(const struct option *opt,
08d080bf7f 5293) struct diff_options *options = opt->value;
08d080bf7f 5295) BUG_ON_OPT_NEG(unset);
08d080bf7f 5296) if (arg) {
08d080bf7f 5308) return error(_("bad --word-diff argument: %s"), arg);
08d080bf7f 5313) return 0;
afe77a4dd9 5316) static int diff_opt_word_diff_regex(const struct option 
*opt,
afe77a4dd9 5319) struct diff_options *options = opt->value;
afe77a4dd9 5321) BUG_ON_OPT_NEG(unset);
afe77a4dd9 5322) if (options->word_diff == DIFF_WORDS_NONE)
afe77a4dd9 5323) options->word_diff = DIFF_WORDS_PLAIN;
afe77a4dd9 5324) options->word_regex = arg;
afe77a4dd9 5325) return 0;

fsck.c
ef644c4150  252) oidset_parse_file(&options->skiplist, buf + equal + 1);

ident.c
97f56073ce 568) static void set_env_if(const char *key, const char 
*value, int *given, int bit)
97f56073ce 570) if ((*given & bit) || getenv(key))
97f56073ce 571) return; /* nothing to do */
97f56073ce 572) setenv(key, value, 0);
97f56073ce 573) *given |= bit;
97f56073ce 576) void prepare_fallback_ident(const char *name, const char 
*email)
97f56073ce 578) set_env_if("GIT_AUTHOR_NAME", name,
97f56073ce 580) set_env_if("GIT_AUTHOR_EMAIL", email,
97f56073ce 582) set_env_if("GIT_COMMITTER_NAME", name,
97f56073ce 584) set_env_if("GIT_COMMITTER_EMAIL", email,
97f56073ce 586) }

list-objects-filter-options.c
3a7a698e93  74) if (!get_oid_with_context(the_repository, v0, GET_OID_BLOB,

list-objects.c
4f6d26b167 229) static void add_edge_parents(struct commit *commit,
4f6d26b167 236) for (parents = commit->parents; parents; parents = 
parents->next) {
4f6d26b167 237) struct commit *parent = parents->item;
4f6d26b167 238) struct tree *tree = get_commit_tree(parent);
4f6d26b167 240) if (!tree)
4f6d26b167 241) continue;
4f6d26b167 243) oidset_insert(set, &tree->object.oid);
4f6d26b167 245) if (!(parent->object.flags & UNINTERESTING))
4f6d26b167 246) continue;
4f6d26b167 247) tree->object.flags |= UNINTERESTING;
4f6d26b167 249) if (revs->edge_hint && !(parent->object.flags & SHOWN)) {
4f6d26b167 250) parent->object.flags |= SHOWN;
4f6d26b167 251) show_edge(parent);
4f6d26b167 254) }
4f6d26b167 265) oidset_init(&set, 16);
4f6d26b167 267) for (list = revs->commits; list; list = list->next) {
4f6d26b167 268) struct commit *commit = list->item;
4f6d26b167 269) struct tree *tree = get_commit_tree(commit);
4f6d26b167 271) if (commit->object.flags & UNINTERESTING)
4f6d26b167 272) tree->object.flags |= UNINTERESTING;
4f6d26b167 274) oidset_insert(&set, &tree->object.oid);
4f6d26b167 275) add_edge_parents(commit, revs, show_edge, &set);
4f6d26b167 278) mark_trees_uninteresting_sparse(revs->repo, &set);
4f6d26b167 279) oidset_clear(&set);
4f6d26b167 287) commit->object.flags |= SHOWN;
4f6d26b167 288) show_edge(commit);

merge-recursive.c
d7cf3a96e9  149) static struct tree *shift_tree_object(struct repository 
*repo,
d7cf3a96e9  163) return lookup_tree(repo, &shifted);
0d6caa2d08  428) struct index_state *istate = o->repo->index;
0d6caa2d08  430) if (unmerged_index(istate)) {
0d6caa2d08  433) for (i = 0; i < istate->cache_nr; i++) {
0d6caa2d08  434) const struct cache_entry *ce = istate->cache[i];
0d6caa2d08  442) if (!istate->cache_tree)
0d6caa2d08  443) istate->cache_tree = cache_tree();
0d6caa2d08  445) if (!cache_tree_fully_valid(istate->cache_tree) &&
0d6caa2d08  446)     cache_tree_update(istate, 0) < 0) {
d7cf3a96e9  451) result = lookup_tree(o->repo, &istate->cache_tree->oid);
0d6caa2d08  733) ce = index_file_exists(o->repo->index, path, strlen(path),
0d6caa2d08 1116) static int find_first_merges(struct repository *repo,
0d6caa2d08 1137) repo_init_revisions(repo, &revs, NULL);
d7cf3a96e9 1215) if (!(commit_base = lookup_commit_reference(o->repo, 
base)) ||
d7cf3a96e9 1216)     !(commit_a = lookup_commit_reference(o->repo, a)) ||
d7cf3a96e9 1217)     !(commit_b = lookup_commit_reference(o->repo, b))) {
0d6caa2d08 1267) parent_count = find_first_merges(o->repo, &merges, path,
0d6caa2d08 1416) if (!o->call_depth && would_lose_untracked(o, 
dest->path)) {
0d6caa2d08 1455)     (!o->call_depth && would_lose_untracked(o, path))) {
0d6caa2d08 1465) ret = remove_file_from_index(o->repo->index, path);
0d6caa2d08 1541) return remove_file_from_index(o->repo->index, dest->path);
0d6caa2d08 1622)     o->call_depth || would_lose_untracked(o, prev_path1));
0d6caa2d08 1625)     o->call_depth || would_lose_untracked(o, prev_path2));
0d6caa2d08 1732) if (dir_in_way(o->repo->index, path, !o->call_depth, 0)) {
0d6caa2d08 1737) } else if (would_lose_untracked(o, path)) {
0d6caa2d08 1798) remove_file_from_index(o->repo->index, a->path);
0d6caa2d08 1805) remove_file_from_index(o->repo->index, b->path);
0d6caa2d08 3057) if (renormalize_buffer(opt->repo->index, path, o.buf, 
o.len, &o) |
0d6caa2d08 3058)     renormalize_buffer(opt->repo->index, path, a.buf, 
a.len, &a))
0d6caa2d08 3139) if (dir_in_way(o->repo->index, path, !o->call_depth,
0d6caa2d08 3173) pos = index_name_pos(o->repo->index, path, strlen(path));
0d6caa2d08 3174) ce = o->repo->index->cache[pos];
0d6caa2d08 3193) remove_file_from_index(o->repo->index, path);
0d6caa2d08 3364) remove_file_from_index(o->repo->index, path);
d7cf3a96e9 3423) merge = shift_tree_object(o->repo, head, merge, 
o->subtree_shift);
d7cf3a96e9 3424) common = shift_tree_object(o->repo, head, common, 
o->subtree_shift);
d7cf3a96e9 3560) tree = lookup_tree(o->repo, 
o->repo->hash_algo->empty_tree);
d7cf3a96e9 3561) merged_common_ancestors = make_virtual_commit(o->repo, 
tree, "ancestor");
0d6caa2d08 3575) discard_index(o->repo->index);
d7cf3a96e9 3605) *result = make_virtual_commit(o->repo, mrtree, "merged 
tree");

merge.c
e1ff0a32e4  40) if (repo_read_index(r) < 0)

notes-merge.c
1d18d7581c 652) create_notes_commit(o->repo, local_tree, parents, 
o->commit_msg.buf,
1d18d7581c 727) create_notes_commit(o->repo, partial_tree, 
partial_commit->parents, msg,

notes-utils.c
1d18d7581c   8) void create_notes_commit(struct repository *r,
1d18d7581c  25) struct commit *parent = lookup_commit(r, &parent_oid);
1d18d7581c  38) void commit_notes(struct repository *r, struct 
notes_tree *t, const char *msg)
1d18d7581c  54) create_notes_commit(r, t, NULL, buf.buf, buf.len, 
&commit_oid);
1d18d7581c 175) void finish_copy_notes_for_rewrite(struct repository *r,
1d18d7581c 181) commit_notes(r, c->trees[i], msg);

oidset.c
ef644c4150 39) void oidset_parse_file(struct oidset *set, const char *path)
ef644c4150 42) struct strbuf sb = STRBUF_INIT;
ef644c4150 45) fp = fopen(path, "r");
ef644c4150 46) if (!fp)
ef644c4150 47) die("Could not open skip list: %s", path);
ef644c4150 48) while (!strbuf_getline(&sb, fp)) {
ef644c4150 57) hash = strchr(sb.buf, '#');
ef644c4150 58) if (hash)
ef644c4150 59) strbuf_setlen(&sb, hash - sb.buf);
ef644c4150 60) strbuf_trim(&sb);
ef644c4150 61) if (!sb.len)
ef644c4150 62) continue;
ef644c4150 64) if (parse_oid_hex(sb.buf, &oid, &p) || *p != '\0')
ef644c4150 65) die("Invalid SHA-1: %s", sb.buf);
ef644c4150 66) oidset_insert(set, &oid);
ef644c4150 68) if (ferror(fp))
ef644c4150 69) die_errno("Could not read '%s'", path);
ef644c4150 70) fclose(fp);
ef644c4150 71) strbuf_release(&sb);
ef644c4150 72) }

parse-options-cb.c
8fc6b47cd5  26) v = the_hash_algo->hexsz;
08339886b9 173) enum parse_opt_result parse_opt_unknown_cb(struct 
parse_opt_ctx_t *ctx,
9b4ae5190a 177) BUG_ON_OPT_ARG(arg);
08339886b9 178) return PARSE_OPT_UNKNOWN;

parse-options.c
08339886b9  48) static enum parse_opt_result opt_command_mode_error(
08339886b9  74) return PARSE_OPT_ERROR;
9b4ae5190a 183) return (*opt->ll_callback)(p, opt, p_arg, p_unset);
9b4ae5190a 255) rc = (*numopt->ll_callback)(p, numopt, arg, 0);

pretty.c
4681fe38e1 1060) static int match_placeholder_arg_value(const char 
*to_parse, const char *candidate,
4681fe38e1 1067) if (valuestart) {
4681fe38e1 1068) if (*p != '=')
4681fe38e1 1069) return 0;
4681fe38e1 1070) *valuestart = p + 1;
4681fe38e1 1071) *valuelen = strcspn(*valuestart, ",)");
4681fe38e1 1072) p = *valuestart + *valuelen;
4681fe38e1 1085) static int match_placeholder_arg(const char *to_parse, 
const char *candidate,
4681fe38e1 1088) return match_placeholder_arg_value(to_parse, candidate, 
end, NULL, NULL);
b755bf6f83 1091) static int match_placeholder_bool_arg(const char 
*to_parse, const char *candidate,
b755bf6f83 1095) if (!skip_prefix(to_parse, candidate, &p))
b755bf6f83 1096) return 0;
b755bf6f83 1098) if (match_placeholder_arg(p, "=no", end) ||
b755bf6f83 1099)     match_placeholder_arg(p, "=off", end) ||
b755bf6f83 1100)     match_placeholder_arg(p, "=false", end)) {
b755bf6f83 1101) *val = 0;
b755bf6f83 1102) return 1;
b755bf6f83 1105) if (match_placeholder_arg(p, "", end) ||
b755bf6f83 1106)     match_placeholder_arg(p, "=yes", end) ||
b755bf6f83 1107)     match_placeholder_arg(p, "=on", end) ||
b755bf6f83 1108)     match_placeholder_arg(p, "=true", end)) {
b755bf6f83 1109) *val = 1;
b755bf6f83 1110) return 1;
4681fe38e1 1112) return 0;
4681fe38e1 1115) static int format_trailer_match_cb(const struct strbuf 
*key, void *ud)
4681fe38e1 1117) const struct string_list *list = ud;
4681fe38e1 1120) for_each_string_list_item (item, list) {
4681fe38e1 1121) if (key->len == (uintptr_t)item->util &&
4681fe38e1 1122)     !strncasecmp (item->string, key->buf, key->len))
4681fe38e1 1123) return 1;
b755bf6f83 1125) return 0;
18f8e81091 1143) return res;
4681fe38e1 1369) struct string_list filter_list = STRING_LIST_INIT_NODUP;
ced45aab72 1370) struct strbuf sepbuf = STRBUF_INIT;
ffd7cae405 1371) size_t ret = 0;
4681fe38e1 1381) if (match_placeholder_arg_value(arg, "key", &arg, 
&argval, &arglen)) {
4681fe38e1 1382) uintptr_t len = arglen;
4681fe38e1 1383) if (len && argval[len - 1] == ':')
4681fe38e1 1384) len--;
4681fe38e1 1385) string_list_append(&filter_list, argval)->util = (char 
*)len;
4681fe38e1 1387) opts.filter = format_trailer_match_cb;
4681fe38e1 1388) opts.filter_data = &filter_list;
ced45aab72 1390) } else if (match_placeholder_arg_value(arg, 
"separator", &arg, &argval, &arglen)) {
ced45aab72 1393) strbuf_reset(&sepbuf);
ced45aab72 1394) fmt = xstrndup(argval, arglen);
ced45aab72 1395) strbuf_expand(&sepbuf, fmt, strbuf_expand_literal_cb, 
NULL);
ced45aab72 1396) free(fmt);
ced45aab72 1397) opts.separator = &sepbuf;
4681fe38e1 1398) } else if (!match_placeholder_bool_arg(arg, "only", 
&arg, &opts.only_trailers) &&
e9da5de761 1399)    !match_placeholder_bool_arg(arg, "unfold", &arg, 
&opts.unfold) &&
e9da5de761 1400)    !match_placeholder_bool_arg(arg, "valueonly", &arg, 
&opts.value_only))
ffd7cae405 1406) ret = arg - placeholder + 1;
4681fe38e1 1408) string_list_clear (&filter_list, 0);
ced45aab72 1409) strbuf_release(&sepbuf);
ffd7cae405 1410) return ret;

protocol.c
6da1f1a920  31) return protocol_v0_string;
6da1f1a920  33) return protocol_v1_string;
6da1f1a920  37) die(_("Unrecognized protocol version"));
6da1f1a920  39) die(_("Unrecognized protocol_version"));
6da1f1a920  76) return;
6da1f1a920 112) ALLOC_ARRAY(tmp_allowed_versions, tmp_nr);
6da1f1a920 113) copy_array(tmp_allowed_versions, allowed_versions, tmp_nr,
6da1f1a920 122) for (i = 1; i < nr_allowed_versions; i++)
6da1f1a920 123) if (tmp_allowed_versions[i] == config_version) {
6da1f1a920 124) SWAP(tmp_allowed_versions[0],
6da1f1a920 131) strbuf_addf(advert, ":version=%s",
6da1f1a920 132) format_protocol_version(tmp_allowed_versions[i]));

rebase-interactive.c
c27b32f0ec  15) static enum missing_commit_check_level 
get_missing_commit_check_level(void)
c27b32f0ec  19) if (git_config_get_value("rebase.missingcommitscheck", 
&value) ||
c27b32f0ec  20) !strcasecmp("ignore", value))
c27b32f0ec  21) return MISSING_COMMIT_CHECK_IGNORE;
c27b32f0ec  22) if (!strcasecmp("warn", value))
c27b32f0ec  23) return MISSING_COMMIT_CHECK_WARN;
c27b32f0ec  24) if (!strcasecmp("error", value))
c27b32f0ec  25) return MISSING_COMMIT_CHECK_ERROR;
c27b32f0ec  26) warning(_("unrecognized setting %s for option "
c27b32f0ec  28) return MISSING_COMMIT_CHECK_IGNORE;
2dd989a694  31) void append_todo_help(unsigned keep_empty, int 
command_count,
2dd989a694  52) unsigned edit_todo = !(shortrevisions && shortonto);
2dd989a694  54) if (!edit_todo) {
2dd989a694  55) strbuf_addch(buf, '\n');
2dd989a694  56) strbuf_commented_addf(buf, Q_("Rebase %s onto %s (%d 
command)",
e5b1c9d929  90) int edit_todo_list(struct repository *r, struct 
todo_list *todo_list,
e5b1c9d929  95) unsigned initial = shortrevisions && shortonto;
e5b1c9d929  97) if (initial) {
e5b1c9d929  98) todo_list_write_to_file(r, todo_list, todo_file, 
shortrevisions, shortonto,
e5b1c9d929 101) if (copy_file(rebase_path_todo_backup(), todo_file, 0666))
e5b1c9d929 102) return error(_("could not copy '%s' to '%s'."), todo_file,
e5b1c9d929 105) todo_list_parse_insn_buffer(r, todo_list->buf.buf, 
todo_list);
e5b1c9d929 106) todo_list_write_to_file(r, todo_list, todo_file, NULL, 
NULL, -1,
e5b1c9d929 110) if (launch_sequence_editor(todo_file, &new_todo->buf, NULL))
e5b1c9d929 111) return -2;
e5b1c9d929 113) strbuf_stripspace(&new_todo->buf, 1);
e5b1c9d929 114) if (initial && new_todo->buf.len == 0)
e5b1c9d929 115) return -3;
e5b1c9d929 117) if (!initial)
e5b1c9d929 118) todo_list_parse_insn_buffer(r, new_todo->buf.buf, new_todo);
e5b1c9d929 120) return 0;
c27b32f0ec 123) define_commit_slab(commit_seen, unsigned char);
c27b32f0ec 130) int todo_list_check(struct todo_list *old_todo, struct 
todo_list *new_todo)
c27b32f0ec 132) enum missing_commit_check_level check_level = 
get_missing_commit_check_level();
c27b32f0ec 133) struct strbuf missing = STRBUF_INIT;
c27b32f0ec 134) int res = 0, i;
c27b32f0ec 137) init_commit_seen(&commit_seen);
c27b32f0ec 139) if (check_level == MISSING_COMMIT_CHECK_IGNORE)
c27b32f0ec 140) goto leave_check;
c27b32f0ec 143) for (i = 0; i < new_todo->nr; i++) {
c27b32f0ec 144) struct commit *commit = new_todo->items[i].commit;
c27b32f0ec 145) if (commit)
c27b32f0ec 146) *commit_seen_at(&commit_seen, commit) = 1;
c27b32f0ec 150) for (i = old_todo->nr - 1; i >= 0; i--) {
c27b32f0ec 151) struct todo_item *item = old_todo->items + i;
c27b32f0ec 152) struct commit *commit = item->commit;
c27b32f0ec 153) if (commit && !*commit_seen_at(&commit_seen, commit)) {
c27b32f0ec 154) strbuf_addf(&missing, " - %s %.*s\n",
c27b32f0ec 155) find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV),
c27b32f0ec 157)     old_todo->buf.buf + item->arg_offset);
c27b32f0ec 158) *commit_seen_at(&commit_seen, commit) = 1;
c27b32f0ec 163) if (!missing.len)
c27b32f0ec 164) goto leave_check;
c27b32f0ec 166) if (check_level == MISSING_COMMIT_CHECK_ERROR)
c27b32f0ec 167) res = 1;
c27b32f0ec 169) fprintf(stderr,
c27b32f0ec 174) fputs(missing.buf, stderr);
c27b32f0ec 175) strbuf_release(&missing);
c27b32f0ec 177) fprintf(stderr, _("To avoid this message, use \"drop\" to "
c27b32f0ec 184) clear_commit_seen(&commit_seen);
c27b32f0ec 185) return res;

remote-curl.c
6da1f1a920  344) return 0;
34a9469d6a  363) return;
34a9469d6a  373) die("invalid server response; expected service, got 
flush packet");
240fb9b7a0  392) } else if (!strcmp(line, "version 2")) {
34a9469d6a  397) d->proto_git = 1;
e586e7df7c  399) } else if (skip_prefix(line, "ERR ", &p)) {
e586e7df7c  400) die(_("remote error: %s"), p);

repository.c
rerere.c
e1ff0a32e4  598) if (repo_read_index(r) < 0)
3a95f31d1c  708) repo_hold_locked_index(r, &index_lock, LOCK_DIE_ON_ERROR);
e1ff0a32e4 1110) if (repo_read_index(r) < 0)

revision.c
d5d2e93577  109) static int path_and_oids_cmp(const void 
*hashmap_cmp_fn_data,
d5d2e93577  114) return strcmp(e1->path, e2->path);
d5d2e93577  117) static void paths_and_oids_init(struct hashmap *map)
d5d2e93577  119) hashmap_init(map, (hashmap_cmp_fn) path_and_oids_cmp, 
NULL, 0);
d5d2e93577  120) }
d5d2e93577  122) static void paths_and_oids_clear(struct hashmap *map)
d5d2e93577  126) hashmap_iter_init(map, &iter);
d5d2e93577  128) while ((entry = (struct path_and_oids_entry 
*)hashmap_iter_next(&iter))) {
d5d2e93577  129) oidset_clear(&entry->trees);
d5d2e93577  130) free(entry->path);
d5d2e93577  133) hashmap_free(map, 1);
d5d2e93577  134) }
d5d2e93577  136) static void paths_and_oids_insert(struct hashmap *map,
d5d2e93577  140) int hash = strhash(path);
d5d2e93577  144) hashmap_entry_init(&key, hash);
d5d2e93577  147) key.path = (char *)path;
d5d2e93577  148) oidset_init(&key.trees, 0);
d5d2e93577  150) if (!(entry = (struct path_and_oids_entry 
*)hashmap_get(map, &key, NULL))) {
d5d2e93577  151) entry = xcalloc(1, sizeof(struct path_and_oids_entry));
d5d2e93577  152) hashmap_entry_init(entry, hash);
d5d2e93577  153) entry->path = xstrdup(key.path);
d5d2e93577  154) oidset_init(&entry->trees, 16);
d5d2e93577  155) hashmap_put(map, entry);
d5d2e93577  158) oidset_insert(&entry->trees, oid);
d5d2e93577  159) }
d5d2e93577  161) static void add_children_by_path(struct repository *r,
d5d2e93577  168) if (!tree)
d5d2e93577  169) return;
d5d2e93577  171) if (parse_tree_gently(tree, 1) < 0)
d5d2e93577  172) return;
d5d2e93577  174) init_tree_desc(&desc, tree->buffer, tree->size);
d5d2e93577  175) while (tree_entry(&desc, &entry)) {
d5d2e93577  176) switch (object_type(entry.mode)) {
5dde8fc6df  178) paths_and_oids_insert(map, entry.path, &entry.oid);
d5d2e93577  180) if (tree->object.flags & UNINTERESTING) {
5dde8fc6df  181) struct tree *child = lookup_tree(r, &entry.oid);
d5d2e93577  182) if (child)
d5d2e93577  183) child->object.flags |= UNINTERESTING;
d5d2e93577  185) break;
d5d2e93577  187) if (tree->object.flags & UNINTERESTING) {
5dde8fc6df  188) struct blob *child = lookup_blob(r, &entry.oid);
d5d2e93577  189) if (child)
d5d2e93577  190) child->object.flags |= UNINTERESTING;
d5d2e93577  192) break;
d5d2e93577  195) break;
d5d2e93577  199) free_tree_buffer(tree);
f1f5de442f  202) void mark_trees_uninteresting_sparse(struct repository *r,
d5d2e93577  205) unsigned has_interesting = 0, has_uninteresting = 0;
f1f5de442f  212) oidset_iter_init(trees, &iter);
d5d2e93577  213) while ((!has_interesting || !has_uninteresting) &&
f1f5de442f  215) struct tree *tree = lookup_tree(r, oid);
f1f5de442f  217) if (!tree)
f1f5de442f  218) continue;
d5d2e93577  220) if (tree->object.flags & UNINTERESTING)
d5d2e93577  221) has_uninteresting = 1;
d5d2e93577  223) has_interesting = 1;
d5d2e93577  227) if (!has_uninteresting || !has_interesting)
d5d2e93577  228) return;
d5d2e93577  230) paths_and_oids_init(&map);
d5d2e93577  232) oidset_iter_init(trees, &iter);
d5d2e93577  233) while ((oid = oidset_iter_next(&iter))) {
d5d2e93577  234) struct tree *tree = lookup_tree(r, oid);
d5d2e93577  235) add_children_by_path(r, tree, &map);
d5d2e93577  238) hashmap_iter_init(&map, &map_iter);
d5d2e93577  239) while ((entry = hashmap_iter_next(&map_iter)))
d5d2e93577  240) mark_trees_uninteresting_sparse(r, &entry->trees);
d5d2e93577  242) paths_and_oids_clear(&map);
e1ff0a32e4 1690) repo_read_index(revs->repo);
3a7a698e93 1749) if (get_oid_with_context(revs->repo, a_name, oc_flags, 
&a_oid, a_oc) ||
3a7a698e93 1750)     get_oid_with_context(revs->repo, b_name, oc_flags, 
&b_oid, b_oc))

sequencer.c
e5b1c9d929   58) GIT_PATH_FUNC(rebase_path_todo_backup, 
"rebase-merge/git-rebase-todo.backup")
e1ff0a32e4  449) static int error_dirty_index(struct repository *repo, 
struct replay_opts *opts)
e1ff0a32e4  451) if (repo_read_index_unmerged(repo))
e1ff0a32e4  486) repo_read_index(r);
1d18d7581c 1118) void commit_post_rewrite(struct repository *r,
1d18d7581c 1128) finish_copy_notes_for_rewrite(r, cfg, "Notes added by 
'git commit --amend'");
1d18d7581c 1409) commit_post_rewrite(r, current_head, oid);
e1ff0a32e4 1745) return error_dirty_index(r, opts);
5d94d54564 1996) void todo_list_release(struct todo_list *todo_list)
d836079ec2 2024) item->arg_offset = bol - buf;
d836079ec2 2051) item->arg_offset = bol - buf;
d836079ec2 2063) item->arg_offset = bol - buf;
d836079ec2 2077) item->arg_offset = bol - buf;
d836079ec2 2089) bol = end_of_object_name + strspn(end_of_object_name, " 
\t");
d836079ec2 2090) item->arg_offset = bol - buf;
d836079ec2 2091) item->arg_len = (int)(eol - bol);
5d94d54564 2100) int todo_list_parse_insn_buffer(struct repository *r, 
char *buf,
2b71595d47 2107) todo_list->current = todo_list->nr = 0;
d836079ec2 2119) if (parse_insn_line(r, item, buf, p, eol)) {
2b71595d47 2122) item->command = TODO_COMMENT + 1;
d836079ec2 2123) item->arg_offset = p - buf;
2b71595d47 2124) item->arg_len = (int)(eol - p);
2b71595d47 2125) item->commit = NULL;
5d94d54564 2200) res = todo_list_parse_insn_buffer(r, 
todo_list->buf.buf, todo_list);
5d94d54564 2231)     !todo_list_parse_insn_buffer(r, done.buf.buf, &done))
d836079ec2 2468) item->arg_offset = 0;
e1ff0a32e4 2829) if (discard_index(r->index) < 0 || repo_read_index(r) < 0)
3a95f31d1c 2953) if (repo_hold_locked_index(r, &lock, 
LOCK_REPORT_ON_ERROR) < 0)
e1ff0a32e4 2998) if (repo_read_index_unmerged(r)) {
3a95f31d1c 3071) if (repo_hold_locked_index(r, &lock, 
LOCK_REPORT_ON_ERROR) < 0) {
e1ff0a32e4 3252)      repo_read_index(r) < 0))
e1ff0a32e4 3274) repo_read_index(r);
0d6caa2d08 3275) init_merge_options(&o, r);
d836079ec2 3507) const char *arg = todo_list->buf.buf + item->arg_offset;
d836079ec2 3595) char *end_of_arg = (char *)(arg + item->arg_len);
d836079ec2 3600) res = do_exec(r, arg);
d836079ec2 3618) if ((res = do_label(r, arg, item->arg_len)))
d836079ec2 3621) if ((res = do_reset(r, arg, item->arg_len, opts)))
e1ff0a32e4 3950) res = error_dirty_index(r, opts);
0566a4f68e 4372) strbuf_addf(out, "%s onto\n", cmd_label);
0566a4f68e 4382) strbuf_addf(out, "\n%c Branch %s\n", comment_line_char, 
entry->string);
0566a4f68e 4384) strbuf_addch(out, '\n');
0566a4f68e 4397) strbuf_addf(out, "%s %s\n", cmd_reset,
0566a4f68e 4411) strbuf_addf(out, "%s onto\n", cmd_reset);
0566a4f68e 4415) strbuf_addf(out, "%s %s # %s\n",
0566a4f68e 4425) strbuf_addf(out, "%s\n", entry->string);
0566a4f68e 4428) strbuf_addf(out, "%s %s\n",
0566a4f68e 4429)     cmd_label, entry->string);
0566a4f68e 4451) int sequencer_make_script(struct repository *r, struct 
strbuf *out, int argc,
0566a4f68e 4499) strbuf_addf(out, "%c ", comment_line_char);
0566a4f68e 4500) strbuf_addf(out, "%s %s ", insn,
0566a4f68e 4502) pretty_print_commit(&pp, commit, out);
0566a4f68e 4503) strbuf_addch(out, '\n');
8414c890aa 4508) static void todo_list_add_exec_commands(struct 
todo_list *todo_list,
8414c890aa 4511) struct strbuf *buf = &todo_list->buf;
8414c890aa 4512) size_t base_offset = buf->len;
8414c890aa 4513) int i, insert, nr = 0, alloc = 0;
8414c890aa 4514) struct todo_item *items = NULL, *base_items = NULL;
8414c890aa 4516) base_items = xcalloc(commands->nr, sizeof(struct 
todo_item));
8414c890aa 4517) for (i = 0; i < commands->nr; ++i) {
8414c890aa 4518) size_t command_len = strlen(commands->items[i].string);
8414c890aa 4520) strbuf_addstr(buf, commands->items[i].string);
8414c890aa 4521) strbuf_addch(buf, '\n');
8414c890aa 4523) base_items[i].command = TODO_EXEC;
8414c890aa 4524) base_items[i].offset_in_buf = base_offset;
8414c890aa 4525) base_items[i].arg_offset = base_offset + strlen("exec ");
8414c890aa 4526) base_items[i].arg_len = command_len - strlen("exec ");
8414c890aa 4528) base_offset += command_len + 1;
8414c890aa 4537) for (i = 0; i < todo_list->nr; i++) {
8414c890aa 4538) enum todo_command command = todo_list->items[i].command;
8414c890aa 4539) if (insert >= 0 && command != TODO_COMMENT && 
!is_fixup(command)) {
8414c890aa 4540) ALLOC_GROW(items, nr + commands->nr, alloc);
8414c890aa 4541) COPY_ARRAY(items + nr, base_items, commands->nr);
8414c890aa 4542) nr += commands->nr;
8414c890aa 4546) ALLOC_GROW(items, nr + 1, alloc);
8414c890aa 4547) items[nr++] = todo_list->items[i];
8414c890aa 4549) if (command == TODO_PICK || command == TODO_MERGE || 
is_fixup(command))
8414c890aa 4554) if (insert >= 0 || nr == todo_list->nr) {
8414c890aa 4555) ALLOC_GROW(items, nr + commands->nr, alloc);
8414c890aa 4556) COPY_ARRAY(items + nr, base_items, commands->nr);
8414c890aa 4557) nr += commands->nr;
8414c890aa 4560) free(base_items);
8414c890aa 4561) FREE_AND_NULL(todo_list->items);
8414c890aa 4562) todo_list->items = items;
8414c890aa 4563) todo_list->nr = nr;
8414c890aa 4564) todo_list->alloc = alloc;
8414c890aa 4571) int sequencer_add_exec_commands(struct repository *r,
8414c890aa 4579) return error_errno(_("could not read '%s'."), todo_file);
8414c890aa 4581) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, 
&todo_list)) {
8414c890aa 4586) todo_list_add_exec_commands(&todo_list, commands);
8414c890aa 4587) res = todo_list_write_to_file(r, &todo_list, todo_file, 
NULL, NULL, -1, 0);
0cce4a2756 4588) todo_list_release(&todo_list);
8414c890aa 4590) if (res)
8414c890aa 4591) return error_errno(_("could not write '%s'."), todo_file);
8414c890aa 4592) return 0;
cf18b3f6c9 4595) static void todo_list_to_strbuf(struct repository *r, 
struct todo_list *todo_list,
cf18b3f6c9 4599) int i, max = todo_list->nr;
cf18b3f6c9 4601) if (num > 0 && num < max)
cf18b3f6c9 4602) max = num;
cf18b3f6c9 4604) for (item = todo_list->items, i = 0; i < max; i++, 
item++) {
cf18b3f6c9 4607) strbuf_addf(buf, "%.*s\n", item->arg_len,
3ebafef416 4608)     todo_list->buf.buf + item->arg_offset);
cf18b3f6c9 4614) strbuf_addch(buf, command_to_char(item->command));
cf18b3f6c9 4616) strbuf_addstr(buf, command_to_string(item->command));
cf18b3f6c9 4626) strbuf_addstr(buf, " -c");
cf18b3f6c9 4628) strbuf_addstr(buf, " -C");
cf18b3f6c9 4631) strbuf_addf(buf, " %s", oid);
cf18b3f6c9 4636) strbuf_addch(buf, '\n');
cf18b3f6c9 4638) strbuf_addf(buf, " %.*s\n", item->arg_len,
3ebafef416 4639)     todo_list->buf.buf + item->arg_offset);
cf18b3f6c9 4643) int todo_list_write_to_file(struct repository *r, 
struct todo_list *todo_list,
cf18b3f6c9 4648) struct strbuf buf = STRBUF_INIT;
cf18b3f6c9 4650) todo_list_to_strbuf(r, todo_list, &buf, num, flags);
2dd989a694 4651) if (flags & TODO_LIST_APPEND_TODO_HELP)
2dd989a694 4652) append_todo_help(flags & TODO_LIST_KEEP_EMPTY, 
count_commands(todo_list),
cf18b3f6c9 4655) res = write_message(buf.buf, buf.len, file, 0);
3ebafef416 4656) strbuf_release(&buf);
cf18b3f6c9 4658) return res;
c27b32f0ec 4667) int check_todo_list_from_file(struct repository *r)
c27b32f0ec 4669) struct todo_list old_todo = TODO_LIST_INIT, new_todo = 
TODO_LIST_INIT;
c27b32f0ec 4670) int res = 0;
c27b32f0ec 4672) if (strbuf_read_file_or_whine(&new_todo.buf, 
rebase_path_todo()) < 0) {
878056005e 4673) res = -1;
c27b32f0ec 4674) goto out;
c27b32f0ec 4677) if (strbuf_read_file_or_whine(&old_todo.buf, 
rebase_path_todo_backup()) < 0) {
c27b32f0ec 4679) goto out;
c27b32f0ec 4682) res = todo_list_parse_insn_buffer(r, old_todo.buf.buf, 
&old_todo);
c27b32f0ec 4683) if (!res)
c27b32f0ec 4684) res = todo_list_parse_insn_buffer(r, new_todo.buf.buf, 
&new_todo);
c27b32f0ec 4685) if (!res)
c27b32f0ec 4686) res = todo_list_check(&old_todo, &new_todo);
c27b32f0ec 4687) if (res)
c27b32f0ec 4688) fprintf(stderr, _(edit_todo_list_advice));
c27b32f0ec 4690) todo_list_release(&old_todo);
c27b32f0ec 4691) todo_list_release(&new_todo);
98b29e0607 4697) static int skip_unnecessary_picks(struct repository *r,
98b29e0607 4704) for (i = 0; i < todo_list->nr; i++) {
98b29e0607 4705) struct todo_item *item = todo_list->items + i;
98b29e0607 4727) if (todo_list_write_to_file(r, todo_list, done_path, 
NULL, NULL, i, 0)) {
98b29e0607 4732) MOVE_ARRAY(todo_list->items, todo_list->items + i, 
todo_list->nr - i);
98b29e0607 4733) todo_list->nr -= i;
98b29e0607 4734) todo_list->current = 0;
98b29e0607 4736) if (is_fixup(peek_command(todo_list, 0)))
98b29e0607 4737) record_in_rewritten(output_oid, peek_command(todo_list, 
0));
c1c074e0cc 4751) struct todo_list new_todo = TODO_LIST_INIT;
c1c074e0cc 4752) struct strbuf *buf = &todo_list->buf;
c1c074e0cc 4759) if (buf->len == 0) {
c1c074e0cc 4760) struct todo_item *item = append_new_todo(todo_list);
c1c074e0cc 4761) item->command = TODO_NOOP;
c1c074e0cc 4762) item->commit = NULL;
c1c074e0cc 4763) item->arg_len = item->arg_offset = item->flags = 
item->offset_in_buf = 0;
c1c074e0cc 4766) if (autosquash && todo_list_rearrange_squash(todo_list))
8414c890aa 4769) if (commands->nr)
c1c074e0cc 4770) todo_list_add_exec_commands(todo_list, commands);
c1c074e0cc 4772) if (count_commands(todo_list) == 0) {
33bc1844f7 4779) res = edit_todo_list(r, todo_list, &new_todo, 
shortrevisions,
33bc1844f7 4781) if (res == -1)
33bc1844f7 4783) else if (res == -2) {
33bc1844f7 4788) } else if (res == -3) {
c1c074e0cc 4791) todo_list_release(&new_todo);
c1c074e0cc 4796) if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, 
&new_todo) ||
c1c074e0cc 4797)     todo_list_check(todo_list, &new_todo)) {
c1c074e0cc 4798) fprintf(stderr, _(edit_todo_list_advice));
c1c074e0cc 4800) todo_list_release(&new_todo);
98b29e0607 4805) if (opts->allow_ff && skip_unnecessary_picks(r, 
&new_todo, &oid)) {
98b29e0607 4806) todo_list_release(&new_todo);
c1c074e0cc 4810) if (todo_list_write_to_file(r, &new_todo, todo_file, 
NULL, NULL, -1,
c1c074e0cc 4812) todo_list_release(&new_todo);
c1c074e0cc 4813) return error_errno(_("could not write '%s'"), todo_file);
c1c074e0cc 4816) todo_list_release(&new_todo);
febebd99b6 4851) static int todo_list_rearrange_squash(struct todo_list 
*todo_list)
febebd99b6 4854) int rearranged = 0, *next, *tail, i, nr = 0, alloc = 0;
febebd99b6 4857) struct todo_item *items = NULL;
febebd99b6 4870)      NULL, todo_list->nr);
febebd99b6 4871) ALLOC_ARRAY(next, todo_list->nr);
febebd99b6 4872) ALLOC_ARRAY(tail, todo_list->nr);
febebd99b6 4873) ALLOC_ARRAY(subjects, todo_list->nr);
febebd99b6 4874) for (i = 0; i < todo_list->nr; i++) {
febebd99b6 4876) struct todo_item *item = todo_list->items + i;
febebd99b6 4923) - todo_list->items;
febebd99b6 4936) todo_list->items[i].command =
febebd99b6 4954) for (i = 0; i < todo_list->nr; i++) {
febebd99b6 4955) enum todo_command command = todo_list->items[i].command;
febebd99b6 4966) ALLOC_GROW(items, nr + 1, alloc);
febebd99b6 4967) items[nr++] = todo_list->items[cur];
febebd99b6 4972) FREE_AND_NULL(todo_list->items);
febebd99b6 4973) todo_list->items = items;
febebd99b6 4974) todo_list->nr = nr;
febebd99b6 4975) todo_list->alloc = alloc;
febebd99b6 4980) for (i = 0; i < todo_list->nr; i++)
febebd99b6 4987) return 0;
febebd99b6 4990) int rearrange_squash_in_todo_file(struct repository *r)
febebd99b6 4992) const char *todo_file = rebase_path_todo();
febebd99b6 4993) struct todo_list todo_list = TODO_LIST_INIT;
febebd99b6 4994) int res = 0;
febebd99b6 4996) if (strbuf_read_file_or_whine(&todo_list.buf, 
todo_file) < 0)
febebd99b6 4997) return -1;
febebd99b6 4998) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, 
&todo_list) < 0) {
febebd99b6 4999) todo_list_release(&todo_list);
febebd99b6 5000) return -1;
febebd99b6 5003) res = todo_list_rearrange_squash(&todo_list);
febebd99b6 5004) if (!res)
febebd99b6 5005) res = todo_list_write_to_file(r, &todo_list, todo_file, 
NULL, NULL, -1, 0);
febebd99b6 5007) todo_list_release(&todo_list);
febebd99b6 5009) if (res)
febebd99b6 5010) return error_errno(_("could not write '%s'."), todo_file);
febebd99b6 5011) return 0;

sha1-name.c
4e763fae87 sha1-name.c 1523) int get_oidf(struct object_id *oid, const 
char *fmt, ...)
4e763fae87 sha1-name.c 1527) struct strbuf sb = STRBUF_INIT;
4e763fae87 sha1-name.c 1529) va_start(ap, fmt);
4e763fae87 sha1-name.c 1530) strbuf_vaddf(&sb, fmt, ap);
4e763fae87 sha1-name.c 1531) va_end(ap);
4e763fae87 sha1-name.c 1533) ret = get_oid(sb.buf, oid);
4e763fae87 sha1-name.c 1534) strbuf_release(&sb);
4e763fae87 sha1-name.c 1536) return ret;
3a7a698e93 sha1-name.c 1624) static void 
diagnose_invalid_index_path(struct index_state *istate,
3a7a698e93 sha1-name.c 1638) pos = index_name_pos(istate, filename, 
namelen);
3a7a698e93 sha1-name.c 1641) if (pos < istate->cache_nr) {
3a7a698e93 sha1-name.c 1642) ce = istate->cache[pos];
3a7a698e93 sha1-name.c 1654) pos = index_name_pos(istate, fullname.buf, 
fullname.len);
3a7a698e93 sha1-name.c 1657) if (pos < istate->cache_nr) {
3a7a698e93 sha1-name.c 1658) ce = istate->cache[pos];
3a7a698e93 sha1-name.c 1771) diagnose_invalid_index_path(repo->index, 
stage, prefix, cp);

strbuf.c
bfc3fe33f6  252) void strbuf_vinsertf(struct strbuf *sb, size_t pos, 
const char *fmt, va_list ap)
bfc3fe33f6  258) if (pos > sb->len)
bfc3fe33f6  259) die("`pos' is too far after the end of the buffer");
bfc3fe33f6  260) va_copy(cp, ap);
bfc3fe33f6  261) len = vsnprintf(sb->buf + sb->len, 0, fmt, cp);
bfc3fe33f6  262) va_end(cp);
bfc3fe33f6  263) if (len < 0)
bfc3fe33f6  265) if (!len)
bfc3fe33f6  266) return; /* nothing to do */
bfc3fe33f6  267) if (unsigned_add_overflows(sb->len, len))
bfc3fe33f6  268) die("you want to use way too much memory");
bfc3fe33f6  269) strbuf_grow(sb, len);
bfc3fe33f6  270) memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos);
bfc3fe33f6  272) save = sb->buf[pos + len];
bfc3fe33f6  273) len2 = vsnprintf(sb->buf + pos, sb->alloc - sb->len, 
fmt, ap);
bfc3fe33f6  274) sb->buf[pos + len] = save;
bfc3fe33f6  275) if (len2 != len)
bfc3fe33f6  277) strbuf_setlen(sb, sb->len + len);
bfc3fe33f6  280) void strbuf_insertf(struct strbuf *sb, size_t pos, 
const char *fmt, ...)
bfc3fe33f6  283) va_start(ap, fmt);
bfc3fe33f6  284) strbuf_vinsertf(sb, pos, fmt, ap);
bfc3fe33f6  285) va_end(ap);
bfc3fe33f6  286) }
0c1599c33c  307) const char *strbuf_join_argv(struct strbuf *buf,
0c1599c33c  310) if (!argc)
0c1599c33c  311) return buf->buf;
0c1599c33c  313) strbuf_addstr(buf, *argv);
0c1599c33c  314) while (--argc) {
0c1599c33c  315) strbuf_addch(buf, delim);
0c1599c33c  316) strbuf_addstr(buf, *(++argv));
0c1599c33c  319) return buf->buf;
18f8e81091  442) strbuf_addch(sb, '\n');
18f8e81091  443) return 1;
18f8e81091  446) ch = hex2chr(placeholder + 1);
18f8e81091  447) if (ch < 0)
18f8e81091  448) return 0;
18f8e81091  449) strbuf_addch(sb, ch);
18f8e81091  450) return 3;

trailer.c
ced45aab72 1132) size_t origlen = out->len;
ced45aab72 1136) if (!opts->only_trailers && !opts->unfold && 
!opts->filter && !opts->separator) {
4681fe38e1 1151) if (!opts->filter || opts->filter(&tok, 
opts->filter_data)) {
4681fe38e1 1152) if (opts->unfold)
4681fe38e1 1153) unfold_value(&val);
ced45aab72 1155) if (opts->separator && out->len != origlen)
ced45aab72 1156) strbuf_addbuf(out, opts->separator);
e9da5de761 1157) if (!opts->value_only)
e9da5de761 1158) strbuf_addf(out, "%s: ", tok.buf);
e9da5de761 1159) strbuf_addbuf(out, &val);
ced45aab72 1160) if (!opts->separator)
ced45aab72 1161) strbuf_addch(out, '\n');
ced45aab72 1167) if (opts->separator && out->len != origlen) {
ced45aab72 1168) strbuf_addbuf(out, opts->separator);
ced45aab72 1171) if (opts->separator) {
ced45aab72 1172) strbuf_rtrim(out);

worktree.c
2ec5633ff4 587) char *get_worktree_config(struct repository *r)
2ec5633ff4 589) struct worktree **worktrees = get_worktrees(0);
2ec5633ff4 592) if (repository_format_worktree_config)
2ec5633ff4 593) path = repo_git_path(r, "config.worktree");
2ec5633ff4 594) else if (worktrees[0] && worktrees[1])
2ec5633ff4 595) path = NULL;
2ec5633ff4 597) path = repo_git_path(r, "config");
2ec5633ff4 599) free_worktrees(worktrees);
2ec5633ff4 600) return path;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

wt-status.c
3a95f31d1c 2378) fd = repo_hold_locked_index(r, &lock_file, 0);
1b0d968b34 2381) repo_update_index_if_able(r, &lock_file);

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      97b202471: commit-graph write: use pack 
order when finding commits
Alban Gruin      0566a4f68: sequencer: make sequencer_make_script() 
write its script to a strbuf
Alban Gruin      2b71595d4: sequencer: changes in parse_insn_buffer()
Alban Gruin      2dd989a69: rebase-interactive: append_todo_help() changes
Alban Gruin      33bc1844f: sequencer: use edit_todo_list() in 
complete_action()
Alban Gruin      3ebafef41: sequencer: refactor transform_todos() to 
work on a todo_list
Alban Gruin      4d55dfd76: rebase-interactive: move 
transform_todo_file() to rebase--interactive.c
Alban Gruin      5d94d5456: sequencer: make the todo_list structure public
Alban Gruin      8414c890a: sequencer: refactor 
sequencer_add_exec_commands() to work on a todo_list
Alban Gruin      98b29e060: sequencer: refactor skip_unnecessary_picks() 
to work on a todo_list
Alban Gruin      c1c074e0c: sequencer: change complete_action() to use 
the refactored functions
Alban Gruin      c27b32f0e: sequencer: refactor check_todo_list() to 
work on a todo_list
Alban Gruin      cf18b3f6c: sequencer: introduce todo_list_write_to_file()
Alban Gruin      d836079ec: sequencer: remove the 'arg' field from todo_item
Alban Gruin      e5b1c9d92: rebase-interactive: rewrite edit_todo_list() 
to handle the initial edit
Alban Gruin      febebd99b: sequencer: refactor rearrange_squash() to 
work on a todo_list
Anders Waldenborg      18f8e8109: strbuf: separate callback for 
strbuf_expand:ing literals
Anders Waldenborg      4681fe38e: pretty: allow showing specific trailers
Anders Waldenborg      b755bf6f8: pretty: allow %(trailers) options with 
explicit value
Anders Waldenborg      ced45aab7: pretty: add support for separator 
option in %(trailers)
Anders Waldenborg      e9da5de76: pretty: add support for "valueonly" 
option in %(trailers)
Anders Waldenborg      ffd7cae40: pretty: single return path in 
%(trailers) handling
Barret Rhoden      07d04b919: blame: add a config option to mark ignored 
lines
Barret Rhoden      e7973c851: blame: add the ability to ignore commits 
and their changes
Barret Rhoden      ef644c415: Move init_skiplist() outside of fsck
Derrick Stolee      3d036eb0d: pack-objects: create pack.useSparse setting
Derrick Stolee      4f6d26b16: list-objects: consume sparse tree walk
Derrick Stolee      d5d2e9357: revision: implement sparse algorithm
Derrick Stolee      f1f5de442: revision: add mark_tree_uninteresting_sparse
Jeff King      240fb9b7a: remote-curl: tighten "version 2" check for 
smart-http
Jeff King      34a9469d6: remote-curl: refactor smart-http discovery
Jiang Xin      a338d1039: pack-redundant: consistent sort method
Jiang Xin      cb7e0336f: pack-redundant: rename pack_list.all_objects
Joel Teichroeb      cdca49bc4: stash: convert drop and clear to builtin
Joel Teichroeb      e1d01876a: stash: convert pop to builtin
Joel Teichroeb      f596f3366: stash: convert branch to builtin
Joel Teichroeb      f6bbd7812: stash: convert apply to builtin
Johannes Schindelin      26799a208: stash: optionally use the scripted 
version again
Johannes Schindelin      97f56073c: ident: add the ability to provide a 
"fallback identity"
Johannes Schindelin      bec65d5b7: tests: add a special setup where 
stash.useBuiltin is off
Josh Steadmon      6da1f1a92: protocol: advertise multiple supported 
versions
Josh Steadmon      e586e7df7: remote-curl: die on server-side errors
Junio C Hamano      5dde8fc6d: Merge branch 'ds/push-sparse-tree-walk' 
into pu
Junio C Hamano      b6b4172bf: Merge branch 'nd/the-index-final' into pu
Liam Beguin      0cce4a275: rebase -i -x: add exec commands via the 
rebase--helper
Linus Torvalds      acdd37769: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Matthew Kraai      ed5d77f7d: stash: fix segmentation fault when files 
were added with intent
Nguyễn Thái Ngọc Duy      059343267: diff.c: convert --no-prefix
Nguyễn Thái Ngọc Duy      06800238c: config.c: avoid git_path() in 
do_git_config_sequence()
Nguyễn Thái Ngọc Duy      08339886b: parse-options: avoid magic return codes
Nguyễn Thái Ngọc Duy      08d080bf7: diff.c: convert --word-diff
Nguyễn Thái Ngọc Duy      0d6caa2d0: merge-recursive.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      0eb03c4cd: diff.c: convert --stat*
Nguyễn Thái Ngọc Duy      10e07ecc0: diff.c: convert -M|--find-renames
Nguyễn Thái Ngọc Duy      150fe065f: read-cache.c: remove the_* from 
index_has_changes()
Nguyễn Thái Ngọc Duy      1b0d968b3: read-cache.c: replace 
update_index_if_able with repo_&
Nguyễn Thái Ngọc Duy      1d18d7581: notes-utils.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      1d2890f4f: diff.c: convert --submodule
Nguyễn Thái Ngọc Duy      1d8598834: diff.c: convert --textconv
Nguyễn Thái Ngọc Duy      1efc2689d: diff.c: convert --diff-algorithm
Nguyễn Thái Ngọc Duy      2156b1fd0: diff.c: convert --patience
Nguyễn Thái Ngọc Duy      221d67669: diff.c: convert --color-moved
Nguyễn Thái Ngọc Duy      26c50430d: range-diff: use parse_options() 
instead of diff_opt_parse()
Nguyễn Thái Ngọc Duy      2ec5633ff: worktree.c: add get_worktree_config()
Nguyễn Thái Ngọc Duy      350a71f2f: diff.c: convert --relative
Nguyễn Thái Ngọc Duy      3a7a698e9: sha1-name.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      3a95f31d1: repository.c: replace 
hold_locked_index() with repo_hold_locked_index()
Nguyễn Thái Ngọc Duy      3d810d186: diff.c: convert --output-*
Nguyễn Thái Ngọc Duy      447867144: cache.h: flip 
NO_THE_INDEX_COMPATIBILITY_MACROS switch
Nguyễn Thái Ngọc Duy      5866e9ce9: diff.c: convert --find-object
Nguyễn Thái Ngọc Duy      58c7ef398: diff.c: convert --[no-]compact-summary
Nguyễn Thái Ngọc Duy      6643eb7bb: diff.c: convert -U|--unified
Nguyễn Thái Ngọc Duy      6c0ec4f72: diff.c: convert --line-prefix
Nguyễn Thái Ngọc Duy      6d0300b2e: diff.c: convert --binary
Nguyễn Thái Ngọc Duy      6f11fd5ed: config: add --move-to
Nguyễn Thái Ngọc Duy      7c33a67a2: diff.c: convert --color-moved-ws
Nguyễn Thái Ngọc Duy      8b70e4177: diff.c: convert --ws-error-highlight
Nguyễn Thái Ngọc Duy      8f7c7f555: config.c: add 
repo_config_set_worktree_gently()
Nguyễn Thái Ngọc Duy      8fc6b47cd: diff.c: convert --[no-]abbrev
Nguyễn Thái Ngọc Duy      963389f6e: diff --no-index: use 
parse_options() instead of diff_opt_parse()
Nguyễn Thái Ngọc Duy      97e53999c: diff.c: convert -C|--find-copies
Nguyễn Thái Ngọc Duy      9b4ae5190: parse-options: allow ll_callback 
with OPTION_CALLBACK
Nguyễn Thái Ngọc Duy      a12c1ff3a: config: factor out 
set_config_source_file()
Nguyễn Thái Ngọc Duy      afe77a4dd: diff.c: convert --word-diff-regex
Nguyễn Thái Ngọc Duy      b065b6607: diff.c: convert --anchored
Nguyễn Thái Ngọc Duy      b74a81799: diff.c: convert --diff-filter
Nguyễn Thái Ngọc Duy      b9b760ed1: diff.c: convert -B|--break-rewrites
Nguyễn Thái Ngọc Duy      c2dcec4fd: diff.c: convert --[no-]follow
Nguyễn Thái Ngọc Duy      d071ebcc8: diff.c: convert -S|-G
Nguyễn Thái Ngọc Duy      d7cf3a96e: merge-recursive.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      da9db54b3: diff.c: allow --no-color-moved-ws
Nguyễn Thái Ngọc Duy      dba093ddc: grep: use grep_opt->repo instead of 
explict repo argument
Nguyễn Thái Ngọc Duy      e1ff0a32e: read-cache.c: kill read_index()
Nguyễn Thái Ngọc Duy      f3b49b7f9: diff.c: convert --color-words
Nguyễn Thái Ngọc Duy      f8d10810d: diff.c: convert --dirstat and friends
Paul-Sebastian Ungureanu      0c1599c33: strbuf.c: add `strbuf_join_argv()`
Paul-Sebastian Ungureanu      168e6cff5: stash: optimize 
`get_untracked_files()` and `check_changes()`
Paul-Sebastian Ungureanu      1f5a011d9: stash: convert create to builtin
Paul-Sebastian Ungureanu      4e763fae8: sha1-name.c: add `get_oidf()` 
which acts like `get_oid()`
Paul-Sebastian Ungureanu      51809c70c: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      559edead8: stash: replace all `write-tree` 
child processes with API calls
Paul-Sebastian Ungureanu      847eb0b0a: stash: convert store to builtin
Paul-Sebastian Ungureanu      9a95010a1: stash: make push -q quiet
Paul-Sebastian Ungureanu      9b77b07ba: stash: convert list to builtin
Paul-Sebastian Ungureanu      b4493f269: stash: convert show to builtin
Paul-Sebastian Ungureanu      bfc3fe33f: strbuf.c: add 
`strbuf_insertf()` and `strbuf_vinsertf()`
Paul-Sebastian Ungureanu      cf5b27d69: stash: convert save to builtin
Paul-Sebastian Ungureanu      fa38428f7: stash: convert push to builtin
René Scharfe      878056005: sequencer: factor out 
strbuf_read_file_or_whine()
Stephen P. Smith      6943bd42f: Add `human` format to test-tool
Stephen P. Smith      86177eb5c: Remove the proposed use of auto as 
secondary way to specify human
Sun Chao      e4e2c2884: pack-redundant: new algorithm to find min packs



Uncovered code in 'jch' not in 'next'
----------------------------------------

builtin/archive.c
01f9ec64c8 builtin/archive.c  63) if (starts_with(reader.line, "NACK "))
01f9ec64c8 builtin/archive.c  64) die(_("git archive: NACK %s"), 
reader.line + 5);

builtin/bisect--helper.c
5e82c3dd22 builtin/bisect--helper.c 162) if (get_oid_commit(commit, &oid))
5e82c3dd22 builtin/bisect--helper.c 163) return error(_("'%s' is not a 
valid commit"), commit);
5e82c3dd22 builtin/bisect--helper.c 164) strbuf_addstr(&branch, commit);
5e82c3dd22 builtin/bisect--helper.c 172) strbuf_release(&branch);
5e82c3dd22 builtin/bisect--helper.c 173) argv_array_clear(&argv);
5e82c3dd22 builtin/bisect--helper.c 174) return error(_("could not check 
out original"
0f30233a11 builtin/bisect--helper.c 215) retval = error(_("Bad 
bisect_write argument: %s"), state);
0f30233a11 builtin/bisect--helper.c 216) goto finish;
0f30233a11 builtin/bisect--helper.c 220) retval = error(_("couldn't get 
the oid of the rev '%s'"), rev);
0f30233a11 builtin/bisect--helper.c 221) goto finish;
0f30233a11 builtin/bisect--helper.c 226) retval = -1;
0f30233a11 builtin/bisect--helper.c 227) goto finish;
0f30233a11 builtin/bisect--helper.c 232) retval = 
error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
0f30233a11 builtin/bisect--helper.c 233) goto finish;
129a6cf344 builtin/bisect--helper.c 329) yesno = git_prompt(_("Are you 
sure [Y/n]? "), PROMPT_ECHO);
129a6cf344 builtin/bisect--helper.c 330) if (starts_with(yesno, "N") || 
starts_with(yesno, "n"))
129a6cf344 builtin/bisect--helper.c 331) retval = -1;
129a6cf344 builtin/bisect--helper.c 332) goto finish;
129a6cf344 builtin/bisect--helper.c 338) retval = 
error(_(need_bisect_start_warning),
450ebb7359 builtin/bisect--helper.c 389) return error(_("invalid 
argument %s for 'git bisect terms'.\n"
06f5608c14 builtin/bisect--helper.c 404) return -1;
06f5608c14 builtin/bisect--helper.c 407) retval = -1;
06f5608c14 builtin/bisect--helper.c 408) goto finish;
06f5608c14 builtin/bisect--helper.c 413) retval = -1;
06f5608c14 builtin/bisect--helper.c 452) no_checkout = 1;
06f5608c14 builtin/bisect--helper.c 474)  !one_of(arg, "--term-good", 
"--term-bad", NULL)) {
06f5608c14 builtin/bisect--helper.c 475) return error(_("unrecognized 
option: '%s'"), arg);
06f5608c14 builtin/bisect--helper.c 510) if (get_oid("HEAD", &head_oid))
06f5608c14 builtin/bisect--helper.c 511) return error(_("bad HEAD - I 
need a HEAD"));
06f5608c14 builtin/bisect--helper.c 526) retval = error(_("checking out 
'%s' failed."
06f5608c14 builtin/bisect--helper.c 547) return error(_("won't bisect on 
cg-seek'ed tree"));
06f5608c14 builtin/bisect--helper.c 550) return error(_("bad HEAD - 
strange symbolic ref"));
06f5608c14 builtin/bisect--helper.c 558) return -1;
06f5608c14 builtin/bisect--helper.c 576) retval = -1;
06f5608c14 builtin/bisect--helper.c 577) goto finish;
06f5608c14 builtin/bisect--helper.c 588) retval = -1;
06f5608c14 builtin/bisect--helper.c 589) goto finish;
06f5608c14 builtin/bisect--helper.c 600) retval = -1;
5e82c3dd22 builtin/bisect--helper.c 677) return error(_("--bisect-reset 
requires either no argument or a commit"));
0f30233a11 builtin/bisect--helper.c 681) return error(_("--bisect-write 
requires either 4 or 5 arguments"));
4fbdbd5bff builtin/bisect--helper.c 687) return 
error(_("--check-and-set-terms requires 3 arguments"));
129a6cf344 builtin/bisect--helper.c 693) return 
error(_("--bisect-next-check requires 2 or 3 arguments"));

builtin/branch.c
711d28e2e4 builtin/branch.c 370) strbuf_addf(&local, 
"%s%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)%%(worktreepath) 
%%(end)%%(end)%s",
0ecb1fc726 builtin/branch.c 460) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 466) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/multi-pack-index.c
334e9745a6 49) die(_("--batch-size option is only for 'repack' 
subcommand"));

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

builtin/rebase.c
21853626ea  258) write_file(state_dir_path("verbose", opts), "%s", "");
21853626ea  260) write_file(state_dir_path("strategy", opts), "%s",
21853626ea  263) write_file(state_dir_path("strategy_opts", opts), "%s",
21853626ea  270) write_file(state_dir_path("gpg_sign_opt", opts), "%s",
21853626ea  273) write_file(state_dir_path("strategy", opts), "--signoff");
c5233708c5  396) ret = -1;
c5233708c5  397) goto leave_reset_head;
c5233708c5  401) ret = error(_("could not determine HEAD revision"));
c5233708c5  402) goto leave_reset_head;
c5233708c5  423) ret = error(_("could not read index"));
c5233708c5  424) goto leave_reset_head;
c5233708c5  428) ret = error(_("failed to find tree of %s"),
c5233708c5  430) goto leave_reset_head;
c5233708c5  434) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
c5233708c5  435) goto leave_reset_head;
c5233708c5  447) ret = error(_("could not write index"));
c5233708c5  448) goto leave_reset_head;
c5233708c5  466) } else if (old_orig)
c5233708c5  467) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
21853626ea  542) argv_array_push(&am.args, opts->gpg_sign_opt);
21853626ea  574) status = error_errno(_("could not open '%s' for writing"),
21853626ea  576) free(rebased_patches);
21853626ea  577) argv_array_clear(&am.args);
21853626ea  578) return status;
21853626ea  587) argv_array_split(&format_patch.args,
21853626ea  588)  opts->git_format_patch_opt.buf);
21853626ea  596) unlink(rebased_patches);
21853626ea  597) free(rebased_patches);
21853626ea  598) argv_array_clear(&am.args);
21853626ea  600) reset_head(&opts->orig_head, "checkout", 
opts->head_name, 0,
21853626ea  602) error(_("\ngit encountered an error while preparing the "
21853626ea  609) strbuf_release(&revisions);
21853626ea  610) return status;
21853626ea  616) status = error_errno(_("could not open '%s' for reading"),
21853626ea  618) free(rebased_patches);
21853626ea  619) argv_array_clear(&am.args);
21853626ea  620) return status;

builtin/receive-pack.c
01f9ec64c8 builtin/receive-pack.c 1587)     reader->line + 8);
01f9ec64c8 builtin/receive-pack.c 1621) die("protocol error: got an 
unexpected packet");

builtin/remote.c
f39a9c6547 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
f39a9c6547 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

commit-graph.c
aa658574bf  127) return NULL;
aa658574bf  130) return NULL;
aa658574bf  186) free(graph);
aa658574bf  187) return NULL;
aa658574bf  222) free(graph);
aa658574bf  223) return NULL;
64415806e8  933) display_progress(oids.progress, approx_nr_objects);

config.c
7e43b32b58 1488) return git_ident_config(var, value, cb);
7e43b32b58 1491) return git_ident_config(var, value, cb);

fetch-pack.c
01f9ec64c8  154) die(_("git fetch-pack: expected a flush packet after 
shallow list"));
01f9ec64c8  358) die(_("invalid shallow line: %s"), reader.line);
01f9ec64c8  364) die(_("invalid unshallow line: %s"), reader.line);
01f9ec64c8  366) die(_("object not found: %s"), reader.line);
01f9ec64c8  369) die(_("error in object: %s"), reader.line);
01f9ec64c8  371) die(_("no shallow found: %s"), reader.line);
01f9ec64c8  374) die(_("expected shallow/unshallow, got %s"), reader.line);
0bbc0bc574 1128) packet_buf_write(&req_buf, "sideband-all");
0bbc0bc574 1350) reader.use_sideband = 1;
0bbc0bc574 1351) reader.me = "fetch-pack";

http-walker.c
514c5fdd03 http-walker.c 550) loose_object_path(the_repository, &buf, 
&req->oid);

ident.c
7e43b32b58 373) email = git_author_email.buf;
7e43b32b58 375) email = git_committer_email.buf;
7e43b32b58 394) name = git_author_name.buf;
7e43b32b58 396) name = git_committer_name.buf;
7e43b32b58 504) if (!value)
7e43b32b58 505) return config_error_nonbool(var);
7e43b32b58 506) strbuf_reset(&git_author_name);
7e43b32b58 507) strbuf_addstr(&git_author_name, value);
7e43b32b58 508) author_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b58 509) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b58 510) return 0;
7e43b32b58 514) if (!value)
7e43b32b58 515) return config_error_nonbool(var);
7e43b32b58 516) strbuf_reset(&git_author_email);
7e43b32b58 517) strbuf_addstr(&git_author_email, value);
7e43b32b58 518) author_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b58 519) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b58 520) return 0;
7e43b32b58 524) if (!value)
7e43b32b58 525) return config_error_nonbool(var);
7e43b32b58 526) strbuf_reset(&git_committer_name);
7e43b32b58 527) strbuf_addstr(&git_committer_name, value);
7e43b32b58 528) committer_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b58 529) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b58 530) return 0;
7e43b32b58 534) if (!value)
7e43b32b58 535) return config_error_nonbool(var);
7e43b32b58 536) strbuf_reset(&git_committer_email);
7e43b32b58 537) strbuf_addstr(&git_committer_email, value);
7e43b32b58 538) committer_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b58 539) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b58 540) return 0;

midx.c
e7a330ee26  428) close_pack(packs->info[packs->nr].p);
e7a330ee26  429) FREE_AND_NULL(packs->info[packs->nr].p);
14b7185175  815) error(_("did not see pack-file %s to drop"),
14b7185175  817) drop_index++;
14b7185175  818) missing_drops++;
14b7185175  819) i--;
14b7185175  826) result = 1;
14b7185175  827) goto cleanup;
14b7185175 1073) return 0;
14b7185175 1088) continue;
14b7185175 1091) continue;
17d0bf5a7d 1142) return 0;
17d0bf5a7d 1151) continue;
17d0bf5a7d 1164) continue;
17d0bf5a7d 1187) error(_("could not start pack-objects"));
17d0bf5a7d 1188) result = 1;
17d0bf5a7d 1189) goto cleanup;
17d0bf5a7d 1206) error(_("could not finish pack-objects"));
17d0bf5a7d 1207) result = 1;
17d0bf5a7d 1208) goto cleanup;

packfile.c
9133688752  369) strbuf_release(&buf);
9133688752  370) return;

pkt-line.c
0bbc0bc574 505) if (demultiplex_sideband(reader->me, reader->buffer,
0bbc0bc574 508) break;
0bbc0bc574 509) }

read-cache.c
ee70c12820 1736) if (advice_unknown_index_extension) {
ee70c12820 1737) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1738) advise(_("This is likely due to the file having been 
written by a newer\n"

ref-filter.c
a9fb549b1d  467) return 0;

remote-curl.c
01f9ec64c8  427) die("invalid server response; got '%s'", reader.line);
01f9ec64c8  439) }

send-pack.c
01f9ec64c8 143) return error(_("unable to parse remote unpack status: 
%s"), reader->line);
01f9ec64c8 162) error("invalid ref status from remote: %s", reader->line);
01f9ec64c8 579) receive_unpack_status(&reader);

sequencer.c
899b49c446 2394) opts->quiet = 1;

sha1-file.c
514c5fdd03 sha1-file.c 1291) status = error(_("unable to parse %s 
header"), oid_to_hex(oid));
00a7760e81 sha1-file.c 2305) the_hash_algo->final_fn(real_oid.hash, &c);
00a7760e81 sha1-file.c 2306) if (!oideq(expected_oid, &real_oid)) {

sideband.c
fbd76cd450 128) suffix = ANSI_SUFFIX;
fbd76cd450 138) strbuf_addf(scratch,
fbd76cd450 140)     scratch->len ? "\n" : "", me);
fbd76cd450 141) *sideband_type = SIDEBAND_PROTOCOL_ERROR;
fbd76cd450 142) goto cleanup;
0bbc0bc574 150) die("remote error: %s", buf + 1);
fbd76cd450 195) strbuf_addf(scratch, "%s%s: protocol error: bad band #%d",
fbd76cd450 196)     scratch->len ? "\n" : "", me, band);
fbd76cd450 197) *sideband_type = SIDEBAND_PROTOCOL_ERROR;
fbd76cd450 198) break;
0bbc0bc574 203) die("%s", scratch->buf);

upload-pack.c
01f9ec64c8  432) die("git upload-pack: expected SHA1 list, got '%s'", 
reader->line);
0bbc0bc574 1066) allow_sideband_all = git_config_bool(var, value);
07c3c2aa16 1306)      allow_sideband_all) &&
07c3c2aa16 1307)     !strcmp(arg, "sideband-all")) {
0bbc0bc574 1308) data->writer.use_sideband = 1;
0bbc0bc574 1309) continue;
bc2e795cea 1441) deepen(&data->writer, INFINITE_DEPTH, 
data->deepen_relative,
07c3c2aa16 1544)    &allow_sideband_all_value) &&

worktree.c
ebefff3c73 465) clear_repository_format(&format);

wrapper.c
e3b1e3bdc0 701) die_errno(_("could not stat %s"), filename);

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      64415806e: commit-graph write: show 
progress for object search
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Denton Liu      f39a9c654: remote: add --save-to-push option to git 
remote set-url
Derrick Stolee      14b718517: multi-pack-index: implement 'expire' 
subcommand
Derrick Stolee      17d0bf5a7: midx: implement midx_repack()
Derrick Stolee      334e9745a: multi-pack-index: prepare 'repack' subcommand
Derrick Stolee      913368875: repack: refactor pack deletion for future use
Derrick Stolee      e7a330ee2: midx: refactor permutation logic and pack 
sorting
Elijah Newren      899b49c44: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Jeff King      00a7760e8: sha1-file: modernize loose header/stream functions
Jeff King      514c5fdd0: sha1-file: modernize loose object file functions
Johannes Schindelin      21853626e: built-in rebase: call `git am` directly
Johannes Schindelin      c5233708c: rebase: move `reset_head()` into a 
better spot
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Jonathan Tan      07c3c2aa1: tests: define GIT_TEST_SIDEBAND_ALL
Jonathan Tan      0bbc0bc57: {fetch,upload}-pack: sideband v2 fetch response
Jonathan Tan      bc2e795ce: pkt-line: introduce struct packet_writer
Jonathan Tan      fbd76cd45: sideband: reverse its dependency on pkt-line
Josh Steadmon      aa658574b: commit-graph, fuzz: add fuzzer for 
commit-graph
Martin Ågren      ebefff3c7: setup: add `clear_repository_format()`
Masaya Suzuki      01f9ec64c: Use packet_reader instead of packet_read_line
Nickolai Belakovski      711d28e2e: branch: add an extra verbose output 
displaying worktree path for checked out branch
Nickolai Belakovski      a9fb549b1: ref-filter: add worktreepath atom
Pranit Bauva      06f5608c1: bisect--helper: `bisect_start` shell 
function partially in C
Pranit Bauva      0f30233a1: bisect--helper: `bisect_write` shell 
function in C
Pranit Bauva      129a6cf34: bisect--helper: `bisect_next_check` shell 
function in C
Pranit Bauva      450ebb735: bisect--helper: `get_terms` & 
`bisect_terms` shell function in C
Pranit Bauva      4fbdbd5bf: bisect--helper: `check_and_set_terms` shell 
function in C
Pranit Bauva      5e82c3dd2: bisect--helper: `bisect_reset` shell 
function in C
Pranit Bauva      e3b1e3bdc: wrapper: move is_empty_file() and rename it 
as is_empty_or_missing_file()
William Hubbs      7e43b32b5: Add author and committer configuration 
settings



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/checkout.c
091e04bc8c builtin/checkout.c  302) return;
091e04bc8c builtin/checkout.c 1268) die(_("'%s' cannot be used with 
switching branches"),

builtin/fetch-pack.c
4316ff3068 builtin/fetch-pack.c 226) get_remote_refs(fd[1], &reader, 
&ref, 0, NULL, NULL);
4316ff3068 builtin/fetch-pack.c 227) break;

builtin/fetch.c
e01378753d builtin/fetch.c 1479) die(_("--filter can only be used with 
the remote "
e01378753d builtin/fetch.c 1648) die(_("--filter can only be used with 
the remote "

builtin/rebase.c
81ef8ee75d  773) return -1;
d421afa0c6 1258) die(_("--reschedule-failed-exec requires an interactive 
rebase"));
d421afa0c6 1296) die(_("error: cannot combine '--preserve-merges' with "

diff.c
b73bcbac4a  308) ret = 0;
21536d077f  812)        (s[off] == '\r' && off < len - 1))
21536d077f  813) off++;
b73bcbac4a 5112) options->color_moved_ws_handling = 0;

entry.c
hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

http-push.c
ea82b2a085 1314) p = process_tree(lookup_tree(the_repository, &entry.oid),

http.c
e6cf87b12d 1999) if (fflush(result)) {
e6cf87b12d 2000) error_errno("unable to flush a file");
e6cf87b12d 2001) return HTTP_START_FAILED;
e6cf87b12d 2003) rewind(result);
e6cf87b12d 2004) if (ftruncate(fileno(result), 0) < 0) {
e6cf87b12d 2005) error_errno("unable to truncate a file");
e6cf87b12d 2006) return HTTP_START_FAILED;
e6cf87b12d 2008) break;

list-objects-filter.c
c813a7c35f 199) return;

match-trees.c
f55ac4311a 231) hashcpy(tree_oid.hash, rewrite_here);
f55ac4311a 232) status = splice_tree(&tree_oid, subpath, oid2, &subtree);

pretty.c
ad6f028f06 1204) return 0;

remote-curl.c
b79bdd8c12  566) return size;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

submodule.c
26f80ccfc1 1398) strbuf_release(&gitdir);
be76c21282 1521) struct fetch_task *task = task_cb;
be76c21282 1525) fetch_task_release(task);

tree-walk.c
0a3faa45b1  530) oidcpy(result, &oid);

tree.c
60c38b9e4a 104) commit = lookup_commit(r, &entry.oid);

upload-pack.c
87c2d9d310  147) sq_quote_buf(&buf, expanded_filter_spec.buf);

Commits introducing uncovered code:
brian m. carlson      0a3faa45b: tree-walk: copy object ID before use
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
brian m. carlson      ea82b2a08: tree-walk: store object_id in a 
separate member
brian m. carlson      f55ac4311: match-trees: use hashcpy to splice trees
Christian Couder      e01378753: fetch: fix extensions.partialclone name 
in error message
Issac Trotts      ad6f028f0: log: add %S option (like --source) to log 
--format
Johannes Schindelin      81ef8ee75: rebase: introduce a shortcut for 
--reschedule-failed-exec
Johannes Schindelin      d421afa0c: rebase: introduce 
--reschedule-failed-exec
Jonathan Tan      4316ff306: fetch-pack: support protocol version 2
Josh Steadmon      87c2d9d31: filter-options: expand scaled numbers
Junio C Hamano      60c38b9e4: Merge branch 'bc/tree-walk-oid' into next
Masaya Suzuki      b79bdd8c1: remote-curl: unset CURLOPT_FAILONERROR
Masaya Suzuki      e6cf87b12: http: enable keep_error for HTTP requests
Matthew DeVore      c813a7c35: list-objects-filter: teach tree:# how to 
handle >0
Phillip Wood      21536d077: diff --color-moved-ws: modify 
allow-indentation-change
Phillip Wood      b73bcbac4: diff: allow --no-color-moved-ws
Stefan Beller      26f80ccfc: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      be76c2128: fetch: ensure submodule objects fetched
Thomas Gummerer      091e04bc8: checkout: introduce --{,no-}overlay option



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/submodule--helper.c
builtin/worktree.c
00a6d4d1d2 752) found_submodules = 1;
00a6d4d1d2 753) break;

commit-graph.c
ref-filter.c
1867ce6cbe  236) oi_deref.info.sizep = &oi_deref.size;
1867ce6cbe  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
33311fa1ad  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));

setup.c
07098b81a4 1093) if (!nongit_ok)
07098b81a4 1094) die(_("not a git repository (or any parent up to mount 
point %s)\n"
07098b81a4 1097) *nongit_ok = 1;
07098b81a4 1098) break;

transport-helper.c
3b3357626e 1029) static int has_attribute(const char *attrs, const char 
*attr)

Commits introducing uncovered code:
Erin Dahlgren      07098b81a: Simplify handling of 
setup_git_directory_gently() failure cases.
Nguyễn Thái Ngọc Duy      00a6d4d1d: worktree: allow to (re)move 
worktrees with uninitialized submodules
Nguyễn Thái Ngọc Duy      3b3357626: style: the opening '{' of a 
function is in a separate line
Olga Telezhnaya      1867ce6cb: ref-filter: add objectsize:disk option
Olga Telezhnaya      33311fa1a: ref-filter: add deltabase option


^ permalink raw reply	[relevance 1%]

* Re: [PATCH] git-submodule: abort if core.worktree could not be set correctly
  2019-01-18 23:18  4% ` Junio C Hamano
@ 2019-01-18 23:30  4%   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2019-01-18 23:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Fri, Jan 18, 2019 at 3:18 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > 74d4731da1f (submodule--helper: replace connect-gitdir-workingtree by
> > ensure-core-worktree, 2018-08-13) forgot to exit the submodule operation
> > if the helper could not ensure that core.worktree is set correctly.
> >
> > Signed-off-by: Stefan Beller <sbeller@google.com>
> > ---
> >  git-submodule.sh | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/git-submodule.sh b/git-submodule.sh
> > index 5e608f8bad3..02a0d728174 100755
> > --- a/git-submodule.sh
> > +++ b/git-submodule.sh
> > @@ -548,7 +548,7 @@ cmd_update()
> >       do
> >               die_if_unmatched "$quickabort" "$sha1"
> >
> > -             git submodule--helper ensure-core-worktree "$sm_path"
> > +             git submodule--helper ensure-core-worktree "$sm_path" || exit 1
>
> Good to have more places check errors from underlying command.
>
> Thanks.
>
> Out of curiousity, was this found by code inspection, or was there a
> real-world breakage episode?

By code inspection to come up with an answer for
https://public-inbox.org/git/CAG0vfyQeA3Hm7AsYgYtP4v-Yg0=rKXW0YYfg_emAwEscZha4VA@mail.gmail.com/

That issue in itself is not fully solved (Duy is still looking into it),
but this fixes a minor inconsistency along the way.

^ permalink raw reply	[relevance 4%]

* Re: [PATCH] git-submodule: abort if core.worktree could not be set correctly
  2019-01-18 21:55 22% [PATCH] git-submodule: abort if core.worktree could not be set correctly Stefan Beller
@ 2019-01-18 23:18  4% ` Junio C Hamano
  2019-01-18 23:30  4%   ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2019-01-18 23:18 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> 74d4731da1f (submodule--helper: replace connect-gitdir-workingtree by
> ensure-core-worktree, 2018-08-13) forgot to exit the submodule operation
> if the helper could not ensure that core.worktree is set correctly.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  git-submodule.sh | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 5e608f8bad3..02a0d728174 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -548,7 +548,7 @@ cmd_update()
>  	do
>  		die_if_unmatched "$quickabort" "$sha1"
>  
> -		git submodule--helper ensure-core-worktree "$sm_path"
> +		git submodule--helper ensure-core-worktree "$sm_path" || exit 1

Good to have more places check errors from underlying command.

Thanks.

Out of curiousity, was this found by code inspection, or was there a
real-world breakage episode?


^ permalink raw reply	[relevance 4%]

* [PATCH] git-submodule: abort if core.worktree could not be set correctly
@ 2019-01-18 21:55 22% Stefan Beller
  2019-01-18 23:18  4% ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2019-01-18 21:55 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

74d4731da1f (submodule--helper: replace connect-gitdir-workingtree by
ensure-core-worktree, 2018-08-13) forgot to exit the submodule operation
if the helper could not ensure that core.worktree is set correctly.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 git-submodule.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index 5e608f8bad3..02a0d728174 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -548,7 +548,7 @@ cmd_update()
 	do
 		die_if_unmatched "$quickabort" "$sha1"
 
-		git submodule--helper ensure-core-worktree "$sm_path"
+		git submodule--helper ensure-core-worktree "$sm_path" || exit 1
 
 		update_module=$(git submodule--helper update-module-mode $just_cloned "$sm_path" $update)
 
-- 
2.20.1.101.g27c53b536e7.dirty


^ permalink raw reply related	[relevance 22%]

* Re: [RFC] submodule: munge paths to submodule git directories
  @ 2019-01-17 17:57  7%     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2019-01-17 17:57 UTC (permalink / raw)
  To: Jeff King; +Cc: Jonathan Nieder, git, Brandon Williams, Aaron Schrab

On Thu, Jan 17, 2019 at 9:32 AM Jeff King <peff@peff.net> wrote:
>
> On Mon, Jan 14, 2019 at 05:25:07PM -0800, Jonathan Nieder wrote:
>
> > I've put a summary in https://crbug.com/git/28 to make this easier to
> > pick up where we left off.  Summary from there of the upstream review:
> >
> > 1. Using urlencoding to escape the slashes is fine, but what if we
> >    want to escape some other character (for example to handle
> >    case-insensitive filesystems)?
> >
> >    Proposal: Store the escaping mapping in config[1] so it can be
> >    modified it in the future:
> >
> >       [submodule "plugin/hooks"]
> >               gitdirname = plugins%2fhooks
>
> I think it might be worth dealing with case-sensitivity _now_, since we
> know it's a problem. That doesn't make the problem of "what if we want
> to change the mapping later" go away, but it does make it a lot less
> likely to come up.

Makes sense.

>
> > 2. The urlencoded name could conflict with a submodule that has % in
> >    its name in an existing clone created by an older version of Git.
> >
> >    Proposal: Put submodules in a new .git/submodules/ directory
> >    instead of .git/modules/.
>
> This proposal is orthogonal to (1), right? I.e., if we store the mapping
> then that is what tells us we're using the mapped name.

Technically true, but it allows for easier implementation:
now we have 2 distinct namespaces, such that we can avoid
double booking easier:

    Consider 2 submodules "a b" and "a%20b".

Without (2), (1) is hard to explain as the first might have been encoded
to a%20b or there might have been the second put in place from a
current (old) version of Git. So we'd have to reason about these corner cases.

With (2) in place, we'd only ever have the second in a place "a%2520b"
(if I am to trust https://www.urlencoder.org/)

> > 3. These gitdirname settings can clutter up .git/config.
> >
> >    Proposal: For the "easy" cases (e.g. submodule name consisting of
> >    [a-z]*), allow omitting the gitdirname setting.
>
> Not having thought about it too hard, I suspect that may open back up
> corner cases with respect to backwards compatibility and ambiguity.
>
> Are you worried about human-readable clutter? I.e., that .git/config
> becomes hard to read? If so, then:
>
>   - I doubt this is any worse than the existing tracking-branch config.
>
>   - it might be reasonable to store it in .git/submodule-config, and
>     make sure that .git/config contains a single "[include]path =
>     submodule-config" line. I've been tempted to do that for
>     tracking-branch config.
>
> Or are you worried about the cost of parsing those entries? Basically
> every git command parses config linearly at least once; this normally
> isn't noticeable, but at some size it becomes a problem. I have no idea
> what that size is.
>
> If so, then I think we'd want submodule config in its own file but
> _without_ an include from the normal config file. That would break
> compatibility with anything that tries to use "git config
> submodule.foo.path", etc.
>
> That's all just musing. I'm actually not really convinced it's a
> problem.

ok, we can deal with the problem once it arises.

>
> > Is that a fair summary?  Are there concerns from the review that I
> > forgot, or would a new version of the series that addresses those
> > three problems put us in good shape?
>
> I don't really have a strong opinion either way. I still think the
> one-way transformation that the patch uses is less elegant than a real
> encode/decode round-trip (i.e., what I discussed in [1]). But I admit to
> not having thought through all of the details of the encode/decode
> thing, and certainly have not written the code.

The suggestion of adding at least a test for url encoding (2. from your mail)
is sensible.

Stefan

>
> [1] http://public-inbox.org/git/20180809212602.GA11342@sigill.intra.peff.net/

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 01/10] doc: about submodule support with multiple worktrees
  2019-01-16 22:06  7%   ` Stefan Beller
@ 2019-01-17 10:22  4%     ` Duy Nguyen
  0 siblings, 0 replies; 200+ results
From: Duy Nguyen @ 2019-01-17 10:22 UTC (permalink / raw)
  To: Stefan Beller
  Cc: git, Tomasz Śniatowski, Jonathan Nieder, Marc Branchaud,
	Junio C Hamano

On Thu, Jan 17, 2019 at 5:06 AM Stefan Beller <sbeller@google.com> wrote:
> > clones from $GIT_COMMON_DIR/worktrees/X/modules to
> > $GIT_COMMON_DIR/common/modules.
>
> ... from the submodule side of things this is big problem,
> as the submodule is usually assumed at $GIT_DIR/modules/<name>
> (I think we have not been strict in $GIT_DIR $GIT_COMMON_DIR
> in the submodule code)
>
> So the plan is to neither use
>
> $GIT_COMMON_DIR/worktrees/X/modules/Y
> $GIT_COMMON_DIR/modules/Y/worktrees/X
>
> but to create a new third location at
>
> $GIT_COMMON_DIR/common/modules
>
> to which either new submodule worktrees
> or superproject worktrees that happen to have this submodule
> can point to?

Yes. And this is yet another "absorb" operation to move from the
current location to the new one. The code will have to check both
places, just as it has to check if "foo/bar/.git" is a real repo
before it goes to $GIT_DIR/.git/modules/bar (at least this is how I
understand it).

> > The latter directory is shared across all worktrees. Once we keep the
> > clone in a common place, the submodule's worktree can be created and
> > managed with git-worktree[1].
>
> So even when the user has never heard of worktrees, the internal structure
> will be worktree oriented, the common dir in common/modules/Y and in
> $GIT_DIR/modules/Y we could just have a worktree git dir?

I think the .git dir will be in common/modules/Y. $GIT_DIR/modules/Y
is basically replaced by $GIT_COMMON_DIR/common/modules/Y, which
should work even when you don't use git-worktree (in single-worktree
setting, $GIT_COMMON_DIR == $GIT_DIR).
-- 
Duy

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 03/10] submodule add: support multiple worktrees
  @ 2019-01-16 22:27  7%   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2019-01-16 22:27 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy
  Cc: git, Tomasz Śniatowski, Jonathan Nieder, Marc Branchaud,
	Junio C Hamano

> --- /dev/null
> +++ b/t/t2405-worktree-submodules.sh
> @@ -0,0 +1,42 @@
> +#!/bin/sh
> +
> +test_description='multiple worktrees as superprojects'
> +
> +. ./test-lib.sh
> +
> +test_expect_success 'set up submodule source' '
> +       test_create_repo submodsrc &&
> +       (
> +               cd submodsrc &&
> +               test_commit one
> +       ) &&

Just like git itself, test_commit now supports the -C <dir>
argument, so you could replace the whole subshell with

    test_commit -C submodsrc one &&


> +       test_commit initial &&
> +       git worktree add -b secondary secondary HEAD &&

Could we have multiple things not named the same?
(i.e. have the the branch and worktree be spelled differently)
That way it is less confusing and we'd catch errors of swapping
these two in the implementation (unlikely, but...)

> +       git config extensions.worktreeConfig true
> +'
> +
> +test_expect_success 'add submodules' '
> +       SRC="$(pwd)/submodsrc" &&
> +       git submodule add "$SRC" sub1 &&

you can also use relative paths in submodules:

    git submodule add ./submodsrc sub1 &&

if you want to.

> +       git commit -m sub1 &&
> +       git -C secondary submodule add "$SRC" sub2 &&

Oh never mind, by having the absolute path we
add the submodule with the same setting.
(When using relative path we'd have to use ../submodusrc
here, but would that matter?)

> +       git -C secondary commit -m sub2 &&
> +
> +       git config --get-regexp "submodule.*" | sort >actual1 &&
> +       cat >expected1 <<-EOF &&
> +       submodule.sub1.active true
> +       submodule.sub1.url $(pwd)/submodsrc
> +       EOF
> +       test_cmp expected1 actual1 &&
> +       test -d .git/modules/sub1 &&
> +
> +       git -C secondary config --get-regexp "submodule.*" | sort >actual2 &&
> +       cat >expected2 <<-EOF &&
> +       submodule.sub2.active true
> +       submodule.sub2.url $(pwd)/submodsrc
> +       EOF
> +       test_cmp expected2 actual2 &&
> +       test -d .git/worktrees/secondary/modules/sub2

This section is very brittle. For example the way how submodules
are active changed not so long ago, and might change again, which
seems unrelated to the thing tested here?

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 01/10] doc: about submodule support with multiple worktrees
  @ 2019-01-16 22:06  7%   ` Stefan Beller
  2019-01-17 10:22  4%     ` Duy Nguyen
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2019-01-16 22:06 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy
  Cc: git, Tomasz Śniatowski, Jonathan Nieder, Marc Branchaud,
	Junio C Hamano

> The third problem is a big and complicaed one. Submodule clones

complicated

> (inside the superproject) are per-worktree. So if you have two
> worktrees, and these have one submodule, you need space for _two_
> clones. This is definitely not elegant. The tenative plan is to move

tentative?

> clones from $GIT_COMMON_DIR/worktrees/X/modules to
> $GIT_COMMON_DIR/common/modules.

... from the submodule side of things this is big problem,
as the submodule is usually assumed at $GIT_DIR/modules/<name>
(I think we have not been strict in $GIT_DIR $GIT_COMMON_DIR
in the submodule code)

So the plan is to neither use
$GIT_COMMON_DIR/worktrees/X/modules/Y
$GIT_COMMON_DIR/modules/Y/worktrees/X
but to create a new third location at
$GIT_COMMON_DIR/common/modules
to which either new submodule worktrees
or superproject worktrees that happen to have this submodule
can point to?

>
> The latter directory is shared across all worktrees. Once we keep the
> clone in a common place, the submodule's worktree can be created and
> managed with git-worktree[1].

So even when the user has never heard of worktrees, the internal structure
will be worktree oriented, the common dir in common/modules/Y and in
$GIT_DIR/modules/Y we could just have a worktree git dir?

> Another good point about this approach is we could finally safely
> allow "git worktree remove" to work with submodules. With current
> solution, removing $GIT_COMMON_DIR/worktrees/X directory means also
> removing potentially precious clones inside the "modules" subdir.

yup, very sensible.

I like this approach very much.

^ permalink raw reply	[relevance 7%]

* Git Test Coverage Report (Wed Jan 16)
@ 2019-01-16 18:22  2% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2019-01-16 18:22 UTC (permalink / raw)
  To: GIT Mailing-list

Here is today's test coverage report.

Thanks,
-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=303

---

pu: 8df4a8d850bb2115f6e24d1e45a2d58700f66ece
jch: 7529c1c1876fbd86faf08d8e45080e5bdde0ca9a
next: 40155ab247a57ccc696d2ded09336b2c5203e832
master: 77556354bb7ac50450e3b28999e3576969869068
master@{1}: ecbdaf0899161c067986e9d9d564586d4b045d62

Uncovered code in 'pu' not in 'jch'
--------------------------------------

bisect.c
9192bb22fd  661) mark_edges_uninteresting(revs, NULL, 0);

builtin/blame.c
080448fbe8 builtin/blame.c    930) blame_date_width = sizeof("Thu Oct 19 
16:00");
080448fbe8 builtin/blame.c    931) break;

builtin/config.c
a12c1ff3a5 builtin/config.c      110) die(_("$HOME not set"));
a12c1ff3a5 builtin/config.c      122) given_config_source.file = 
git_etc_gitconfig();
6f11fd5edb builtin/config.c      503) die(_("unknown config source"));
6f11fd5edb builtin/config.c      509) die(_("invalid key pattern: %s"), 
key);

builtin/diff-tree.c
e1ff0a32e4 builtin/diff-tree.c 169) repo_read_index(the_repository);

builtin/pack-redundant.c
a338d10395 builtin/pack-redundant.c 347) return 0;
cb7e0336fc builtin/pack-redundant.c 461) 
llist_sorted_difference_inplace(all_objects, pl->remaining_objects);
cb7e0336fc builtin/pack-redundant.c 490) 
llist_sorted_difference_inplace(all_objects, alt->remaining_objects);

builtin/rebase--interactive.c
e5b1c9d929 builtin/rebase--interactive.c   24) return 
error_errno(_("could not read '%s'."), todo_file);
e5b1c9d929 builtin/rebase--interactive.c   31) return 
error_errno(_("could not write '%s'"), todo_file);
4d55dfd767 builtin/rebase--interactive.c   46) return 
error_errno(_("could not read '%s'."), todo_file);
4d55dfd767 builtin/rebase--interactive.c   50) 
todo_list_release(&todo_list);
4d55dfd767 builtin/rebase--interactive.c   51) return error(_("unusable 
todo list: '%s'"), todo_file);
4d55dfd767 builtin/rebase--interactive.c   59) return 
error_errno(_("could not write '%s'."), todo_file);
febebd99b6 builtin/rebase--interactive.c  313) ret = 
rearrange_squash_in_todo_file(the_repository);
8414c890aa builtin/rebase--interactive.c  316) ret = 
sequencer_add_exec_commands(the_repository, &commands);

builtin/stash.c
f6bbd78127 builtin/stash--helper.c  128) die(_("'%s' is not a stash-like 
commit"), revision);
f6bbd78127 builtin/stash--helper.c  161) free_stash_info(info);
f6bbd78127 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
f6bbd78127 builtin/stash--helper.c  163) return -1;
f6bbd78127 builtin/stash--helper.c  198) free_stash_info(info);
cdca49bc4c builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
f6bbd78127 builtin/stash--helper.c  241) return -1;
f6bbd78127 builtin/stash--helper.c  249) return -1;
f6bbd78127 builtin/stash--helper.c  262) return -1;
f6bbd78127 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
f6bbd78127 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
f6bbd78127 builtin/stash--helper.c  378) return -1;
f6bbd78127 builtin/stash--helper.c  405) return -1;
f6bbd78127 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
f6bbd78127 builtin/stash--helper.c  418) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  419) return error(_("could not 
generate diff %s^!."),
f6bbd78127 builtin/stash--helper.c  426) return error(_("conflicts in 
index."
f6bbd78127 builtin/stash--helper.c  432) return error(_("could not save 
index tree"));
f6bbd78127 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
f6bbd78127 builtin/stash--helper.c  470) return -1;
f6bbd78127 builtin/stash--helper.c  475) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  480) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  481) return -1;
cdca49bc4c builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
e1d01876a4 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
b4493f269e builtin/stash--helper.c  766) free_stash_info(&info);
51809c70ca builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
847eb0b0a8 builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
847eb0b0a8 builtin/stash--helper.c  789) if (!quiet) {
847eb0b0a8 builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
847eb0b0a8 builtin/stash--helper.c  793) return -1;
847eb0b0a8 builtin/stash--helper.c  817) if (!quiet)
847eb0b0a8 builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
847eb0b0a8 builtin/stash--helper.c  820) return -1;
1f5a011d90 builtin/stash--helper.c  903) return -1;
1f5a011d90 builtin/stash--helper.c  963) ret = -1;
1f5a011d90 builtin/stash--helper.c  964) goto done;
1f5a011d90 builtin/stash--helper.c  969) ret = -1;
1f5a011d90 builtin/stash--helper.c  970) goto done;
1f5a011d90 builtin/stash--helper.c  975) ret = -1;
1f5a011d90 builtin/stash--helper.c  976) goto done;
1f5a011d90 builtin/stash--helper.c 1002) ret = -1;
1f5a011d90 builtin/stash--helper.c 1003) goto done;
1f5a011d90 builtin/stash--helper.c 1014) ret = -1;
1f5a011d90 builtin/stash--helper.c 1015) goto done;
1f5a011d90 builtin/stash--helper.c 1021) ret = -1;
1f5a011d90 builtin/stash--helper.c 1022) goto done;
1f5a011d90 builtin/stash--helper.c 1029) ret = -1;
1f5a011d90 builtin/stash--helper.c 1030) goto done;
1f5a011d90 builtin/stash--helper.c 1055) ret = -1;
1f5a011d90 builtin/stash--helper.c 1056) goto done;
1f5a011d90 builtin/stash--helper.c 1067) ret = -1;
1f5a011d90 builtin/stash--helper.c 1068) goto done;
1f5a011d90 builtin/stash--helper.c 1074) ret = -1;
1f5a011d90 builtin/stash--helper.c 1075) goto done;
1f5a011d90 builtin/stash--helper.c 1086) ret = -1;
1f5a011d90 builtin/stash--helper.c 1087) goto done;
1f5a011d90 builtin/stash--helper.c 1092) ret = -1;
1f5a011d90 builtin/stash--helper.c 1093) goto done;
9a95010a11 builtin/stash--helper.c 1129) fprintf_ln(stderr, _("You do 
not have "
1f5a011d90 builtin/stash--helper.c 1138) ret = 1;
1f5a011d90 builtin/stash--helper.c 1139) goto done;
9a95010a11 builtin/stash--helper.c 1155) if (!quiet)
9a95010a11 builtin/stash--helper.c 1156) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1158) ret = -1;
1f5a011d90 builtin/stash--helper.c 1159) goto done;
9a95010a11 builtin/stash--helper.c 1164) if (!quiet)
9a95010a11 builtin/stash--helper.c 1165) fprintf_ln(stderr, _("Cannot save "
1f5a011d90 builtin/stash--helper.c 1167) ret = -1;
1f5a011d90 builtin/stash--helper.c 1168) goto done;
9a95010a11 builtin/stash--helper.c 1175) if (!quiet)
9a95010a11 builtin/stash--helper.c 1176) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1178) goto done;
9a95010a11 builtin/stash--helper.c 1184) if (!quiet)
9a95010a11 builtin/stash--helper.c 1185) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1187) ret = -1;
1f5a011d90 builtin/stash--helper.c 1188) goto done;
9a95010a11 builtin/stash--helper.c 1212) if (!quiet)
9a95010a11 builtin/stash--helper.c 1213) fprintf_ln(stderr, _("Cannot 
record "
1f5a011d90 builtin/stash--helper.c 1215) ret = -1;
1f5a011d90 builtin/stash--helper.c 1216) goto done;
fa38428f76 builtin/stash--helper.c 1285) ret = -1;
fa38428f76 builtin/stash--helper.c 1286) goto done;
fa38428f76 builtin/stash--helper.c 1296) ret = -1;
9a95010a11 builtin/stash--helper.c 1297) if (!quiet)
9a95010a11 builtin/stash--helper.c 1298) fprintf_ln(stderr, _("Cannot 
initialize stash"));
fa38428f76 builtin/stash--helper.c 1299) goto done;
fa38428f76 builtin/stash--helper.c 1311) ret = -1;
9a95010a11 builtin/stash--helper.c 1312) if (!quiet)
9a95010a11 builtin/stash--helper.c 1313) fprintf_ln(stderr, _("Cannot 
save the current status"));
fa38428f76 builtin/stash--helper.c 1314) goto done;
fa38428f76 builtin/stash--helper.c 1331) ret = -1;
fa38428f76 builtin/stash--helper.c 1350) ret = -1;
fa38428f76 builtin/stash--helper.c 1351) goto done;
fa38428f76 builtin/stash--helper.c 1360) ret = -1;
fa38428f76 builtin/stash--helper.c 1361) goto done;
fa38428f76 builtin/stash--helper.c 1369) ret = -1;
fa38428f76 builtin/stash--helper.c 1378) ret = -1;
fa38428f76 builtin/stash--helper.c 1389) ret = -1;
fa38428f76 builtin/stash--helper.c 1390) goto done;
fa38428f76 builtin/stash--helper.c 1399) ret = -1;
fa38428f76 builtin/stash--helper.c 1400) goto done;
fa38428f76 builtin/stash--helper.c 1408) ret = -1;
fa38428f76 builtin/stash--helper.c 1434) ret = -1;
bec65d5b78 builtin/stash.c         1526) return env;
26799a208f builtin/stash.c         1554) const char *path = 
mkpath("%s/git-legacy-stash",
26799a208f builtin/stash.c         1557) if (sane_execvp(path, (char 
**)argv) < 0)
26799a208f builtin/stash.c         1558) die_errno(_("could not exec 
%s"), path);
51809c70ca builtin/stash.c         1601) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
51809c70ca builtin/stash.c         1629) continue;

config.c
8f7c7f5555 2147) int repo_config_set_gently(struct repository *r,
8f7c7f5555 2150) char *path = repo_git_path(r, "config");
8f7c7f5555 2151) int ret = git_config_set_multivar_in_file_gently(path, 
key, value, NULL, 0);
8f7c7f5555 2152) free(path);
8f7c7f5555 2153) return ret;
8f7c7f5555 2156) void repo_config_set(struct repository *r, const char 
*key, const char *value)
8f7c7f5555 2158) if (!repo_config_set_gently(r, key, value))
8f7c7f5555 2159) return;
8f7c7f5555 2160) if (value)
8f7c7f5555 2161) die(_("could not set '%s' to '%s'"), key, value);
8f7c7f5555 2163) die(_("could not unset '%s'"), key);
8f7c7f5555 2166) int repo_config_set_worktree_gently(struct repository *r,
8f7c7f5555 2172) path = get_worktree_config(r);
8f7c7f5555 2173) if (!path)
8f7c7f5555 2174) return CONFIG_INVALID_FILE;
8f7c7f5555 2175) ret = git_config_set_multivar_in_file_gently(path, key, 
value, NULL, 0);
8f7c7f5555 2176) free(path);
8f7c7f5555 2177) return ret;

date.c
080448fbe8  113) die("Timestamp too large for this system: %"PRItime, time);
080448fbe8  223) hide.date = 1;
080448fbe8  886) static int auto_date_style(void)
080448fbe8  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
080448fbe8  911) return auto_date_style();

list-objects.c
9192bb22fd 241) continue;
9192bb22fd 250) parent->object.flags |= SHOWN;
9192bb22fd 251) show_edge(parent);
9192bb22fd 272) tree->object.flags |= UNINTERESTING;
9192bb22fd 287) commit->object.flags |= SHOWN;
9192bb22fd 288) show_edge(commit);

merge-recursive.c
0d6caa2d08  433) for (i = 0; i < istate->cache_nr; i++) {
0d6caa2d08  434) const struct cache_entry *ce = istate->cache[i];
0d6caa2d08  443) istate->cache_tree = cache_tree();
0d6caa2d08  733) ce = index_file_exists(o->repo->index, path, strlen(path),
0d6caa2d08 3193) remove_file_from_index(o->repo->index, path);

pretty.c
4681fe38e1 1069) return 0;
b755bf6f83 1107)     match_placeholder_arg(p, "=on", end) ||
b755bf6f83 1108)     match_placeholder_arg(p, "=true", end)) {

protocol.c
6da1f1a920  37) die(_("Unrecognized protocol version"));
6da1f1a920  39) die(_("Unrecognized protocol_version"));

rebase-interactive.c
c27b32f0ec  26) warning(_("unrecognized setting %s for option "
e5b1c9d929 102) return error(_("could not copy '%s' to '%s'."), todo_file,
c27b32f0ec 164) goto leave_check;

remote-curl.c
6da1f1a920  344) return 0;
34a9469d6a  373) die("invalid server response; expected service, got 
flush packet");
34a9469d6a  397) d->proto_git = 1;

repository.c
revision.c
9949aaeef4  169) return;
9949aaeef4  172) return;
9949aaeef4  195) break;
8446350be2  218) continue;

sequencer.c
e1ff0a32e4 3950) res = error_dirty_index(r, opts);
8414c890aa 4571) int sequencer_add_exec_commands(struct repository *r,
8414c890aa 4579) return error_errno(_("could not read '%s'."), todo_file);
8414c890aa 4581) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, 
&todo_list)) {
8414c890aa 4586) todo_list_add_exec_commands(&todo_list, commands);
8414c890aa 4587) res = todo_list_write_to_file(r, &todo_list, todo_file, 
NULL, NULL, -1, 0);
0cce4a2756 4588) todo_list_release(&todo_list);
8414c890aa 4590) if (res)
8414c890aa 4591) return error_errno(_("could not write '%s'."), todo_file);
8414c890aa 4592) return 0;
cf18b3f6c9 4626) strbuf_addstr(buf, " -c");
878056005e 4673) res = -1;
c27b32f0ec 4674) goto out;
c27b32f0ec 4679) goto out;
c27b32f0ec 4688) fprintf(stderr, _(edit_todo_list_advice));
98b29e0607 4806) todo_list_release(&new_todo);
c1c074e0cc 4812) todo_list_release(&new_todo);
c1c074e0cc 4813) return error_errno(_("could not write '%s'"), todo_file);
febebd99b6 4990) int rearrange_squash_in_todo_file(struct repository *r)
febebd99b6 4992) const char *todo_file = rebase_path_todo();
febebd99b6 4993) struct todo_list todo_list = TODO_LIST_INIT;
febebd99b6 4994) int res = 0;
febebd99b6 4996) if (strbuf_read_file_or_whine(&todo_list.buf, 
todo_file) < 0)
febebd99b6 4997) return -1;
febebd99b6 4998) if (todo_list_parse_insn_buffer(r, todo_list.buf.buf, 
&todo_list) < 0) {
febebd99b6 4999) todo_list_release(&todo_list);
febebd99b6 5000) return -1;
febebd99b6 5003) res = todo_list_rearrange_squash(&todo_list);
febebd99b6 5004) if (!res)
febebd99b6 5005) res = todo_list_write_to_file(r, &todo_list, todo_file, 
NULL, NULL, -1, 0);
febebd99b6 5007) todo_list_release(&todo_list);
febebd99b6 5009) if (res)
febebd99b6 5010) return error_errno(_("could not write '%s'."), todo_file);
febebd99b6 5011) return 0;

strbuf.c
bfc3fe33f6  259) die("`pos' is too far after the end of the buffer");
bfc3fe33f6  266) return; /* nothing to do */
bfc3fe33f6  268) die("you want to use way too much memory");
18f8e81091  448) return 0;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Alban Gruin      4d55dfd76: rebase-interactive: move 
transform_todo_file() to rebase--interactive.c
Alban Gruin      8414c890a: sequencer: refactor 
sequencer_add_exec_commands() to work on a todo_list
Alban Gruin      98b29e060: sequencer: refactor skip_unnecessary_picks() 
to work on a todo_list
Alban Gruin      c1c074e0c: sequencer: change complete_action() to use 
the refactored functions
Alban Gruin      c27b32f0e: sequencer: refactor check_todo_list() to 
work on a todo_list
Alban Gruin      cf18b3f6c: sequencer: introduce todo_list_write_to_file()
Alban Gruin      e5b1c9d92: rebase-interactive: rewrite edit_todo_list() 
to handle the initial edit
Alban Gruin      febebd99b: sequencer: refactor rearrange_squash() to 
work on a todo_list
Anders Waldenborg      18f8e8109: strbuf: separate callback for 
strbuf_expand:ing literals
Anders Waldenborg      4681fe38e: pretty: allow showing specific trailers
Anders Waldenborg      b755bf6f8: pretty: allow %(trailers) options with 
explicit value
Derrick Stolee      8446350be: revision: add mark_tree_uninteresting_sparse
Derrick Stolee      9192bb22f: list-objects: consume sparse tree walk
Derrick Stolee      9949aaeef: revision: implement sparse algorithm
Jeff King      34a9469d6: remote-curl: refactor smart-http discovery
Jiang Xin      a338d1039: pack-redundant: consistent sort method
Jiang Xin      cb7e0336f: pack-redundant: rename pack_list.all_objects
Joel Teichroeb      cdca49bc4: stash: convert drop and clear to builtin
Joel Teichroeb      e1d01876a: stash: convert pop to builtin
Joel Teichroeb      f6bbd7812: stash: convert apply to builtin
Johannes Schindelin      26799a208: stash: optionally use the scripted 
version again
Johannes Schindelin      bec65d5b7: tests: add a special setup where 
stash.useBuiltin is off
Josh Steadmon      6da1f1a92: protocol: advertise multiple supported 
versions
Liam Beguin      0cce4a275: rebase -i -x: add exec commands via the 
rebase--helper
Linus Torvalds      080448fbe: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      0d6caa2d0: merge-recursive.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      6f11fd5ed: config: add --move-to
Nguyễn Thái Ngọc Duy      8f7c7f555: config.c: add 
repo_config_set_worktree_gently()
Nguyễn Thái Ngọc Duy      a12c1ff3a: config: factor out 
set_config_source_file()
Nguyễn Thái Ngọc Duy      e1ff0a32e: read-cache.c: kill read_index()
Paul-Sebastian Ungureanu      1f5a011d9: stash: convert create to builtin
Paul-Sebastian Ungureanu      51809c70c: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      847eb0b0a: stash: convert store to builtin
Paul-Sebastian Ungureanu      9a95010a1: stash: make push -q quiet
Paul-Sebastian Ungureanu      b4493f269: stash: convert show to builtin
Paul-Sebastian Ungureanu      bfc3fe33f: strbuf.c: add 
`strbuf_insertf()` and `strbuf_vinsertf()`
Paul-Sebastian Ungureanu      fa38428f7: stash: convert push to builtin
René Scharfe      878056005: sequencer: factor out 
strbuf_read_file_or_whine()



Uncovered code in 'jch' not in 'next'
----------------------------------------

builtin/archive.c
01f9ec64c8 builtin/archive.c  63) if (starts_with(reader.line, "NACK "))
01f9ec64c8 builtin/archive.c  64) die(_("git archive: NACK %s"), 
reader.line + 5);

builtin/bisect--helper.c
5e82c3dd22 builtin/bisect--helper.c 162) if (get_oid_commit(commit, &oid))
5e82c3dd22 builtin/bisect--helper.c 163) return error(_("'%s' is not a 
valid commit"), commit);
5e82c3dd22 builtin/bisect--helper.c 164) strbuf_addstr(&branch, commit);
5e82c3dd22 builtin/bisect--helper.c 172) strbuf_release(&branch);
5e82c3dd22 builtin/bisect--helper.c 173) argv_array_clear(&argv);
5e82c3dd22 builtin/bisect--helper.c 174) return error(_("could not check 
out original"
0f30233a11 builtin/bisect--helper.c 215) retval = error(_("Bad 
bisect_write argument: %s"), state);
0f30233a11 builtin/bisect--helper.c 216) goto finish;
0f30233a11 builtin/bisect--helper.c 220) retval = error(_("couldn't get 
the oid of the rev '%s'"), rev);
0f30233a11 builtin/bisect--helper.c 221) goto finish;
0f30233a11 builtin/bisect--helper.c 226) retval = -1;
0f30233a11 builtin/bisect--helper.c 227) goto finish;
0f30233a11 builtin/bisect--helper.c 232) retval = 
error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
0f30233a11 builtin/bisect--helper.c 233) goto finish;
129a6cf344 builtin/bisect--helper.c 329) yesno = git_prompt(_("Are you 
sure [Y/n]? "), PROMPT_ECHO);
129a6cf344 builtin/bisect--helper.c 330) if (starts_with(yesno, "N") || 
starts_with(yesno, "n"))
129a6cf344 builtin/bisect--helper.c 331) retval = -1;
129a6cf344 builtin/bisect--helper.c 332) goto finish;
129a6cf344 builtin/bisect--helper.c 338) retval = 
error(_(need_bisect_start_warning),
450ebb7359 builtin/bisect--helper.c 389) return error(_("invalid 
argument %s for 'git bisect terms'.\n"
06f5608c14 builtin/bisect--helper.c 404) return -1;
06f5608c14 builtin/bisect--helper.c 407) retval = -1;
06f5608c14 builtin/bisect--helper.c 408) goto finish;
06f5608c14 builtin/bisect--helper.c 413) retval = -1;
06f5608c14 builtin/bisect--helper.c 452) no_checkout = 1;
06f5608c14 builtin/bisect--helper.c 474)  !one_of(arg, "--term-good", 
"--term-bad", NULL)) {
06f5608c14 builtin/bisect--helper.c 475) return error(_("unrecognized 
option: '%s'"), arg);
06f5608c14 builtin/bisect--helper.c 510) if (get_oid("HEAD", &head_oid))
06f5608c14 builtin/bisect--helper.c 511) return error(_("bad HEAD - I 
need a HEAD"));
06f5608c14 builtin/bisect--helper.c 526) retval = error(_("checking out 
'%s' failed."
06f5608c14 builtin/bisect--helper.c 547) return error(_("won't bisect on 
cg-seek'ed tree"));
06f5608c14 builtin/bisect--helper.c 550) return error(_("bad HEAD - 
strange symbolic ref"));
06f5608c14 builtin/bisect--helper.c 558) return -1;
06f5608c14 builtin/bisect--helper.c 576) retval = -1;
06f5608c14 builtin/bisect--helper.c 577) goto finish;
06f5608c14 builtin/bisect--helper.c 588) retval = -1;
06f5608c14 builtin/bisect--helper.c 589) goto finish;
06f5608c14 builtin/bisect--helper.c 600) retval = -1;
5e82c3dd22 builtin/bisect--helper.c 677) return error(_("--bisect-reset 
requires either no argument or a commit"));
0f30233a11 builtin/bisect--helper.c 681) return error(_("--bisect-write 
requires either 4 or 5 arguments"));
4fbdbd5bff builtin/bisect--helper.c 687) return 
error(_("--check-and-set-terms requires 3 arguments"));
129a6cf344 builtin/bisect--helper.c 693) return 
error(_("--bisect-next-check requires 2 or 3 arguments"));

builtin/branch.c
711d28e2e4 builtin/branch.c 370) strbuf_addf(&local, 
"%s%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)%%(worktreepath) 
%%(end)%%(end)%s",
0ecb1fc726 builtin/branch.c 460) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 466) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/checkout.c
091e04bc8c builtin/checkout.c  302) return;
091e04bc8c builtin/checkout.c 1268) die(_("'%s' cannot be used with 
switching branches"),

builtin/fetch-pack.c
4316ff3068 builtin/fetch-pack.c 227) get_remote_refs(fd[1], &reader, 
&ref, 0, NULL, NULL);
4316ff3068 builtin/fetch-pack.c 228) break;

builtin/multi-pack-index.c
334e9745a6 49) die(_("--batch-size option is only for 'repack' 
subcommand"));

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

builtin/rebase.c
3bd5f07101  258) write_file(state_dir_path("verbose", opts), "%s", "");
3bd5f07101  260) write_file(state_dir_path("strategy", opts), "%s",
3bd5f07101  263) write_file(state_dir_path("strategy_opts", opts), "%s",
3bd5f07101  270) write_file(state_dir_path("gpg_sign_opt", opts), "%s",
3bd5f07101  273) write_file(state_dir_path("strategy", opts), "--signoff");
2ead83aefb  396) ret = -1;
2ead83aefb  397) goto leave_reset_head;
2ead83aefb  401) ret = error(_("could not determine HEAD revision"));
2ead83aefb  402) goto leave_reset_head;
2ead83aefb  423) ret = error(_("could not read index"));
2ead83aefb  424) goto leave_reset_head;
2ead83aefb  428) ret = error(_("failed to find tree of %s"),
2ead83aefb  430) goto leave_reset_head;
2ead83aefb  434) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
2ead83aefb  435) goto leave_reset_head;
2ead83aefb  447) ret = error(_("could not write index"));
2ead83aefb  448) goto leave_reset_head;
2ead83aefb  466) } else if (old_orig)
2ead83aefb  467) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
3bd5f07101  543) argv_array_push(&am.args, opts->gpg_sign_opt);
3bd5f07101  577) status = error_errno(_("could not write '%s'"),
3bd5f07101  579) free(rebased_patches);
3bd5f07101  580) argv_array_clear(&am.args);
3bd5f07101  581) return status;
3bd5f07101  590) argv_array_split(&format_patch.args,
3bd5f07101  591)  opts->git_format_patch_opt.buf);
3bd5f07101  599) unlink(rebased_patches);
3bd5f07101  600) free(rebased_patches);
3bd5f07101  601) argv_array_clear(&am.args);
3bd5f07101  603) reset_head(&opts->orig_head, "checkout", 
opts->head_name, 0,
3bd5f07101  605) error(_("\ngit encountered an error while preparing the "
3bd5f07101  612) strbuf_release(&revisions);
3bd5f07101  613) return status;
3bd5f07101  619) status = error_errno(_("could not read '%s'"),
3bd5f07101  621) free(rebased_patches);
3bd5f07101  622) argv_array_clear(&am.args);
3bd5f07101  623) return status;
3bd5f07101  635) argv_array_push(&am.args, opts->gpg_sign_opt);
81ef8ee75d  956) return -1;
d421afa0c6 1444) die(_("--reschedule-failed-exec requires an interactive 
rebase"));
d421afa0c6 1476) die(_("error: cannot combine '--preserve-merges' with "

builtin/receive-pack.c
01f9ec64c8 builtin/receive-pack.c 1587)     reader->line + 8);
01f9ec64c8 builtin/receive-pack.c 1621) die("protocol error: got an 
unexpected packet");

builtin/remote.c
f39a9c6547 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
f39a9c6547 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

commit-graph.c
aa658574bf  127) return NULL;
aa658574bf  130) return NULL;
aa658574bf  186) free(graph);
aa658574bf  187) return NULL;
aa658574bf  222) free(graph);
aa658574bf  223) return NULL;

config.c
7e43b32b58 1488) return git_ident_config(var, value, cb);
7e43b32b58 1491) return git_ident_config(var, value, cb);

diff.c
b73bcbac4a  308) ret = 0;
21536d077f  812)        (s[off] == '\r' && off < len - 1))
21536d077f  813) off++;
b73bcbac4a 5112) options->color_moved_ws_handling = 0;

entry.c
fetch-pack.c
01f9ec64c8  154) die(_("git fetch-pack: expected a flush packet after 
shallow list"));
01f9ec64c8  358) die(_("invalid shallow line: %s"), reader.line);
01f9ec64c8  364) die(_("invalid unshallow line: %s"), reader.line);
01f9ec64c8  366) die(_("object not found: %s"), reader.line);
01f9ec64c8  369) die(_("error in object: %s"), reader.line);
01f9ec64c8  371) die(_("no shallow found: %s"), reader.line);
01f9ec64c8  374) die(_("expected shallow/unshallow, got %s"), reader.line);
7d268894d4 1128) packet_buf_write(&req_buf, "sideband-all");
7d268894d4 1350) reader.use_sideband = 1;
7d268894d4 1351) reader.me = "fetch-pack";

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

http-push.c
ea82b2a085 1314) p = process_tree(lookup_tree(the_repository, &entry.oid),

http-walker.c
514c5fdd03 http-walker.c 550) loose_object_path(the_repository, &buf, 
&req->oid);

http.c
e6cf87b12d 1999) if (fflush(result)) {
e6cf87b12d 2000) error_errno("unable to flush a file");
e6cf87b12d 2001) return HTTP_START_FAILED;
e6cf87b12d 2003) rewind(result);
e6cf87b12d 2004) if (ftruncate(fileno(result), 0) < 0) {
e6cf87b12d 2005) error_errno("unable to truncate a file");
e6cf87b12d 2006) return HTTP_START_FAILED;
e6cf87b12d 2008) break;

ident.c
7e43b32b58 373) email = git_author_email.buf;
7e43b32b58 375) email = git_committer_email.buf;
7e43b32b58 394) name = git_author_name.buf;
7e43b32b58 396) name = git_committer_name.buf;
7e43b32b58 504) if (!value)
7e43b32b58 505) return config_error_nonbool(var);
7e43b32b58 506) strbuf_reset(&git_author_name);
7e43b32b58 507) strbuf_addstr(&git_author_name, value);
7e43b32b58 508) author_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b58 509) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b58 510) return 0;
7e43b32b58 514) if (!value)
7e43b32b58 515) return config_error_nonbool(var);
7e43b32b58 516) strbuf_reset(&git_author_email);
7e43b32b58 517) strbuf_addstr(&git_author_email, value);
7e43b32b58 518) author_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b58 519) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b58 520) return 0;
7e43b32b58 524) if (!value)
7e43b32b58 525) return config_error_nonbool(var);
7e43b32b58 526) strbuf_reset(&git_committer_name);
7e43b32b58 527) strbuf_addstr(&git_committer_name, value);
7e43b32b58 528) committer_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b58 529) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b58 530) return 0;
7e43b32b58 534) if (!value)
7e43b32b58 535) return config_error_nonbool(var);
7e43b32b58 536) strbuf_reset(&git_committer_email);
7e43b32b58 537) strbuf_addstr(&git_committer_email, value);
7e43b32b58 538) committer_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b58 539) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b58 540) return 0;

list-objects-filter.c
c813a7c35f 199) return;

match-trees.c
f55ac4311a 231) hashcpy(tree_oid.hash, rewrite_here);
f55ac4311a 232) status = splice_tree(&tree_oid, subpath, oid2, &subtree);

midx.c
e7a330ee26  428) close_pack(packs->info[packs->nr].p);
e7a330ee26  429) FREE_AND_NULL(packs->info[packs->nr].p);
14b7185175  815) error(_("did not see pack-file %s to drop"),
14b7185175  817) drop_index++;
14b7185175  818) missing_drops++;
14b7185175  819) i--;
14b7185175  826) result = 1;
14b7185175  827) goto cleanup;
14b7185175 1073) return 0;
14b7185175 1088) continue;
14b7185175 1091) continue;
17d0bf5a7d 1142) return 0;
17d0bf5a7d 1151) continue;
17d0bf5a7d 1164) continue;
17d0bf5a7d 1187) error(_("could not start pack-objects"));
17d0bf5a7d 1188) result = 1;
17d0bf5a7d 1189) goto cleanup;
17d0bf5a7d 1206) error(_("could not finish pack-objects"));
17d0bf5a7d 1207) result = 1;
17d0bf5a7d 1208) goto cleanup;

packfile.c
9133688752  369) strbuf_release(&buf);
9133688752  370) return;

pkt-line.c
7d268894d4 502) retval = demultiplex_sideband(reader->me, reader->buffer,
7d268894d4 504) switch (retval) {
7d268894d4 509) goto nonprogress_received;
7d268894d4 511) if (reader->pktlen != 1)
7d268894d4 512) goto nonprogress_received;
7d268894d4 518) break;
7d268894d4 522) }

pretty.c
ad6f028f06 1204) return 0;

read-cache.c
ee70c12820 1736) if (advice_unknown_index_extension) {
ee70c12820 1737) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1738) advise(_("This is likely due to the file having been 
written by a newer\n"

ref-filter.c
a9fb549b1d  467) return 0;

remote-curl.c
01f9ec64c8  427) die("invalid server response; got '%s'", reader.line);
01f9ec64c8  439) }
b79bdd8c12  576) return size;

send-pack.c
01f9ec64c8 143) return error(_("unable to parse remote unpack status: 
%s"), reader->line);
01f9ec64c8 162) error("invalid ref status from remote: %s", reader->line);
01f9ec64c8 579) receive_unpack_status(&reader);

sequencer.c
899b49c446 2394) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;
514c5fdd03 sha1-file.c 1291) status = error(_("unable to parse %s 
header"), oid_to_hex(oid));
00a7760e81 sha1-file.c 2305) the_hash_algo->final_fn(real_oid.hash, &c);
00a7760e81 sha1-file.c 2306) if (!oideq(expected_oid, &real_oid)) {

sideband.c
8553d661ee 127) suffix = ANSI_SUFFIX;
8553d661ee 137) strbuf_addf(&outbuf,
8553d661ee 139)     outbuf.len ? "\n" : "", me);
8553d661ee 140) retval = SIDEBAND_PROTOCOL_ERROR;
8553d661ee 141) goto cleanup;
7d268894d4 149) die("remote error: %s", buf + 1);
8553d661ee 196) strbuf_addf(&outbuf, "%s%s: protocol error: bad band #%d",
8553d661ee 197)     outbuf.len ? "\n" : "", me, band);
8553d661ee 198) retval = SIDEBAND_PROTOCOL_ERROR;
8553d661ee 199) break;
7d268894d4 204) die("%s", outbuf.buf);

submodule.c
26f80ccfc1 1398) strbuf_release(&gitdir);
be76c21282 1521) struct fetch_task *task = task_cb;
be76c21282 1525) fetch_task_release(task);

tree-walk.c
0a3faa45b1  530) oidcpy(result, &oid);

tree.c
38111b0e9d 104) commit = lookup_commit(r, &entry.oid);

upload-pack.c
87c2d9d310  149) sq_quote_buf(&buf, expanded_filter_spec.buf);
01f9ec64c8  432) die("git upload-pack: expected SHA1 list, got '%s'", 
reader->line);
7d268894d4 1066) allow_sideband_all = git_config_bool(var, value);
8aba257018 1306)      allow_sideband_all) &&
8aba257018 1307)     !strcmp(arg, "sideband-all")) {
7d268894d4 1308) data->writer.use_sideband = 1;
7d268894d4 1309) continue;
bc2e795cea 1441) deepen(&data->writer, INFINITE_DEPTH, 
data->deepen_relative,
8aba257018 1544)    &allow_sideband_all_value) &&

worktree.c
ebefff3c73 465) clear_repository_format(&format);

wrapper.c
e3b1e3bdc0 701) die_errno(_("could not stat %s"), filename);

Commits introducing uncovered code:
brian m. carlson      0a3faa45b: tree-walk: copy object ID before use
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
brian m. carlson      ea82b2a08: tree-walk: store object_id in a 
separate member
brian m. carlson      f55ac4311: match-trees: use hashcpy to splice trees
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Denton Liu      f39a9c654: remote: add --save-to-push option to git 
remote set-url
Derrick Stolee      14b718517: multi-pack-index: implement 'expire' 
subcommand
Derrick Stolee      17d0bf5a7: midx: implement midx_repack()
Derrick Stolee      334e9745a: multi-pack-index: prepare 'repack' subcommand
Derrick Stolee      913368875: repack: refactor pack deletion for future use
Derrick Stolee      e7a330ee2: midx: refactor permutation logic and pack 
sorting
Elijah Newren      899b49c44: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Issac Trotts      ad6f028f0: log: add %S option (like --source) to log 
--format
Jeff King      00a7760e8: sha1-file: modernize loose header/stream functions
Jeff King      514c5fdd0: sha1-file: modernize loose object file functions
Johannes Schindelin      2ead83aef: rebase: move `reset_head()` into a 
better spot
Johannes Schindelin      3bd5f0710: built-in rebase: call `git am` directly
Johannes Schindelin      81ef8ee75: rebase: introduce a shortcut for 
--reschedule-failed-exec
Johannes Schindelin      d421afa0c: rebase: introduce 
--reschedule-failed-exec
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Jonathan Tan      4316ff306: fetch-pack: support protocol version 2
Jonathan Tan      7d268894d: {fetch,upload}-pack: sideband v2 fetch response
Jonathan Tan      8553d661e: sideband: reverse its dependency on pkt-line
Jonathan Tan      8aba25701: tests: define GIT_TEST_SIDEBAND_ALL
Jonathan Tan      bc2e795ce: pkt-line: introduce struct packet_writer
Josh Steadmon      87c2d9d31: filter-options: expand scaled numbers
Josh Steadmon      aa658574b: commit-graph, fuzz: add fuzzer for 
commit-graph
Junio C Hamano      38111b0e9: Merge branch 'bc/tree-walk-oid' into jch
Martin Ågren      ebefff3c7: setup: add `clear_repository_format()`
Masaya Suzuki      01f9ec64c: Use packet_reader instead of packet_read_line
Masaya Suzuki      b79bdd8c1: remote-curl: unset CURLOPT_FAILONERROR
Masaya Suzuki      e6cf87b12: http: enable keep_error for HTTP requests
Matthew DeVore      c813a7c35: list-objects-filter: teach tree:# how to 
handle >0
Nickolai Belakovski      711d28e2e: branch: add an extra verbose output 
displaying worktree path for checked out branch
Nickolai Belakovski      a9fb549b1: ref-filter: add worktreepath atom
Phillip Wood      21536d077: diff --color-moved-ws: modify 
allow-indentation-change
Phillip Wood      b73bcbac4: diff: allow --no-color-moved-ws
Pranit Bauva      06f5608c1: bisect--helper: `bisect_start` shell 
function partially in C
Pranit Bauva      0f30233a1: bisect--helper: `bisect_write` shell 
function in C
Pranit Bauva      129a6cf34: bisect--helper: `bisect_next_check` shell 
function in C
Pranit Bauva      450ebb735: bisect--helper: `get_terms` & 
`bisect_terms` shell function in C
Pranit Bauva      4fbdbd5bf: bisect--helper: `check_and_set_terms` shell 
function in C
Pranit Bauva      5e82c3dd2: bisect--helper: `bisect_reset` shell 
function in C
Pranit Bauva      e3b1e3bdc: wrapper: move is_empty_file() and rename it 
as is_empty_or_missing_file()
Stefan Beller      26f80ccfc: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      be76c2128: fetch: ensure submodule objects fetched
Thomas Gummerer      091e04bc8: checkout: introduce --{,no-}overlay option
William Hubbs      7e43b32b5: Add author and committer configuration 
settings



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/fetch.c
e01378753d builtin/fetch.c 1481) die(_("--filter can only be used with 
the remote "
e01378753d builtin/fetch.c 1650) die(_("--filter can only be used with 
the remote "

builtin/submodule--helper.c
builtin/worktree.c
00a6d4d1d2 752) found_submodules = 1;
00a6d4d1d2 753) break;

commit-graph.c
ref-filter.c
1867ce6cbe  236) oi_deref.info.sizep = &oi_deref.size;
1867ce6cbe  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
33311fa1ad  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));

setup.c
07098b81a4 1093) if (!nongit_ok)
07098b81a4 1094) die(_("not a git repository (or any parent up to mount 
point %s)\n"
07098b81a4 1097) *nongit_ok = 1;
07098b81a4 1098) break;

transport-helper.c
3b3357626e 1029) static int has_attribute(const char *attrs, const char 
*attr)

Commits introducing uncovered code:
Christian Couder      e01378753: fetch: fix extensions.partialclone name 
in error message
Erin Dahlgren      07098b81a: Simplify handling of 
setup_git_directory_gently() failure cases.
Nguyễn Thái Ngọc Duy      00a6d4d1d: worktree: allow to (re)move 
worktrees with uninitialized submodules
Nguyễn Thái Ngọc Duy      3b3357626: style: the opening '{' of a 
function is in a separate line
Olga Telezhnaya      1867ce6cb: ref-filter: add objectsize:disk option
Olga Telezhnaya      33311fa1a: ref-filter: add deltabase option



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

pathspec.c
22af33bece 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
ec36c42a63 3498) const char *index = NULL;
ec36c42a63 3504) if (!offset)
ec36c42a63 3505) return NULL;
ec36c42a63 3506) while (offset <= mmap_size - the_hash_algo->rawsz - 8) {
ec36c42a63 3507) extsize = get_be32(mmap + offset + 4);
ec36c42a63 3508) if (CACHE_EXT((mmap + offset)) == 
CACHE_EXT_INDEXENTRYOFFSETTABLE) {
ec36c42a63 3509) index = mmap + offset + 4 + 4;
ec36c42a63 3510) break;
ec36c42a63 3512) offset += 8;
ec36c42a63 3513) offset += extsize;
ec36c42a63 3515) if (!index)
ec36c42a63 3516) return NULL;
ec36c42a63 3519) ext_version = get_be32(index);
ec36c42a63 3520) if (ext_version != IEOT_VERSION) {
ec36c42a63 3521) error("invalid IEOT version %d", ext_version);
ec36c42a63 3522) return NULL;
ec36c42a63 3524) index += sizeof(uint32_t);
ec36c42a63 3527) nr = (extsize - sizeof(uint32_t)) / (sizeof(uint32_t) + 
sizeof(uint32_t));
ec36c42a63 3528) if (!nr) {
ec36c42a63 3529) error("invalid number of IEOT entries %d", nr);
ec36c42a63 3530) return NULL;
ec36c42a63 3532) ieot = xmalloc(sizeof(struct index_entry_offset_table)
ec36c42a63 3533)        + (nr * sizeof(struct index_entry_offset)));
ec36c42a63 3534) ieot->nr = nr;
ec36c42a63 3535) for (i = 0; i < nr; i++) {
ec36c42a63 3536) ieot->entries[i].offset = get_be32(index);
ec36c42a63 3537) index += sizeof(uint32_t);
ec36c42a63 3538) ieot->entries[i].nr = get_be32(index);
ec36c42a63 3539) index += sizeof(uint32_t);
ec36c42a63 3542) return ieot;

tree.c
e092073d64 104) commit = lookup_commit(r, entry.oid);

Commits introducing uncovered code:
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths
Nguyễn Thái Ngọc Duy      22af33bec: dir.c: move, rename and export 
match_attrs()
Nguyễn Thái Ngọc Duy      e092073d6: tree.c: make read_tree*() take 
'struct repository *'
Nguyễn Thái Ngọc Duy      ec36c42a6: Indent code with TABs



^ permalink raw reply	[relevance 2%]

* Re: [PATCH] FYI / RFC: submodules: introduce repo-like workflow
  @ 2019-01-14 22:34 19% ` Jonathan Nieder
  0 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2019-01-14 22:34 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Hi,

Stefan Beller wrote:

> Internally we have rolled out this as an experiment for
> "submodules replacing the repo tool[1]".

Thanks again for writing and explaining it.  Here's an updated
version, basically identical (just rebased).  "git range-diff" shows
mostly context lines affected, so this really is a minor update.

I suspect the *next* time this hits the list will be more interesting,
since we can start making use of the repository API.

Thoughts of all kinds welcome, as always.

-- >8 --
From: Stefan Beller <sbeller@google.com>
Date: Mon, 4 Dec 2017 15:47:40 -0800

Internally we have rolled out this as an experiment for
"submodules replacing the repo tool[1]". The repo tool is described as:

    Repo unifies Git repositories when necessary, performs uploads to the
    Gerrit revision control system, and automates parts of the Android
    development workflow. Repo is not meant to replace Git, only to make
    it easier to work with Git in the context of Android. The repo command
    is an executable Python script that you can put anywhere in your path.

    In working with the Android source files, you use Repo for
    across-network operations. For example, with a single Repo command you
    can download files from multiple repositories into your local working
    directory.

    In most situations, you can use Git instead of Repo, or mix Repo and
    Git commands to form complex commands.

[1] https://source.android.com/setup/develop/

Submodules can also be understood as unifying Git repositories, even more,
in the superproject the submodules have relationships between their
versions, which the repo tool only provides in releases.

The repo tool does not provide these relationships between versions, but
all the repositories (in case of Android think of ~1000 git repositories)
are put in their place without depending on each other.

This comes with a couple of advantages and disadvantages:

* Many users are familiar with Git, but not submodules. Each repository
  can be used independently with Git and there is no need to update the
  superproject or the repo manifest for a change in a repository.
* It is easy to work with repositories with no version-control-dependencies
  if there are dependencies in the code. In case of Android the
  repositories are bound at natural boundaries. For example the linux
  kernel is one repository, as then upstream work is made easy for this
  repository. So it is desirable to keep an easy-as-repo workflow.
* Fetching changes ("repo sync") needs to fetch all repositories, as there
  is no central place that tracks what has changed. In a superproject
  git fetch can determine which submodules need fetching.  In Androids
  case the daily change is only in a few repositories (think 10s), so
  migrating to a superproject would save an order of magnitude in fetch
  traffic for daily updates of developers.
* Sometimes when the dependencies are not on a clear repository boundary
  one would like to have git-bisect available across the different
  repositories, which repo cannot provide due to its design.

Internally we have the Gerrit as a central point, where the source of
truth is found for a given repository.

This patch adds a new mode to submodule handling, where the superproject
controls the existence of the submodule (just as current submodule
handling), but the submodule HEAD is not detached, but following the same
branch name as the superproject.

Current situation visualized:

  superproject
  HEAD -> "<branch name>" -> OID
                              |
  submodule                   v
  HEAD --------------------> OID

The OID in the submodule is controlled via the HEAD in the submodule that
is set accordingly to the gitlink in the superproject. Confusion can arise
when the (detached) HEAD in the submodule doesn't match the superprojects
gitlink.

This patch visualized:

  superproject
  HEAD -> "<branch name>" -> OID
                 |
  submodule      v
  HEAD -> "<branch name>" -> OID

As there is a central point of truth in our setup (our Gerrit installation)
which keeps the superproject and the submodule branches in sync, this
ought to look the same for the user; removing the "detached HEAD" in the
submodule. git-status will still notice if there is an OID mismatch between
the gitlink and the submodules branch, but that is a race condition and
should be caught by Gerrit.

This changes the following commands in the superproject:

  checkout -B/-b create branches in subs, too
  checkout (-f): update branch in submodule (create if needed) and check
                 it out; Pass the argument down literally if it is a branch
                 name (e.g. "checkout -f master" will run a
                            "checkout -f master" in the submodule as well)
  clone: see checkout
  reset --hard: see checkout

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 Documentation/git-checkout.txt | 13 +++--
 Makefile                       |  1 +
 branch.c                       | 84 +++++++++++++++++++++++++++++++++
 builtin.h                      |  1 +
 builtin/branch.c               | 35 ++++++++++++++
 builtin/checkout.c             | 76 ++++++++++++++++++++++++------
 builtin/clone.c                | 12 ++++-
 builtin/reset.c                | 41 ++++++++++++++--
 entry.c                        | 51 +++++++++++++-------
 git-submodule.sh               | 24 +++++++++-
 git.c                          |  1 +
 submodule-move-head.c          | 81 ++++++++++++++++++++++++++++++++
 submodule-move-head.h          | 22 +++++++++
 submodule.c                    | 14 ++++++
 submodule.h                    |  8 +++-
 t/lib-submodule-update.sh      | 86 +++++++++++++++++++++++++++++++++-
 t/t1013-read-tree-submodule.sh |  1 +
 t/t2013-checkout-submodule.sh  |  4 ++
 t/t7112-reset-submodule.sh     |  5 ++
 unpack-trees.c                 | 20 ++++++--
 unpack-trees.h                 |  9 ++++
 21 files changed, 536 insertions(+), 53 deletions(-)
 create mode 100644 submodule-move-head.c
 create mode 100644 submodule-move-head.h

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 6acc3d98e7..d9ca9e9e24 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -268,13 +268,12 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
 	worktree.
 
 --[no-]recurse-submodules::
-	Using --recurse-submodules will update the content of all initialized
-	submodules according to the commit recorded in the superproject. If
-	local modifications in a submodule would be overwritten the checkout
-	will fail unless `-f` is used. If nothing (or --no-recurse-submodules)
-	is used, the work trees of submodules will not be updated.
-	Just like linkgit:git-submodule[1], this will detach the
-	submodules HEAD.
+	Using --recurse-submodules will update the content and current
+	branch of all initialized submodules in addition to the
+	superproject. If local modifications in a submodule would be
+	overwritten, the checkout will fail unless `-f` is used. If
+	nothing (or --no-recurse-submodules) is used, the work trees of
+	submodules will not be updated.
 
 --no-guess::
 	Do not attempt to create a branch if a remote tracking branch
diff --git a/Makefile b/Makefile
index 1a44c811aa..132c336bbf 100644
--- a/Makefile
+++ b/Makefile
@@ -989,6 +989,7 @@ LIB_OBJS += streaming.o
 LIB_OBJS += string-list.o
 LIB_OBJS += submodule.o
 LIB_OBJS += submodule-config.o
+LIB_OBJS += submodule-move-head.o
 LIB_OBJS += sub-process.o
 LIB_OBJS += symlinks.o
 LIB_OBJS += tag.o
diff --git a/branch.c b/branch.c
index 28b81a7e02..9212a0a256 100644
--- a/branch.c
+++ b/branch.c
@@ -1,9 +1,13 @@
 #include "git-compat-util.h"
 #include "cache.h"
 #include "config.h"
+#include "repository.h"
+#include "submodule.h"
 #include "branch.h"
 #include "refs.h"
 #include "refspec.h"
+#include "tree-walk.h"
+#include "run-command.h"
 #include "remote.h"
 #include "commit.h"
 #include "worktree.h"
@@ -242,6 +246,76 @@ N_("\n"
 "will track its remote counterpart, you may want to use\n"
 "\"git push -u\" to set the upstream config as you push.");
 
+static void create_branch_in_submodule(const char *name, const char *start_name,
+		   const char *start_ref, const struct object_id *start_oid,
+		   int force, int reflog, int clobber_head,
+		   int quiet, enum branch_track track,
+		   int checking_out_branch,
+		   const char *sub_path, const struct object_id *entry_oid)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+
+	trace_printf("create_branch_in_submodule %s", sub_path);
+
+	prepare_submodule_repo_env(&cp.env_array);
+	cp.git_cmd = 1;
+	cp.dir = sub_path;
+	argv_array_push(&cp.args, "branch--helper");
+	argv_array_pushf(&cp.args, "--name=%s", name);
+	if (checking_out_branch) {
+		argv_array_pushf(&cp.args, "--start_name=%s",
+				 start_ref);
+	} else {
+		argv_array_pushf(&cp.args, "--start_name=%s",
+				 oid_to_hex(entry_oid));
+	}
+	argv_array_pushf(&cp.args, "--force=%d", force);
+	argv_array_pushf(&cp.args, "--reflog=%d", reflog);
+	argv_array_pushf(&cp.args, "--clobber_head=%d", clobber_head);
+	argv_array_pushf(&cp.args, "--quiet=%d", quiet);
+	argv_array_pushf(&cp.args, "--track=%d", track);
+
+	if (run_command(&cp))
+		fprintf(stderr, "process for submodule '%s' failed", sub_path);
+	child_process_clear(&cp);
+}
+
+static void create_branch_in_submodules(const char *name, const char *start_name,
+		   const char *start_ref, const struct object_id *start_oid,
+		   int force, int reflog, int clobber_head,
+		   int quiet, enum branch_track track, struct strbuf *rec_path)
+{
+
+	int checking_out_branch = start_ref && starts_with(start_ref, "refs/heads/");
+	void *buf;
+	struct tree_desc tree;
+	struct name_entry entry;
+	int rec_path_len = rec_path->len;
+
+	buf = fill_tree_descriptor(&tree, start_oid);
+	if (!buf)
+		die("could not read %s for checkout", start_name);
+
+	while (tree_entry(&tree, &entry)) {
+
+		if (rec_path->len > 0)
+			strbuf_addch(rec_path, '/');
+		strbuf_addstr(rec_path, entry.path);
+
+		trace_printf("create_branch_in_submodules %s %o", rec_path->buf, entry.mode);
+
+		if (S_ISGITLINK(entry.mode) && is_submodule_active(the_repository, rec_path->buf))
+			create_branch_in_submodule(name, start_name, start_ref,
+						start_oid, force, reflog, clobber_head,
+						quiet, track, checking_out_branch, rec_path->buf, entry.oid);
+		else if (S_ISDIR(entry.mode)) {
+			create_branch_in_submodules(name, start_name, start_ref, entry.oid, force, reflog, clobber_head, quiet, track, rec_path);
+		}
+		strbuf_setlen(rec_path, rec_path_len);
+	}
+	free(buf);
+}
+
 void create_branch(struct repository *r,
 		   const char *name, const char *start_name,
 		   int force, int clobber_head_ok, int reflog,
@@ -251,6 +325,7 @@ void create_branch(struct repository *r,
 	struct object_id oid;
 	char *real_ref;
 	struct strbuf ref = STRBUF_INIT;
+	struct strbuf sub_path = STRBUF_INIT;
 	int forcing = 0;
 	int dont_change_ref = 0;
 	int explicit_tracking = 0;
@@ -308,6 +383,14 @@ void create_branch(struct repository *r,
 	if (reflog)
 		log_all_ref_updates = LOG_REFS_NORMAL;
 
+	/*
+	 * NEEDSWORK: Doesn't handle errors part-way through very well.
+	 */
+	trace_printf("create_branch need to update subs: %d", should_update_submodules());
+	if (behave_google_repo_like() && should_update_submodules())
+		create_branch_in_submodules(name, start_name, real_ref, &oid,
+					    force, reflog, clobber_head_ok, quiet, track, &sub_path);
+
 	if (!dont_change_ref) {
 		struct ref_transaction *transaction;
 		struct strbuf err = STRBUF_INIT;
@@ -334,6 +417,7 @@ void create_branch(struct repository *r,
 		setup_tracking(ref.buf + 11, real_ref, track, quiet);
 
 	strbuf_release(&ref);
+	strbuf_release(&sub_path);
 	free(real_ref);
 }
 
diff --git a/builtin.h b/builtin.h
index 6538932e99..68dc715392 100644
--- a/builtin.h
+++ b/builtin.h
@@ -135,6 +135,7 @@ extern int cmd_archive(int argc, const char **argv, const char *prefix);
 extern int cmd_bisect__helper(int argc, const char **argv, const char *prefix);
 extern int cmd_blame(int argc, const char **argv, const char *prefix);
 extern int cmd_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_branch_helper(int argc, const char **argv, const char *prefix);
 extern int cmd_bundle(int argc, const char **argv, const char *prefix);
 extern int cmd_cat_file(int argc, const char **argv, const char *prefix);
 extern int cmd_checkout(int argc, const char **argv, const char *prefix);
diff --git a/builtin/branch.c b/builtin/branch.c
index 1be727209b..6ee45cbbaa 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -36,6 +36,11 @@ static const char * const builtin_branch_usage[] = {
 	NULL
 };
 
+static const char * const builtin_branch_helper_usage[] = {
+	N_("git branch--helper"),
+	NULL
+};
+
 static const char *head;
 static struct object_id head_oid;
 
@@ -578,6 +583,36 @@ static int edit_branch_description(const char *branch_name)
 	return 0;
 }
 
+int cmd_branch_helper(int argc, const char **argv, const char *prefix)
+{
+	const char *name = NULL, *start_name = NULL;
+	int force = 0, reflog = 0, clobber_head = 0, quiet = 0;
+	enum branch_track track = BRANCH_TRACK_NEVER;
+
+	struct option options[] = {
+		OPT_STRING(0, "name", &name, N_(""), N_("")),
+		OPT_STRING(0, "start_name", &start_name, N_(""), N_("")),
+
+		OPT_INTEGER(0, "force", &force, N_("")),
+		OPT_INTEGER(0, "reflog", &reflog, N_("")),
+		OPT_INTEGER(0, "clobber_head", &clobber_head, N_("")),
+		OPT_INTEGER(0, "quiet", &quiet, N_("")),
+
+		/* implicit int -> enum conversion */
+		OPT_INTEGER(0, "track", &track, N_("")),
+		OPT_END(),
+	};
+
+	argc = parse_options(argc, argv, prefix, options,
+			     builtin_branch_helper_usage, 0);
+	if (argc > 0)
+		die (_("branchhelper doesn't know about %s"), argv[0]);
+
+	create_branch(the_repository, name, start_name, force, clobber_head,
+		      reflog, quiet, track);
+	return 0;
+}
+
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
 	int delete = 0, rename = 0, copy = 0, force = 0, list = 0;
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 08b0ac48f3..5a8a4e200f 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -3,6 +3,7 @@
 #include "checkout.h"
 #include "lockfile.h"
 #include "parse-options.h"
+#include "repository.h"
 #include "refs.h"
 #include "object-store.h"
 #include "commit.h"
@@ -22,6 +23,7 @@
 #include "ll-merge.h"
 #include "resolve-undo.h"
 #include "submodule-config.h"
+#include "submodule-move-head.h"
 #include "submodule.h"
 #include "advice.h"
 
@@ -422,11 +424,24 @@ static void describe_detached_head(const char *msg, struct commit *commit)
 	strbuf_release(&sb);
 }
 
-static int reset_tree(struct tree *tree, const struct checkout_opts *o,
+struct branch_info {
+	const char *name; /* The short name used */
+	const char *path; /* The full name of a real branch */
+	struct commit *commit; /* The named commit */
+	/*
+	 * if not null the branch is detached because it's already
+	 * checked out in this checkout
+	 */
+	char *checkout;
+};
+
+static int reset_tree(struct branch_info *b, const struct checkout_opts *o,
 		      int worktree, int *writeout_error)
 {
 	struct unpack_trees_options opts;
+	struct submodule_move_head_options move_head_opts;
 	struct tree_desc tree_desc;
+	struct tree *tree = get_commit_tree(b->commit);
 
 	memset(&opts, 0, sizeof(opts));
 	opts.head_idx = -1;
@@ -438,6 +453,16 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
 	opts.verbose_update = o->show_progress;
 	opts.src_index = &the_index;
 	opts.dst_index = &the_index;
+
+	if (behave_google_repo_like()) {
+		opts.move_head = unpack_trees_move_head;
+		memset(&move_head_opts, 0, sizeof(move_head_opts));
+		move_head_opts.force = 1;
+		move_head_opts.new_ref = b->path;
+		move_head_opts.target_ref = o->force_detach ? NULL : b->path;
+		opts.unpack_data = &move_head_opts;
+	}
+
 	parse_tree(tree);
 	init_tree_desc(&tree_desc, tree->buffer, tree->size);
 	switch (unpack_trees(1, &tree_desc, &opts)) {
@@ -457,17 +482,6 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
 	}
 }
 
-struct branch_info {
-	const char *name; /* The short name used */
-	const char *path; /* The full name of a real branch */
-	struct commit *commit; /* The named commit */
-	/*
-	 * if not null the branch is detached because it's already
-	 * checked out in this checkout
-	 */
-	char *checkout;
-};
-
 static void setup_branch_path(struct branch_info *branch)
 {
 	struct strbuf buf = STRBUF_INIT;
@@ -586,7 +600,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
 
 	resolve_undo_clear();
 	if (opts->force) {
-		ret = reset_tree(get_commit_tree(new_branch_info->commit),
+		ret = reset_tree(new_branch_info,
 				 opts, 1, writeout_error);
 		if (ret)
 			return ret;
@@ -594,6 +608,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
 		struct tree_desc trees[2];
 		struct tree *tree;
 		struct unpack_trees_options topts;
+		struct submodule_move_head_options mopts;
 
 		memset(&topts, 0, sizeof(topts));
 		topts.head_idx = -1;
@@ -609,6 +624,16 @@ static int merge_working_tree(const struct checkout_opts *opts,
 			return 1;
 		}
 
+		if (behave_google_repo_like()) {
+			topts.move_head = unpack_trees_move_head;
+			memset(&mopts, 0, sizeof(mopts));
+			mopts.old_ref = old_branch_info->path;
+			mopts.new_ref = new_branch_info->path;
+			mopts.target_ref = opts->force_detach
+					? NULL : new_branch_info->path;
+			topts.unpack_data = &mopts;
+		}
+
 		/* 2-way merge to the new branch */
 		topts.initial_checkout = is_cache_unborn();
 		topts.update = 1;
@@ -674,7 +699,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
 			o.verbosity = 0;
 			work = write_tree_from_memory(&o);
 
-			ret = reset_tree(get_commit_tree(new_branch_info->commit),
+			ret = reset_tree(new_branch_info,
 					 opts, 1,
 					 writeout_error);
 			if (ret)
@@ -689,7 +714,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
 					  &result);
 			if (ret < 0)
 				exit(128);
-			ret = reset_tree(get_commit_tree(new_branch_info->commit),
+			ret = reset_tree(new_branch_info,
 					 opts, 0,
 					 writeout_error);
 			strbuf_release(&o.obuf);
@@ -724,6 +749,18 @@ static void report_tracking(struct branch_info *new_branch_info)
 	strbuf_release(&sb);
 }
 
+static void create_symref_in_submodules(const char *symref, const char *target, const char *logmsg)
+{
+	int i = 0;
+	for (i = 0; i < active_nr; i++) {
+		const struct cache_entry *ce = active_cache[i];
+		if (!S_ISGITLINK(ce->ce_mode) || !is_submodule_active(the_repository, ce->name))
+			continue;
+
+		create_symref_in_submodule(ce->name, symref, target, logmsg);
+	}
+}
+
 static void update_refs_for_switch(const struct checkout_opts *opts,
 				   struct branch_info *old_branch_info,
 				   struct branch_info *new_branch_info)
@@ -734,6 +771,9 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
 		if (opts->new_orphan_branch) {
 			char *refname;
 
+			if (should_update_submodules())
+				die("--orphan --recurse-submodules is not implemented");
+
 			refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch);
 			if (opts->new_branch_log &&
 			    !should_autocreate_reflog(refname)) {
@@ -787,6 +827,12 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
 			describe_detached_head(_("HEAD is now at"), new_branch_info->commit);
 		}
 	} else if (new_branch_info->path) {	/* Switch branches. */
+		/*
+		 * NEEDSWORK: We don't handle attachment on checkout <branch>
+		 * yet.
+		 */
+		if (opts->new_branch && should_update_submodules() && behave_google_repo_like())
+			create_symref_in_submodules("HEAD", new_branch_info->path, msg.buf);
 		if (create_symref("HEAD", new_branch_info->path, msg.buf) < 0)
 			die(_("unable to update HEAD"));
 		if (!opts->quiet) {
diff --git a/builtin/clone.c b/builtin/clone.c
index 7c7f98c72c..c91ec0f5f0 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -28,6 +28,7 @@
 #include "run-command.h"
 #include "connected.h"
 #include "packfile.h"
+#include "submodule.h"
 #include "list-objects-filter-options.h"
 #include "object-store.h"
 
@@ -744,7 +745,6 @@ static int checkout(int submodule_progress)
 		if (!starts_with(head, "refs/heads/"))
 			die(_("HEAD not found below refs/heads!"));
 	}
-	free(head);
 
 	/* We need to be in the new work tree for the checkout */
 	setup_work_tree();
@@ -773,8 +773,17 @@ static int checkout(int submodule_progress)
 			   oid_to_hex(&oid), "1", NULL);
 
 	if (!err && (option_recurse_submodules.nr > 0)) {
+		const char *branch;
 		struct argv_array args = ARGV_ARRAY_INIT;
 		argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
+		if (behave_google_repo_like()) {
+			if (!strcmp(head, "HEAD"))
+				; /* detach HEAD in submodules, too. */
+			else if (skip_prefix(head, "refs/heads/", &branch))
+				argv_array_pushl(&args, "--checkout-branch", branch, NULL);
+			else
+				BUG("HEAD not found below refs/heads!");
+		}
 
 		if (option_shallow_submodules == 1)
 			argv_array_push(&args, "--depth=1");
@@ -792,6 +801,7 @@ static int checkout(int submodule_progress)
 		argv_array_clear(&args);
 	}
 
+	free(head);
 	return err;
 }
 
diff --git a/builtin/reset.c b/builtin/reset.c
index 59898c972e..108b2b97c7 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -24,6 +24,7 @@
 #include "cache-tree.h"
 #include "submodule.h"
 #include "submodule-config.h"
+#include "submodule-move-head.h"
 
 #define REFRESH_INDEX_DELAY_WARNING_IN_MS (2 * 1000)
 
@@ -44,12 +45,16 @@ static inline int is_merge(void)
 	return !access(git_path_merge_head(the_repository), F_OK);
 }
 
-static int reset_index(const struct object_id *oid, int reset_type, int quiet)
+static int reset_index(const char *rev, const struct object_id *oid, int reset_type, int quiet)
 {
-	int i, nr = 0;
+	int i, nr = 0, flags = 0;
 	struct tree_desc desc[2];
 	struct tree *tree;
 	struct unpack_trees_options opts;
+	struct submodule_move_head_options mopts;
+	char *current_branch = NULL;
+	struct object_id discard;
+	char *new_ref = NULL;
 	int ret = -1;
 
 	memset(&opts, 0, sizeof(opts));
@@ -67,6 +72,31 @@ static int reset_index(const struct object_id *oid, int reset_type, int quiet)
 		break;
 	case HARD:
 		opts.update = 1;
+
+		if (behave_google_repo_like()) {
+			/*
+			 * Submodule handling:
+			 * - unless we are detached, attach HEAD in submodules
+			 * - if rev is a branch name, use that branch instead of oid in
+			 *   submodules.
+			 */
+			current_branch = resolve_refdup("HEAD", 0, NULL, &flags);
+			if (!(flags & REF_ISSYMREF))
+				current_branch = NULL;
+			if (dwim_ref(rev, strlen(rev), &discard, &new_ref) != 1 ||
+			    !starts_with(new_ref, "refs/heads/")) {
+				free(new_ref);
+				new_ref = NULL;
+			}
+
+			opts.move_head = unpack_trees_move_head;
+
+			memset(&mopts, 0, sizeof(mopts));
+			mopts.force = 1;
+			mopts.new_ref = new_ref;
+			mopts.target_ref = current_branch;
+			opts.unpack_data = &mopts;
+		}
 		/* fallthrough */
 	default:
 		opts.reset = 1;
@@ -103,6 +133,8 @@ static int reset_index(const struct object_id *oid, int reset_type, int quiet)
 out:
 	for (i = 0; i < nr; i++)
 		free((void *)desc[i].buffer);
+	free(current_branch);
+	free(new_ref);
 	return ret;
 }
 
@@ -321,6 +353,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
 		oidcpy(&oid, the_hash_algo->empty_tree);
 	} else if (!pathspec.nr) {
 		struct commit *commit;
+
 		if (get_oid_committish(rev, &oid))
 			die(_("Failed to resolve '%s' as a valid revision."), rev);
 		commit = lookup_commit_reference(the_repository, &oid);
@@ -393,9 +426,9 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
 				}
 			}
 		} else {
-			int err = reset_index(&oid, reset_type, quiet);
+			int err = reset_index(rev, &oid, reset_type, quiet);
 			if (reset_type == KEEP && !err)
-				err = reset_index(&oid, MIXED, quiet);
+				err = reset_index(rev, &oid, MIXED, quiet);
 			if (err)
 				die(_("Could not reset index file to revision '%s'."), rev);
 		}
diff --git a/entry.c b/entry.c
index 0a3c451f5f..7943602f13 100644
--- a/entry.c
+++ b/entry.c
@@ -2,11 +2,23 @@
 #include "blob.h"
 #include "object-store.h"
 #include "dir.h"
+#include "unpack-trees.h"
 #include "streaming.h"
 #include "submodule.h"
 #include "progress.h"
 #include "fsmonitor.h"
 
+/* NEEDSWORK: share code with unpack-trees.c */
+static int move_head(const struct unpack_trees_options *o, const char *path, const char *old, const char *new, unsigned flags)
+{
+	if (behave_google_repo_like()) {
+		if (!o || !o->move_head)
+			return submodule_move_head(path, old, new, flags);
+		return o->move_head(o, path, old, new, flags);
+	} else
+		return submodule_move_head(path, old, new, flags);
+}
+
 static void create_directories(const char *path, int path_len,
 			       const struct checkout *state)
 {
@@ -251,7 +263,7 @@ int finish_delayed_checkout(struct checkout *state)
 	return errs;
 }
 
-static int write_entry(struct cache_entry *ce,
+static int write_entry(struct unpack_trees_options *o, struct cache_entry *ce,
 		       char *path, const struct checkout *state, int to_tempfile)
 {
 	unsigned int ce_mode_s_ifmt = ce->ce_mode & S_IFMT;
@@ -357,7 +369,7 @@ static int write_entry(struct cache_entry *ce,
 			return error("cannot create submodule directory %s", path);
 		sub = submodule_from_ce(ce);
 		if (sub)
-			return submodule_move_head(ce->name,
+			return move_head(o, ce->name,
 				NULL, oid_to_hex(&ce->oid),
 				state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
 		break;
@@ -427,22 +439,15 @@ static void mark_colliding_entries(const struct checkout *state,
 	}
 }
 
-/*
- * Write the contents from ce out to the working tree.
- *
- * When topath[] is not NULL, instead of writing to the working tree
- * file named by ce, a temporary file is created by this function and
- * its name is returned in topath[], which must be able to hold at
- * least TEMPORARY_FILENAME_LENGTH bytes long.
- */
-int checkout_entry(struct cache_entry *ce,
-		   const struct checkout *state, char *topath)
+int unpack_trees_checkout_entry(struct unpack_trees_options *o,
+				struct cache_entry *ce,
+				const struct checkout *state, char *topath)
 {
 	static struct strbuf path = STRBUF_INIT;
 	struct stat st;
 
 	if (topath)
-		return write_entry(ce, topath, state, 1);
+		return write_entry(o, ce, topath, state, 1);
 
 	strbuf_reset(&path);
 	strbuf_add(&path, state->base_dir, state->base_dir_len);
@@ -466,10 +471,10 @@ int checkout_entry(struct cache_entry *ce,
 				if (!(st.st_mode & S_IFDIR))
 					unlink_or_warn(ce->name);
 
-				return submodule_move_head(ce->name,
+				return move_head(o, ce->name,
 					NULL, oid_to_hex(&ce->oid), 0);
 			} else
-				return submodule_move_head(ce->name,
+				return move_head(o, ce->name,
 					"HEAD", oid_to_hex(&ce->oid),
 					state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
 		}
@@ -506,5 +511,19 @@ int checkout_entry(struct cache_entry *ce,
 		return 0;
 
 	create_directories(path.buf, path.len, state);
-	return write_entry(ce, path.buf, state, 0);
+	return write_entry(o, ce, path.buf, state, 0);
+}
+
+/*
+ * Write the contents from ce out to the working tree.
+ *
+ * When topath[] is not NULL, instead of writing to the working tree
+ * file named by ce, a temporary file is created by this function and
+ * its name is returned in topath[], which must be able to hold at
+ * least TEMPORARY_FILENAME_LENGTH bytes long.
+ */
+int checkout_entry(struct cache_entry *ce,
+		   const struct checkout *state, char *topath)
+{
+	return unpack_trees_checkout_entry(NULL, ce, state, topath);
 }
diff --git a/git-submodule.sh b/git-submodule.sh
index 5e608f8bad..1d228c9df7 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -434,6 +434,18 @@ fetch_in_submodule () (
 	esac
 )
 
+# usage: checkout_in_submoodule "$sm_path" "$command" "${branch:-}" "$rev"
+checkout_in_submodule () (
+	sanitize_submodule_env &&
+	cd "$1" &&
+	if test -n "$3"
+	then
+		$2 -B "$3" "$4"
+	else
+		$2 "$4"
+	fi
+)
+
 #
 # Update each submodule path to correct revision, using clone and checkout as needed
 #
@@ -486,6 +498,11 @@ cmd_update()
 		--recursive)
 			recursive=1
 			;;
+		--checkout-branch)
+			update="checkout"
+			checkout_dest=$2
+			shift
+			;;
 		--checkout)
 			update="checkout"
 			;;
@@ -602,6 +619,11 @@ cmd_update()
 				die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")"
 			fi
 
+			if test -n "$checkout_dest" && test "$update_module" != checkout
+			then
+				die "Cannot use --checkout-branch with update mode '$update_module'"
+			fi
+
 			must_die_on_failure=
 			case "$update_module" in
 			checkout)
@@ -631,7 +653,7 @@ cmd_update()
 				die "$(eval_gettext "Invalid update mode '$update_module' for submodule path '$path'")"
 			esac
 
-			if (sanitize_submodule_env; cd "$sm_path" && $command "$sha1")
+			if checkout_in_submodule "$sm_path" "$command" "$checkout_dest" "$sha1"
 			then
 				say "$say_msg"
 			elif test -n "$must_die_on_failure"
diff --git a/git.c b/git.c
index 4d53a3d50d..3f13b4e7cf 100644
--- a/git.c
+++ b/git.c
@@ -450,6 +450,7 @@ static struct cmd_struct commands[] = {
 	{ "bisect--helper", cmd_bisect__helper, RUN_SETUP },
 	{ "blame", cmd_blame, RUN_SETUP },
 	{ "branch", cmd_branch, RUN_SETUP | DELAY_PAGER_CONFIG },
+	{ "branch--helper", cmd_branch_helper, RUN_SETUP },
 	{ "bundle", cmd_bundle, RUN_SETUP_GENTLY | NO_PARSEOPT },
 	{ "cat-file", cmd_cat_file, RUN_SETUP },
 	{ "check-attr", cmd_check_attr, RUN_SETUP },
diff --git a/submodule-move-head.c b/submodule-move-head.c
new file mode 100644
index 0000000000..4c8f49066f
--- /dev/null
+++ b/submodule-move-head.c
@@ -0,0 +1,81 @@
+#include "cache.h"
+#include "submodule-move-head.h"
+#include "repository.h"
+#include "submodule.h"
+#include "refs.h"
+#include "unpack-trees.h"
+#include "run-command.h"
+
+void create_symref_in_submodule(const char *path, const char *symref, const char *target, const char *logmsg)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+
+	/* NEEDSWORK: What about sub-submodules? */
+	prepare_submodule_repo_env(&cp.env_array);
+	cp.git_cmd = 1;
+	cp.dir = path;
+	argv_array_pushl(&cp.args, "symbolic-ref", "-m", logmsg, symref, target, NULL);
+
+	if (run_command(&cp))
+		die("process for submodule '%s' failed", path);
+}
+
+static void create_ref_in_submodule(const char *path, const char *ref, const char *value)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+
+	/* NEEDSWORK: set a reasonable reflog message. */
+	prepare_submodule_repo_env(&cp.env_array);
+	cp.git_cmd = 1;
+	cp.dir = path;
+	argv_array_pushl(&cp.args, "update-ref", ref, value, sha1_to_hex(null_sha1), NULL);
+
+	if (run_command(&cp))
+		die("process for submodule '%s' failed", path);
+}
+
+static int ref_exists_in_submodule(const char *submodule_path, const char *refname)
+{
+	struct ref_store *refs = get_submodule_ref_store(submodule_path);
+	if (!refs)
+		return 0;
+	return refs_resolve_ref_unsafe(refs, refname, RESOLVE_REF_READING, NULL, NULL) != NULL;
+}
+
+int unpack_trees_move_head(const struct unpack_trees_options *opt, const char *path, const char *old, const char *new, unsigned flags)
+{
+	struct submodule_move_head_options *o = opt->unpack_data;
+	const char *new_ref = o->new_ref;
+	const char *target_ref = o->target_ref;
+	const char *old_commit = old;
+	const char *new_commit = new;
+
+	/*
+	 * NEEDSWORK:
+	 * - set log message
+	 * - what about sub-submodules?
+	 */
+
+	if (!is_submodule_active(the_repository, path))
+		return 0;
+
+	if (old) {
+		if (o->force)
+			old_commit = "HEAD";
+		else if (o->old_ref && ref_exists_in_submodule(path, o->old_ref))
+			old_commit = o->old_ref;
+	}
+	if (new_ref && new && ref_exists_in_submodule(path, new_ref))
+		new_commit = new_ref;
+
+	if (target_ref)
+		flags |= SUBMODULE_MOVE_HEAD_SKIP_REF_UPDATE;
+	if (submodule_move_head(path, old_commit, new_commit, flags) < 0)
+		return -1;
+	if (new && target_ref && !(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
+		if (!ref_exists_in_submodule(path, target_ref))
+			create_ref_in_submodule(path, target_ref, new);
+		create_symref_in_submodule(path, "HEAD", target_ref, "msg");
+	}
+	return 0;
+}
diff --git a/submodule-move-head.h b/submodule-move-head.h
new file mode 100644
index 0000000000..80e2679038
--- /dev/null
+++ b/submodule-move-head.h
@@ -0,0 +1,22 @@
+#ifndef SUBMODULE_MOVE_HEAD_H
+#define SUBMODULE_MOVE_HEAD_H
+
+struct unpack_trees_options;
+
+/* NEEDSWORK: document */
+struct submodule_move_head_options {
+	int force;
+	const char *old_ref;
+	const char *new_ref;
+	const char *target_ref;
+};
+
+/*
+ * For use as unpack_trees_options.move_head. Parameters should be a
+ * struct submodule_move_head_options * in unpack_trees_options.unpack_data.
+ */
+extern int unpack_trees_move_head(const struct unpack_trees_options *opt, const char *path, const char *old, const char *new, unsigned flags);
+
+extern void create_symref_in_submodule(const char *path, const char *symref, const char *target, const char *logmsg);
+
+#endif /* SUBMODULE_MOVE_HEAD_H */
diff --git a/submodule.c b/submodule.c
index 6415cc5580..001f5eb364 100644
--- a/submodule.c
+++ b/submodule.c
@@ -30,6 +30,17 @@ static int initialized_fetch_ref_tips;
 static struct oid_array ref_tips_before_fetch;
 static struct oid_array ref_tips_after_fetch;
 
+int behave_google_repo_like(void)
+{
+	static int google_repo_like = -1;
+
+	if (google_repo_like == -1)
+		git_config_get_bool("submodule.repolike", &google_repo_like);
+
+	return google_repo_like;
+}
+
+
 /*
  * Check if the .gitmodules file is unmerged. Parsing of the .gitmodules file
  * will be disabled because we can't guess what might be configured in
@@ -1703,6 +1714,9 @@ int submodule_move_head(const char *path,
 
 	if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
 		if (new_head) {
+			if (flags & SUBMODULE_MOVE_HEAD_SKIP_REF_UPDATE)
+				goto out;
+
 			child_process_init(&cp);
 			/* also set the HEAD accordingly */
 			cp.git_cmd = 1;
diff --git a/submodule.h b/submodule.h
index a680214c01..91ff94b0cb 100644
--- a/submodule.h
+++ b/submodule.h
@@ -124,8 +124,10 @@ int push_unpushed_submodules(struct repository *r,
  */
 int submodule_to_gitdir(struct strbuf *buf, const char *submodule);
 
-#define SUBMODULE_MOVE_HEAD_DRY_RUN (1<<0)
-#define SUBMODULE_MOVE_HEAD_FORCE   (1<<1)
+#define SUBMODULE_MOVE_HEAD_DRY_RUN             (1<<0)
+#define SUBMODULE_MOVE_HEAD_FORCE               (1<<1)
+#define SUBMODULE_MOVE_HEAD_SKIP_REF_UPDATE     (1<<2)
+
 int submodule_move_head(const char *path,
 			const char *old,
 			const char *new_head,
@@ -150,4 +152,6 @@ void absorb_git_dir_into_superproject(const char *prefix,
  */
 const char *get_superproject_working_tree(void);
 
+int behave_google_repo_like(void);
+
 #endif
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 016391723c..71d5b506de 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -657,7 +657,16 @@ test_submodule_recursing_with_args_common() {
 			test_submodule_content sub1 origin/add_sub1
 		)
 	'
-	test_expect_success "$command: submodule branch is not changed, detach HEAD instead" '
+
+	if test "$KNOWN_FAILURE_SUBMODULE_REFS_NOT_UPDATED" = 1
+	then
+		RESULT=failure
+	else
+		RESULT=success
+	fi
+	if test "$KNOWN_DIFFERENCE_SUBMODULE_REFS_NOT_UPDATED" = "read-tree"
+	then
+	test_expect_$RESULT "$command: submodule branch is not changed, detach HEAD" '
 		prolog &&
 		reset_work_tree_to_interested add_sub1 &&
 		(
@@ -670,9 +679,82 @@ test_submodule_recursing_with_args_common() {
 			test_submodule_content sub1 origin/modify_sub1 &&
 			git -C sub1 rev-parse keep_branch >actual &&
 			test_cmp expect actual &&
-			test_must_fail git -C sub1 symbolic-ref HEAD
+			test_must_fail git -C sub1 symbolic-ref HEAD >actual
 		)
 	'
+	elif test "$KNOWN_DIFFERENCE_SUBMODULE_REFS_NOT_UPDATED" = "checkout -B current"
+	then
+	test_expect_$RESULT "$command: submodule branch is changed to 'current'" '
+		prolog &&
+		reset_work_tree_to_interested add_sub1 &&
+		(
+			cd submodule_update &&
+			git -C sub1 checkout -b keep_branch &&
+			git -C sub1 rev-parse HEAD >expect &&
+			git branch -t modify_sub1 origin/modify_sub1 &&
+			$command modify_sub1 &&
+			test_superproject_content origin/modify_sub1 &&
+			test_submodule_content sub1 origin/modify_sub1 &&
+			git -C sub1 rev-parse keep_branch >actual &&
+			test_cmp expect actual &&
+			echo refs/heads/current >expect &&
+			git -C sub1 symbolic-ref HEAD >actual &&
+			test_cmp expect actual
+		)
+	'
+	elif test "$KNOWN_DIFFERENCE_SUBMODULE_REFS_NOT_UPDATED" = "reset"
+	then
+	test_expect_$RESULT "$command: submodule branch is changed to superproject, resetting to target" '
+		prolog &&
+		reset_work_tree_to_interested add_sub1 &&
+		(
+			cd submodule_update &&
+			git -C sub1 checkout -b keep_branch &&
+			git -C sub1 rev-parse HEAD >expect &&
+			git branch -t modify_sub1 origin/modify_sub1 &&
+			git checkout -b newbranch &&
+			$command modify_sub1 &&
+
+			# we modified the wt
+			test_superproject_content origin/modify_sub1 &&
+			test_submodule_content sub1 origin/modify_sub1 &&
+
+			# keep_branch does not change
+			git -C sub1 rev-parse keep_branch >actual &&
+			test_cmp expect actual &&
+
+			# the submodule is attached to the same branch as the superproject
+			git -C sub1 symbolic-ref HEAD >actual &&
+			echo refs/heads/newbranch >expect &&
+			test_cmp expect actual
+		)
+	'
+	else
+	test_expect_$RESULT "$command: submodule branch is changed" '
+		prolog &&
+		reset_work_tree_to_interested add_sub1 &&
+		(
+			cd submodule_update &&
+			git -C sub1 checkout -b keep_branch &&
+			git -C sub1 rev-parse HEAD >expect &&
+			git branch -t modify_sub1 origin/modify_sub1 &&
+			$command modify_sub1 &&
+
+			# modified wt
+			test_superproject_content origin/modify_sub1 &&
+			test_submodule_content sub1 origin/modify_sub1 &&
+
+			# unrelated keep_branch is fine
+			git -C sub1 rev-parse keep_branch >actual &&
+			test_cmp expect actual &&
+
+			# submodule ref is checked out
+			git -C sub1 symbolic-ref HEAD >actual &&
+			echo refs/heads/modify_sub1 >expect &&
+			test_cmp expect actual
+		)
+	'
+	fi
 
 	# Replacing a tracked file with a submodule produces a checked out submodule
 	test_expect_success "$command: replace tracked file with submodule checks out submodule" '
diff --git a/t/t1013-read-tree-submodule.sh b/t/t1013-read-tree-submodule.sh
index 91a6fafcb4..de59ebd121 100755
--- a/t/t1013-read-tree-submodule.sh
+++ b/t/t1013-read-tree-submodule.sh
@@ -7,6 +7,7 @@ test_description='read-tree can handle submodules'
 
 KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1
 KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED=1
+KNOWN_DIFFERENCE_SUBMODULE_REFS_NOT_UPDATED="read-tree"
 
 test_submodule_switch_recursing_with_args "read-tree -u -m"
 
diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
index 8f86b5f4b2..940f0fca20 100755
--- a/t/t2013-checkout-submodule.sh
+++ b/t/t2013-checkout-submodule.sh
@@ -66,6 +66,10 @@ test_expect_success '"checkout <submodule>" honors submodule.*.ignore from .git/
 KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1
 test_submodule_switch_recursing_with_args "checkout"
 
+KNOWN_DIFFERENCE_SUBMODULE_REFS_NOT_UPDATED="checkout -B current"
+test_submodule_switch_recursing_with_args "checkout -B current"
+unset KNOWN_DIFFERENCE_SUBMODULE_REFS_NOT_UPDATED
+
 test_submodule_forced_switch_recursing_with_args "checkout -f"
 
 test_submodule_switch "git checkout"
diff --git a/t/t7112-reset-submodule.sh b/t/t7112-reset-submodule.sh
index a1cb9ff858..c31acc6578 100755
--- a/t/t7112-reset-submodule.sh
+++ b/t/t7112-reset-submodule.sh
@@ -8,13 +8,18 @@ test_description='reset can handle submodules'
 KNOWN_FAILURE_SUBMODULE_RECURSIVE_NESTED=1
 KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1
 KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED=1
+KNOWN_DIFFERENCE_SUBMODULE_REFS_NOT_UPDATED="reset"
 
+KNOWN_FAILURE_SUBMODULE_REFS_NOT_UPDATED=1
 test_submodule_switch_recursing_with_args "reset --keep"
 
+unset KNOWN_FAILURE_SUBMODULE_REFS_NOT_UPDATED
 test_submodule_forced_switch_recursing_with_args "reset --hard"
 
+KNOWN_FAILURE_SUBMODULE_REFS_NOT_UPDATED=1
 test_submodule_switch "git reset --keep"
 
+unset KNOWN_FAILURE_SUBMODULE_REFS_NOT_UPDATED
 test_submodule_switch "git reset --merge"
 
 test_submodule_forced_switch "git reset --hard"
diff --git a/unpack-trees.c b/unpack-trees.c
index 6d53cbfc86..f721d48f38 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -254,6 +254,16 @@ static void display_error_msgs(struct unpack_trees_options *o)
 		fprintf(stderr, _("Aborting\n"));
 }
 
+static int move_head(const struct unpack_trees_options *o, const char *path, const char *old, const char *new, unsigned flags)
+{
+	if (behave_google_repo_like()) {
+		if (!o->move_head)
+			return submodule_move_head(path, old, new, flags);
+		return o->move_head(o, path, old, new, flags);
+	} else
+		return submodule_move_head(path, old, new, flags);
+}
+
 static int check_submodule_move_head(const struct cache_entry *ce,
 				     const char *old_id,
 				     const char *new_id,
@@ -268,7 +278,7 @@ static int check_submodule_move_head(const struct cache_entry *ce,
 	if (o->reset)
 		flags |= SUBMODULE_MOVE_HEAD_FORCE;
 
-	if (submodule_move_head(ce->name, old_id, new_id, flags))
+	if (move_head(o, ce->name, old_id, new_id, flags))
 		return o->gently ? -1 :
 				   add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
 	return 0;
@@ -304,12 +314,12 @@ static void load_gitmodules_file(struct index_state *index,
  * Unlink the last component and schedule the leading directories for
  * removal, such that empty directories get removed.
  */
-static void unlink_entry(const struct cache_entry *ce)
+static void unlink_entry(const struct unpack_trees_options *o, const struct cache_entry *ce)
 {
 	const struct submodule *sub = submodule_from_ce(ce);
 	if (sub) {
 		/* state.force is set at the caller. */
-		submodule_move_head(ce->name, "HEAD", NULL,
+		move_head(o, ce->name, "HEAD", NULL,
 				    SUBMODULE_MOVE_HEAD_FORCE);
 	}
 	if (!check_leading_path(ce->name, ce_namelen(ce)))
@@ -408,7 +418,7 @@ static int check_updates(struct unpack_trees_options *o)
 		if (ce->ce_flags & CE_WT_REMOVE) {
 			display_progress(progress, ++cnt);
 			if (o->update && !o->dry_run)
-				unlink_entry(ce);
+				unlink_entry(o, ce);
 		}
 	}
 	remove_marked_cache_entries(index);
@@ -450,7 +460,7 @@ static int check_updates(struct unpack_trees_options *o)
 			display_progress(progress, ++cnt);
 			ce->ce_flags &= ~CE_UPDATE;
 			if (o->update && !o->dry_run) {
-				errs |= checkout_entry(ce, &state, NULL);
+				errs |= unpack_trees_checkout_entry(o, ce, &state, NULL);
 			}
 		}
 	}
diff --git a/unpack-trees.h b/unpack-trees.h
index 0135080a7b..ad98157d6e 100644
--- a/unpack-trees.h
+++ b/unpack-trees.h
@@ -9,12 +9,15 @@
 #define MAX_UNPACK_TREES 8
 
 struct cache_entry;
+struct tree_desc;
 struct unpack_trees_options;
 struct exclude_list;
 
 typedef int (*merge_fn_t)(const struct cache_entry * const *src,
 		struct unpack_trees_options *options);
 
+typedef int (*submodule_move_head_fn)(const struct unpack_trees_options *o, const char *path, const char *old, const char *new, unsigned flags);
+
 enum unpack_trees_error_types {
 	ERROR_WOULD_OVERWRITE = 0,
 	ERROR_NOT_UPTODATE_FILE,
@@ -65,6 +68,7 @@ struct unpack_trees_options {
 	struct dir_struct *dir;
 	struct pathspec *pathspec;
 	merge_fn_t fn;
+	submodule_move_head_fn move_head;
 	const char *msgs[NB_UNPACK_TREES_ERROR_TYPES];
 	struct argv_array msgs_to_free;
 	/*
@@ -86,6 +90,11 @@ struct unpack_trees_options {
 	struct exclude_list *el; /* for internal use */
 };
 
+/* defined in entry.c, for internal use */
+int unpack_trees_checkout_entry(struct unpack_trees_options *o,
+				struct cache_entry *ce,
+				const struct checkout *state, char *topath);
+
 int unpack_trees(unsigned n, struct tree_desc *t,
 		 struct unpack_trees_options *options);
 
-- 
2.20.1.97.g81188d93c3


^ permalink raw reply related	[relevance 19%]

* [PATCH v2 01/11] grep: use grep_opt->repo instead of explict repo argument
  @ 2019-01-12  2:13 10%   ` Nguyễn Thái Ngọc Duy
  0 siblings, 0 replies; 200+ results
From: Nguyễn Thái Ngọc Duy @ 2019-01-12  2:13 UTC (permalink / raw)
  To: git; +Cc: Martin Ågren, Nguyễn Thái Ngọc Duy,
	Stefan Beller

This command is probably the first one that operates on a repository
other than the_repository, in f9ee2fcdfa (grep: recurse in-process
using 'struct repository' - 2017-08-02). An explicit 'struct
repository *' was added in that commit to pass around the repository
that we're supposed to grep from.

Since 38bbc2ea39 (grep.c: remove implicit dependency on the_index -
2018-09-21). 'struct grep_opt *' carries in itself a repository
parameter for grepping. We should now be able to reuse grep_opt to
hold the submodule repo instead of a separate argument, which is just
room for mistakes.

While at there, use the right reference instead of the_repository and
the_index in this code. I was a bit careless in my attempt to kick
the_repository / the_index out of library code. It's normally safe to
just stick the_repository / the_index in bultin/ code, but it's not
the case for grep.

Reviewed-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/grep.c | 41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index bad9c0a3d5..0cc671f7d6 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -393,18 +393,20 @@ static void run_pager(struct grep_opt *opt, const char *prefix)
 		exit(status);
 }
 
-static int grep_cache(struct grep_opt *opt, struct repository *repo,
+static int grep_cache(struct grep_opt *opt,
 		      const struct pathspec *pathspec, int cached);
 static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 		     struct tree_desc *tree, struct strbuf *base, int tn_len,
-		     int check_attr, struct repository *repo);
+		     int check_attr);
 
-static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
+static int grep_submodule(struct grep_opt *opt,
 			  const struct pathspec *pathspec,
 			  const struct object_id *oid,
 			  const char *filename, const char *path)
 {
+	struct repository *superproject = opt->repo;
 	struct repository submodule;
+	struct grep_opt subopt;
 	int hit;
 
 	/*
@@ -440,6 +442,9 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 	add_to_alternates_memory(submodule.objects->odb->path);
 	grep_read_unlock();
 
+	memcpy(&subopt, opt, sizeof(subopt));
+	subopt.repo = &submodule;
+
 	if (oid) {
 		struct object *object;
 		struct tree_desc tree;
@@ -461,21 +466,22 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 		strbuf_addch(&base, '/');
 
 		init_tree_desc(&tree, data, size);
-		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-				object->type == OBJ_COMMIT, &submodule);
+		hit = grep_tree(&subopt, pathspec, &tree, &base, base.len,
+				object->type == OBJ_COMMIT);
 		strbuf_release(&base);
 		free(data);
 	} else {
-		hit = grep_cache(opt, &submodule, pathspec, 1);
+		hit = grep_cache(&subopt, pathspec, 1);
 	}
 
 	repo_clear(&submodule);
 	return hit;
 }
 
-static int grep_cache(struct grep_opt *opt, struct repository *repo,
+static int grep_cache(struct grep_opt *opt,
 		      const struct pathspec *pathspec, int cached)
 {
+	struct repository *repo = opt->repo;
 	int hit = 0;
 	int nr;
 	struct strbuf name = STRBUF_INIT;
@@ -513,7 +519,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
 			}
 		} else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
 			   submodule_path_match(repo->index, pathspec, name.buf, NULL)) {
-			hit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name);
+			hit |= grep_submodule(opt, pathspec, NULL, ce->name, ce->name);
 		} else {
 			continue;
 		}
@@ -535,8 +541,9 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
 
 static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 		     struct tree_desc *tree, struct strbuf *base, int tn_len,
-		     int check_attr, struct repository *repo)
+		     int check_attr)
 {
+	struct repository *repo = opt->repo;
 	int hit = 0;
 	enum interesting match = entry_not_interesting;
 	struct name_entry entry;
@@ -582,10 +589,10 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 			strbuf_addch(base, '/');
 			init_tree_desc(&sub, data, size);
 			hit |= grep_tree(opt, pathspec, &sub, base, tn_len,
-					 check_attr, repo);
+					 check_attr);
 			free(data);
 		} else if (recurse_submodules && S_ISGITLINK(entry.mode)) {
-			hit |= grep_submodule(opt, repo, pathspec, entry.oid,
+			hit |= grep_submodule(opt, pathspec, entry.oid,
 					      base->buf, base->buf + tn_len);
 		}
 
@@ -627,7 +634,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
 		}
 		init_tree_desc(&tree, data, size);
 		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-				obj->type == OBJ_COMMIT, the_repository);
+				obj->type == OBJ_COMMIT);
 		strbuf_release(&base);
 		free(data);
 		return hit;
@@ -644,12 +651,12 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
 
 	for (i = 0; i < nr; i++) {
 		struct object *real_obj;
-		real_obj = deref_tag(the_repository, list->objects[i].item,
+		real_obj = deref_tag(opt->repo, list->objects[i].item,
 				     NULL, 0);
 
 		/* load the gitmodules file for this rev */
 		if (recurse_submodules) {
-			submodule_free(the_repository);
+			submodule_free(opt->repo);
 			gitmodules_config_oid(&real_obj->oid);
 		}
 		if (grep_object(opt, pathspec, real_obj, list->objects[i].name,
@@ -674,9 +681,9 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
 	if (exc_std)
 		setup_standard_excludes(&dir);
 
-	fill_directory(&dir, &the_index, pathspec);
+	fill_directory(&dir, opt->repo->index, pathspec);
 	for (i = 0; i < dir.nr; i++) {
-		if (!dir_path_match(&the_index, dir.entries[i], pathspec, 0, NULL))
+		if (!dir_path_match(opt->repo->index, dir.entries[i], pathspec, 0, NULL))
 			continue;
 		hit |= grep_file(opt, dir.entries[i]->name);
 		if (hit && opt->status_only)
@@ -1117,7 +1124,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 		if (!cached)
 			setup_work_tree();
 
-		hit = grep_cache(&opt, the_repository, &pathspec, cached);
+		hit = grep_cache(&opt, &pathspec, cached);
 	} else {
 		if (cached)
 			die(_("both --cached and trees are given"));
-- 
2.20.0.482.g66447595a7


^ permalink raw reply related	[relevance 10%]

* Re: Regression: submodule worktrees can clobber core.worktree config
  2019-01-10 20:07  7%     ` Stefan Beller
@ 2019-01-11  0:07  7%       ` Duy Nguyen
  0 siblings, 0 replies; 200+ results
From: Duy Nguyen @ 2019-01-11  0:07 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Tomasz Śniatowski, git

On Fri, Jan 11, 2019 at 3:07 AM Stefan Beller <sbeller@google.com> wrote:
>
> > I had a look at https://gitlab.com/pclouds/git/commits/submodules-in-worktrees,
> > and it doesn't seem to be quite all okay.
> >
> > The submodule update step of the repro (that breaks the config on 2.20) emits
> > an error message instead, and leaves the config unchanged:
> >    git -C b2 submodule update
> >    fatal: could not set 'core.worktree' to '../../../../../../b2/a'
> > It looks a bit like it's still trying to do the wrong thing, but errors out
> > during the attempt (repo_config_set_worktree_gently returns false).
>
> There is more than just that. After adding the worktrees,
> (and after the first status call)
>
>     $ cat b2/.git
> gitdir: /u/git/t/trash directory.t7419-submodule-worktrees/b/.git/worktrees/b2
>     $ cat b2/a/.git
> gitdir: /u/git/t/trash
> directory.t7419-submodule-worktrees/b/.git/modules/a/worktrees/a
>
> Are worktrees using absolute path for their gitlinks?

Yes. Moving to relative paths is on my todo list and I probably should
get to it after I'm mostly done (*) with submodule support

(*) Sharing submodule repos between worktrees is still something not addressed.
-- 
Duy

^ permalink raw reply	[relevance 7%]

* Re: Regression: submodule worktrees can clobber core.worktree config
  2019-01-09 23:57  7%   ` Tomasz Śniatowski
@ 2019-01-10 20:07  7%     ` Stefan Beller
  2019-01-11  0:07  7%       ` Duy Nguyen
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2019-01-10 20:07 UTC (permalink / raw)
  To: Tomasz Śniatowski; +Cc: Duy Nguyen, git

> I had a look at https://gitlab.com/pclouds/git/commits/submodules-in-worktrees,
> and it doesn't seem to be quite all okay.
>
> The submodule update step of the repro (that breaks the config on 2.20) emits
> an error message instead, and leaves the config unchanged:
>    git -C b2 submodule update
>    fatal: could not set 'core.worktree' to '../../../../../../b2/a'
> It looks a bit like it's still trying to do the wrong thing, but errors out
> during the attempt (repo_config_set_worktree_gently returns false).

There is more than just that. After adding the worktrees,
(and after the first status call)

    $ cat b2/.git
gitdir: /u/git/t/trash directory.t7419-submodule-worktrees/b/.git/worktrees/b2
    $ cat b2/a/.git
gitdir: /u/git/t/trash
directory.t7419-submodule-worktrees/b/.git/modules/a/worktrees/a

Are worktrees using absolute path for their gitlinks?
Submodules themselves try really hard to use relative path:

    $ cat b/a/.git
gitdir: ../.git/modules/a

> Curiously, even though it says "fatal", it will then perform the actual
> submodule update if it's required.

Oh. :/ I think we should solve that by either warning
(but that gives bad UX) or actually aborting, by adding
a "|| exit 1" in git-submodule.sh in cmd_update where we
call "git submodule--helper ensure-core-worktree".

When we run "git -C b2 submodule update", it calls
"git submodule--helper ensure-core-worktree a" which
currently would make sure that b2/a/.git points to
b2/.git/modules/a, but that is not the case as b2 and b2/a
are worktrees, whose git directories are housed in
b/.git/worktrees.

So maybe we need to be a bit more careful and check
if b2/a/.git resolves to a worktree and if so we'd not
touch it at all (and warn about it?).


>
> Same behavior on master with a subset of that branch cherry-picked, that is:
> https://gitlab.com/pclouds/git/commit/94751ada7c32eb6fb2c67dd7723161d1955a5683
> along with two others it needed to build:
> https://gitlab.com/pclouds/git/commit/d26ab4c5013f6117814161be3e87c8d2b73561a4
> https://gitlab.com/pclouds/git/commit/b2e21eece6b35e00707ed3a8377a84a95da6b778
>
> --
> Tomasz Śniatowski

^ permalink raw reply	[relevance 7%]

* Re: What's cooking in git.git (Jan 2019, #01; Mon, 7)
  @ 2019-01-10 18:02  2% ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2019-01-10 18:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

> * sb/submodule-recursive-fetch-gets-the-tip (2018-12-09) 9 commits
>  - fetch: ensure submodule objects fetched
>  - submodule.c: fetch in submodules git directory instead of in worktree
>  - submodule: migrate get_next_submodule to use repository structs
>  - repository: repo_submodule_init to take a submodule struct
>  - submodule: store OIDs in changed_submodule_names
>  - submodule.c: tighten scope of changed_submodule_names struct
>  - submodule.c: sort changed_submodule_names before searching it
>  - submodule.c: fix indentation
>  - sha1-array: provide oid_array_filter
>
>  "git fetch --recurse-submodules" may not fetch the necessary commit
>  that is bound to the superproject, which is getting corrected.
>
>  Ready?

I checked the last discussion at
https://public-inbox.org/git/20181129002756.167615-1-sbeller@google.com/
and I think it is ready as I did not see any outstanding issues.

Thanks,
Stefan

^ permalink raw reply	[relevance 2%]

* Re: Regression: submodule worktrees can clobber core.worktree config
  2019-01-09 17:42  7% ` Stefan Beller
@ 2019-01-09 23:57  7%   ` Tomasz Śniatowski
  2019-01-10 20:07  7%     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Tomasz Śniatowski @ 2019-01-09 23:57 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Duy Nguyen, git

On Wed, 9 Jan 2019 at 18:42, Stefan Beller <sbeller@google.com> wrote:
>
> On Tue, Jan 8, 2019 at 2:16 PM Tomasz Śniatowski <tsniatowski@vewd.com> wrote:
> >
> > After upgrading to 2.20.1 I noticed in some submodule+worktree scenarios git
> > will break the submodule configuration. Reproducible with:
> >     git init a && (cd a; touch a; git add a; git commit -ma)
> >     git init b && (cd b; git submodule add ../a; git commit -mb)
> >     git -C b worktree add ../b2
> >     git -C b/a worktree add ../../b2/a
> >     git -C b status
> >     git -C b2 submodule update
> >     git -C b status
> >
> > The submodule update in the _worktree_ puts an invalid core.worktree value in
> > the _original_ repository submodule config (b/.git/modules/a/config), causing
> > the last git status to error out with:
> >     fatal: cannot chdir to '../../../../../../b2/a': No such file or directory
> >     fatal: 'git status --porcelain=2' failed in submodule a
> >
> > Looking at the config file itself, the submodule update operation applies the
> > following change (the new path is invalid):
> >     -       worktree = ../../../a
> >     +       worktree = ../../../../../../b2/a
> >
> > This worked fine on 2.19.2 (no config change, no error), and was useful to have
> > a worktree with (large) submodules that are also worktrees.
>
> Thanks for reporting the issue!
>
> >
> > Bisects down to:
> > 74d4731da1 submodule--helper: replace connect-gitdir-workingtree by
> > ensure-core-worktree
>
> So this would need to update the worktree config, not the generic config.
>
> We'd need to replace the line
>     cfg_file = repo_git_path(&subrepo, "config");
> in builtin/submodule--helper.c::ensure_core_worktree()
> to be a worktree specific call.
>
> Or the other way round we'd want to make repo_git_path to
> be worktree specific and introduce repo_common_path for
> the main working tree.
>
> Looking at Duys tree,
> https://gitlab.com/pclouds/git/commit/94751ada7c32eb6fb2c67dd7723161d1955a5683
> is pretty much what we need.
>
> Reverting that topic that introduced this (4d6d6e,
> Merge branch 'sb/submodule-update-in-c'), might be possible but
> that would conflict with another followup that fixes issues in
> that series
> (see sb/submodule-unset-core-worktree-when-worktree-is-lost
> https://github.com/gitster/git/commits/sb/submodule-unset-core-worktree-when-worktree-is-lost)
> so I'd rather just cherry-pick the commit from Duy.

I had a look at https://gitlab.com/pclouds/git/commits/submodules-in-worktrees,
and it doesn't seem to be quite all okay.

The submodule update step of the repro (that breaks the config on 2.20) emits
an error message instead, and leaves the config unchanged:
   git -C b2 submodule update
   fatal: could not set 'core.worktree' to '../../../../../../b2/a'
It looks a bit like it's still trying to do the wrong thing, but errors out
during the attempt (repo_config_set_worktree_gently returns false).

Curiously, even though it says "fatal", it will then perform the actual
submodule update if it's required.

Same behavior on master with a subset of that branch cherry-picked, that is:
https://gitlab.com/pclouds/git/commit/94751ada7c32eb6fb2c67dd7723161d1955a5683
along with two others it needed to build:
https://gitlab.com/pclouds/git/commit/d26ab4c5013f6117814161be3e87c8d2b73561a4
https://gitlab.com/pclouds/git/commit/b2e21eece6b35e00707ed3a8377a84a95da6b778

--
Tomasz Śniatowski

^ permalink raw reply	[relevance 7%]

* Re: Submodule log bug
  @ 2019-01-09 23:13 12% ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2019-01-09 23:13 UTC (permalink / raw)
  To: David Turner; +Cc: Git Mailing List

On Wed, Jan 2, 2019 at 2:14 PM David Turner <novalis@novalis.org> wrote:
>
> When a submodule is renamed, git log gives incorrect output:
>
> commit 350ebece9bce8d9c495f9a51e6f5529749c5c3cc (HEAD -> master)
> Author:
> David Turner <novalis@novalis.org>
> Date:   Wed Jan 2 17:09:56 2019 -0500
>
>     move
>
> diff --git a/.gitmodules b/.gitmodules
> index da1a767..f4baf2a 100644
> --- a/.gitmodules
> +++ b/.gitmodules
> @@ -1,3 +1,3 @@
> -[submodule "mymod"]
> -       path = mymod
> +[submodule "morx"]
> +       path = morx
>         url = ../sub
> Submodule mymod 86da4a4...86da4a4 (commits not present)
>
> ^-- I expect this last line to tell me that the submodule has been
> renamed, rather than that it has changed SHA to the same SHA.

Trying to reproduce this myself, it seems to work:

    $ git mv supertest-3/ supertest-3-moved
    $ git commit -m test
    $ git show
commit 463ce75588378a8c5c0ba1fd427cd02c87e2078a (HEAD -> master)
Author: Stefan Beller <sbeller@google.com>
Date:   Wed Jan 9 14:31:09 2019 -0800

    test

diff --git a/.gitmodules b/.gitmodules
index bf393d9..80e7d91 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
 [submodule "supertest-3"]
-       path = supertest-3
+       path = supertest-3-moved
        url = https://github.com/stefanbeller/supertest-3
diff --git a/supertest-3 b/supertest-3-moved
similarity index 100%
rename from supertest-3
rename to supertest-3-moved

The difference is that I did not rename the submodule
name, which is crucial, as that determines the superprojects
access to the submodules. (The sed command in the
demo causes the name to change)
But this doesn't seem to be the issue of this bug report.

The core issue is whether --submodule=log is given,
as that will also produce the line
    $ git show --submodule=log
    [...]
Submodule supertest-3 636b587...636b587 (commits not present)

I think to fix this, we'd want to pipe struct diff_filepair *p
from run_diff_cmd through builtin_diff to
show_submodule_summary and show_submodule_inline_diff
which both use show_submodule_header, which could
check for a rename of the submodule via
p->status == DIFF_STATUS_RENAMED
and then act appropriately.

Stefan

^ permalink raw reply related	[relevance 12%]

* Re: "IMAP IDLE"-like long-polling "git fetch"
  @ 2019-01-09 22:27  4%     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2019-01-09 22:27 UTC (permalink / raw)
  To: Eric Wong, git, meta

On Fri, Dec 28, 2018 at 8:39 PM Konstantin Ryabitsev
<konstantin@linuxfoundation.org> wrote:
>
> On Sat, Dec 29, 2018 at 03:56:21AM +0000, Eric Wong wrote:
> > Hey all, I just added this to the TODO file for public-inbox[1] but
> > obviously it's intended for git.git (meta@public-inbox cc-ed):
> >
> > > +* Contribute something like IMAP IDLE for "git fetch".
> > > +  Inboxes (and any git repos) can be kept up-to-date without
> > > +  relying on polling.
> >
> > I would've thought somebody had done this by now, but I guess
> > it's dependent on a bunch of things (TLS layer nowadays, maybe
> > HTTP/2), so git-daemon support alone wouldn't cut it...
>
> Polling is not all bad, especially for large repository collections.

I disagree with that statement.

IIRC, More than half the bandwidth of Googles git servers are used
for ls-remote calls (i.e. polling a lot of repos, most of them did *not*
change, by build bots which are really eager to try again after a minute).

That is why we use a superproject, with all other repositories as
a submodule for polling, as that would slash the ls-remote traffic
approximately by the number of repositories.

There was an attempt in JGit to support this type of communication
of long polling at
https://git.eclipse.org/r/plugins/gitiles/jgit/jgit/+/2adc572628f9382ace5fbd791325dc64f7c968d3
but not a whole lot is left over in JGit as it was refactored at least
once again.

IIRC the issues where in the lack of protocol definition that made it
usable for a wider audience.

^ permalink raw reply	[relevance 4%]

* Re: Regression: submodule worktrees can clobber core.worktree config
  @ 2019-01-09 17:42  7% ` Stefan Beller
  2019-01-09 23:57  7%   ` Tomasz Śniatowski
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2019-01-09 17:42 UTC (permalink / raw)
  To: Tomasz Śniatowski, Duy Nguyen; +Cc: git

On Tue, Jan 8, 2019 at 2:16 PM Tomasz Śniatowski <tsniatowski@vewd.com> wrote:
>
> After upgrading to 2.20.1 I noticed in some submodule+worktree scenarios git
> will break the submodule configuration. Reproducible with:
>     git init a && (cd a; touch a; git add a; git commit -ma)
>     git init b && (cd b; git submodule add ../a; git commit -mb)
>     git -C b worktree add ../b2
>     git -C b/a worktree add ../../b2/a
>     git -C b status
>     git -C b2 submodule update
>     git -C b status
>
> The submodule update in the _worktree_ puts an invalid core.worktree value in
> the _original_ repository submodule config (b/.git/modules/a/config), causing
> the last git status to error out with:
>     fatal: cannot chdir to '../../../../../../b2/a': No such file or directory
>     fatal: 'git status --porcelain=2' failed in submodule a
>
> Looking at the config file itself, the submodule update operation applies the
> following change (the new path is invalid):
>     -       worktree = ../../../a
>     +       worktree = ../../../../../../b2/a
>
> This worked fine on 2.19.2 (no config change, no error), and was useful to have
> a worktree with (large) submodules that are also worktrees.

Thanks for reporting the issue!

>
> Bisects down to:
> 74d4731da1 submodule--helper: replace connect-gitdir-workingtree by
> ensure-core-worktree

So this would need to update the worktree config, not the generic config.

We'd need to replace the line
    cfg_file = repo_git_path(&subrepo, "config");
in builtin/submodule--helper.c::ensure_core_worktree()
to be a worktree specific call.

Or the other way round we'd want to make repo_git_path to
be worktree specific and introduce repo_common_path for
the main working tree.

Looking at Duys tree,
https://gitlab.com/pclouds/git/commit/94751ada7c32eb6fb2c67dd7723161d1955a5683
is pretty much what we need.

Reverting that topic that introduced this (4d6d6e,
Merge branch 'sb/submodule-update-in-c'), might be possible but
that would conflict with another followup that fixes issues in
that series
(see sb/submodule-unset-core-worktree-when-worktree-is-lost
https://github.com/gitster/git/commits/sb/submodule-unset-core-worktree-when-worktree-is-lost)
so I'd rather just cherry-pick the commit from Duy.

Stefan

^ permalink raw reply	[relevance 7%]

* Git Test Coverage Report (Tues, Jan 8)
@ 2019-01-08 17:50  3% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2019-01-08 17:50 UTC (permalink / raw)
  To: Git List

Here is today's test coverage report.

Thanks,
-Stolee

[1] https://git.visualstudio.com/git/_build/results?buildId=290

---

pu: a5fd499f842ac17440e29bd610058ccdd3cf24a1
jch: 2ccddf26bf6308d5ea65fa26ffd7372d083bfc16
next: d81d796ee0c49eae40e3f85467a8e6b18022bcea
master: ecbdaf0899161c067986e9d9d564586d4b045d62
master@{1}: b21ebb671bb7dea8d342225f0d66c41f4e54d5ca

Uncovered code in 'pu' not in 'jch'
--------------------------------------

apply.c
1fcfdf84ce 4275) oidclr(&patch->old_oid);

backup-log.c
fdbbdf809f  25) return error_errno(_("unable to open %s"), path);
fdbbdf809f  27) close(fd);
fdbbdf809f  28) return error_errno(_("unable to update %s"), path);
fdbbdf809f  41) return -1;
102b7856e3  63) return -1;/* corrupt? */
102b7856e3  71) return -1; /* corrupt? */
102b7856e3  75) message += 6;
102b7856e3 105) if (errno == ENOENT || errno == ENOTDIR)
102b7856e3 106) return 0;
102b7856e3 107) return -1;
102b7856e3 112) ret = error_errno(_("cannot seek back in %s"), path);
102b7856e3 123) ret = error_errno(_("cannot seek back in %s"), path);
102b7856e3 124) break;
102b7856e3 128) ret = error_errno(_("cannot read %d bytes from %s"),
102b7856e3 130) break;
102b7856e3 189) strbuf_splice(&sb, 0, 0, buf, endp - buf);
102b7856e3 190) break;
102b7856e3 215) return -1;
102b7856e3 219) ret = parse(&sb, data);
bde028c667 232) static int good_oid(struct repository *r, const struct 
object_id *oid)
bde028c667 234) if (is_null_oid(oid))
bde028c667 235) return 1;
bde028c667 237) return oid_object_info(r, oid, NULL) == OBJ_BLOB;
bde028c667 240) static int prune_parse(struct strbuf *line, void *data)
bde028c667 242) struct prune_options *opts = data;
bde028c667 245) strbuf_reset(&opts->copy);
bde028c667 246) strbuf_addbuf(&opts->copy, line);
bde028c667 248) if (bkl_parse_entry(line, &entry))
bde028c667 249) return -1;
bde028c667 251) if (entry.timestamp < opts->expire)
bde028c667 252) return 0;
bde028c667 254) if (oideq(&entry.old_oid, &entry.new_oid))
bde028c667 255) return 0;
bde028c667 257) if (!good_oid(opts->repo, &entry.old_oid) ||
bde028c667 258)     !good_oid(opts->repo, &entry.new_oid))
bde028c667 259) return 0;
bde028c667 261) if (!opts->fp)
bde028c667 262) return -1;
bde028c667 264) fputs(opts->copy.buf, opts->fp);
bde028c667 265) return 0;
bde028c667 278) return error(_("failed to lock '%s'"), path);
bde028c667 287) rollback_lock_file(&lk);
b86e9ac723 301) die(_("failed to prune %s"), "gitdir.bkl");
b86e9ac723 309) if (wt->id)
b86e9ac723 310) die(_("failed to prune %s on working tree '%s'"),
b86e9ac723 313) die(_("failed to prune %s"), "index.bkl");
b86e9ac723 316) if (wt->id)
b86e9ac723 317) die(_("failed to prune %s on working tree '%s'"),
b86e9ac723 320) die(_("failed to prune %s"), "worktree.bkl");
b2069b6eb0 331) static void add_blob_to_pending(const struct object_id *oid,
b2069b6eb0 337) if (!good_oid(cb->revs->repo, oid))
b2069b6eb0 338) return;
b2069b6eb0 340) blob = lookup_blob(cb->revs->repo, oid);
b2069b6eb0 341) blob->object.flags |= cb->flags;
b2069b6eb0 342) add_pending_object(cb->revs, &blob->object, path);
b2069b6eb0 345) static int add_pending(struct strbuf *line, void *cb)
b2069b6eb0 349) if (bkl_parse_entry(line, &entry))
b2069b6eb0 350) return -1;
b2069b6eb0 352) add_blob_to_pending(&entry.old_oid, entry.path, cb);
b2069b6eb0 353) add_blob_to_pending(&entry.new_oid, entry.path, cb);
b2069b6eb0 354) return 0;

bisect.c
04dac00473  661) mark_edges_uninteresting(revs, NULL, 0);

builtin/archive.c
01f9ec64c8 builtin/archive.c  64) if (starts_with(reader.line, "NACK "))
01f9ec64c8 builtin/archive.c  65) die(_("git archive: NACK %s"), 
reader.line + 5);

builtin/backup-log.c
fdbbdf809f  28) usage_with_options(backup_log_usage, NULL);
fdbbdf809f  33) die(_("not a valid object name: %s"), argv[2]);
fdbbdf809f  36) die(_("not a valid object name: %s"), argv[3]);
6a05b9ab74  62) return -1;
6a05b9ab74  65) return 2;
6a05b9ab74  69) return 0;
6a05b9ab74  82) return 1;/* treat null oid like empty blob */
6a05b9ab74  86) die(_("object not found: %s"), oid_to_hex(oid));
6a05b9ab74  88) die(_("not a blob: %s"), oid_to_hex(oid));
6a05b9ab74 111) usage_with_options(backup_log_usage, options);
6a05b9ab74 114) die(_("not a valid change id: %s"), argv[0]);
6a05b9ab74 119) die(_("failed to parse '%s'"), log_path);
45f3e0cd9d 130) old = the_hash_algo->empty_blob;
45f3e0cd9d 135) new = the_hash_algo->empty_blob;
45f3e0cd9d 140) return;
45f3e0cd9d 156) return -1;
45f3e0cd9d 162) return 0;
45f3e0cd9d 183) found_dash_dash = 1;
45f3e0cd9d 184) i++;
45f3e0cd9d 185) continue;
45f3e0cd9d 189) exit(128);
45f3e0cd9d 196) die(_("not a valid change id: %s"), arg);
45f3e0cd9d 204) usage_with_options(backup_log_usage, NULL);
45f3e0cd9d 208) die(_("failed to parse '%s'"), log_path);
7f1d166ee1 252) return -1;
7f1d166ee1 255) return 1;
7f1d166ee1 260) return 0;
7f1d166ee1 283) opts.revs.diffopt.output_format = DIFF_FORMAT_PATCH;
7f1d166ee1 284) diff_setup_done(&opts.revs.diffopt);
7f1d166ee1 293) ret = bkl_parse_file(log_path, log_parse, &opts);
7f1d166ee1 298) die(_("failed to parse '%s'"), log_path);
bde028c667 304) static int prune(int argc, const char **argv,
bde028c667 307) timestamp_t expire = time(NULL) - 90 * 24 * 3600;
bde028c667 308) struct option options[] = {
bde028c667 314) argc = parse_options(argc, argv, prefix, options, 
backup_log_usage, 0);
bde028c667 316) return bkl_prune(the_repository, log_path, expire);
fdbbdf809f 323) else if (!strcmp(id, "worktree"))
fdbbdf809f 324) return git_pathdup("worktree.bkl");
fdbbdf809f 325) else if (!strcmp(id, "gitdir"))
fdbbdf809f 326) return git_pathdup("common/gitdir.bkl");
fdbbdf809f 328) die(_("backup log id '%s' is not recognized"), id);
fdbbdf809f 346) die(_("expected a subcommand"));
fdbbdf809f 350) die(_("--id and --path are incompatible"));
fdbbdf809f 354) die(_("either --id or --path is required"));
bde028c667 364) else if (!strcmp(argv[0], "prune"))
bde028c667 365) return prune(argc, argv, prefix, log_path);

builtin/blame.c
080448fbe8 builtin/blame.c    930) blame_date_width = sizeof("Thu Oct 19 
16:00");
080448fbe8 builtin/blame.c    931) break;

builtin/config.c
937d6bee9e builtin/config.c      604) oidclr(oid);

builtin/fetch-pack.c
4d0feb7630 builtin/fetch-pack.c 231) get_remote_refs(fd[1], &reader, 
&ref, 0, NULL, NULL);
4d0feb7630 builtin/fetch-pack.c 232) break;

builtin/grep.c
d5498e0871 builtin/grep.c  408) const struct submodule *sub = 
submodule_from_path(superproject,
d5498e0871 builtin/grep.c  426) if (repo_submodule_init(&subrepo, 
superproject, sub)) {
d5498e0871 builtin/grep.c  431) repo_read_gitmodules(&subrepo);
d6af6af1f0 builtin/grep.c  443) 
add_to_alternates_memory(subrepo.objects->odb->path);
d5498e0871 builtin/grep.c  468) object->type == OBJ_COMMIT, &subrepo);
d5498e0871 builtin/grep.c  472) hit = grep_cache(opt, &subrepo, 
pathspec, 1);
d5498e0871 builtin/grep.c  475) repo_clear(&subrepo);

builtin/multi-pack-index.c
5532d59aaa 49) die(_("--batch-size option is only for 'repack' verb"));

builtin/rebase.c
3bd5f07101  258) write_file(state_dir_path("verbose", opts), "%s", "");
3bd5f07101  260) write_file(state_dir_path("strategy", opts), "%s",
3bd5f07101  263) write_file(state_dir_path("strategy_opts", opts), "%s",
3bd5f07101  270) write_file(state_dir_path("gpg_sign_opt", opts), "%s",
3bd5f07101  273) write_file(state_dir_path("strategy", opts), "--signoff");
2ead83aefb  396) ret = -1;
2ead83aefb  397) goto leave_reset_head;
2ead83aefb  401) ret = error(_("could not determine HEAD revision"));
2ead83aefb  402) goto leave_reset_head;
2ead83aefb  426) ret = error(_("could not read index"));
2ead83aefb  427) goto leave_reset_head;
2ead83aefb  431) ret = error(_("failed to find tree of %s"),
2ead83aefb  433) goto leave_reset_head;
2ead83aefb  437) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
2ead83aefb  438) goto leave_reset_head;
2ead83aefb  450) ret = error(_("could not write index"));
2ead83aefb  451) goto leave_reset_head;
2ead83aefb  469) } else if (old_orig)
2ead83aefb  470) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
3bd5f07101  546) argv_array_push(&am.args, opts->gpg_sign_opt);
3bd5f07101  580) status = error_errno(_("could not write '%s'"),
3bd5f07101  582) free(rebased_patches);
3bd5f07101  583) argv_array_clear(&am.args);
3bd5f07101  584) return status;
3bd5f07101  594) argv_array_split(&format_patch.args,
3bd5f07101  595)  opts->git_format_patch_opt.buf);
3bd5f07101  603) unlink(rebased_patches);
3bd5f07101  604) free(rebased_patches);
3bd5f07101  605) argv_array_clear(&am.args);
3bd5f07101  607) reset_head(&opts->orig_head, "checkout", 
opts->head_name, 0,
3bd5f07101  609) error(_("\ngit encountered an error while preparing the "
3bd5f07101  616) strbuf_release(&revisions);
3bd5f07101  617) return status;
3bd5f07101  623) status = error_errno(_("could not read '%s'"),
3bd5f07101  625) free(rebased_patches);
3bd5f07101  626) argv_array_clear(&am.args);
3bd5f07101  627) return status;
3bd5f07101  639) argv_array_push(&am.args, opts->gpg_sign_opt);
81ef8ee75d  960) return -1;
d421afa0c6 1448) die(_("--reschedule-failed-exec requires an interactive 
rebase"));
d421afa0c6 1480) die(_("error: cannot combine '--preserve-merges' with "

builtin/receive-pack.c
01f9ec64c8 builtin/receive-pack.c 1587)     reader->line + 8);
01f9ec64c8 builtin/receive-pack.c 1621) die("protocol error: got an 
unexpected packet");

builtin/stash.c
f6bbd78127 builtin/stash--helper.c  127) die(_("'%s' is not a stash-like 
commit"), revision);
f6bbd78127 builtin/stash--helper.c  160) free_stash_info(info);
f6bbd78127 builtin/stash--helper.c  161) fprintf_ln(stderr, _("No stash 
entries found."));
f6bbd78127 builtin/stash--helper.c  162) return -1;
f6bbd78127 builtin/stash--helper.c  197) free_stash_info(info);
cdca49bc4c builtin/stash--helper.c  224) return error(_("git stash clear 
with parameters is "
f6bbd78127 builtin/stash--helper.c  240) return -1;
f6bbd78127 builtin/stash--helper.c  248) return -1;
f6bbd78127 builtin/stash--helper.c  261) return -1;
f6bbd78127 builtin/stash--helper.c  264) return error(_("unable to write 
new index file"));
f6bbd78127 builtin/stash--helper.c  376) remove_path(stash_index_path.buf);
f6bbd78127 builtin/stash--helper.c  377) return -1;
f6bbd78127 builtin/stash--helper.c  404) return -1;
f6bbd78127 builtin/stash--helper.c  407) return error(_("cannot apply a 
stash in the middle of a merge"));
f6bbd78127 builtin/stash--helper.c  417) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  418) return error(_("could not 
generate diff %s^!."),
f6bbd78127 builtin/stash--helper.c  425) return error(_("conflicts in 
index."
f6bbd78127 builtin/stash--helper.c  431) return error(_("could not save 
index tree"));
f6bbd78127 builtin/stash--helper.c  438) return error(_("could not 
restore untracked files from stash"));
f6bbd78127 builtin/stash--helper.c  469) return -1;
f6bbd78127 builtin/stash--helper.c  474) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  479) strbuf_release(&out);
f6bbd78127 builtin/stash--helper.c  480) return -1;
cdca49bc4c builtin/stash--helper.c  556) return error(_("%s: Could not 
drop stash entry"),
e1d01876a4 builtin/stash--helper.c  631) printf_ln(_("The stash entry is 
kept in case "
b4493f269e builtin/stash--helper.c  765) free_stash_info(&info);
51809c70ca builtin/stash.c          766) 
usage_with_options(git_stash_show_usage, options);
847eb0b0a8 builtin/stash--helper.c  782) stash_msg = "Created via \"git 
stash store\".";
847eb0b0a8 builtin/stash--helper.c  788) if (!quiet) {
847eb0b0a8 builtin/stash--helper.c  789) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
847eb0b0a8 builtin/stash--helper.c  792) return -1;
847eb0b0a8 builtin/stash--helper.c  816) if (!quiet)
847eb0b0a8 builtin/stash--helper.c  817) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
847eb0b0a8 builtin/stash--helper.c  819) return -1;
1f5a011d90 builtin/stash--helper.c  901) return -1;
1f5a011d90 builtin/stash--helper.c  961) ret = -1;
1f5a011d90 builtin/stash--helper.c  962) goto done;
1f5a011d90 builtin/stash--helper.c  967) ret = -1;
1f5a011d90 builtin/stash--helper.c  968) goto done;
1f5a011d90 builtin/stash--helper.c  973) ret = -1;
1f5a011d90 builtin/stash--helper.c  974) goto done;
1f5a011d90 builtin/stash--helper.c 1000) ret = -1;
1f5a011d90 builtin/stash--helper.c 1001) goto done;
1f5a011d90 builtin/stash--helper.c 1012) ret = -1;
1f5a011d90 builtin/stash--helper.c 1013) goto done;
1f5a011d90 builtin/stash--helper.c 1019) ret = -1;
1f5a011d90 builtin/stash--helper.c 1020) goto done;
1f5a011d90 builtin/stash--helper.c 1027) ret = -1;
1f5a011d90 builtin/stash--helper.c 1028) goto done;
1f5a011d90 builtin/stash--helper.c 1053) ret = -1;
1f5a011d90 builtin/stash--helper.c 1054) goto done;
1f5a011d90 builtin/stash--helper.c 1065) ret = -1;
1f5a011d90 builtin/stash--helper.c 1066) goto done;
1f5a011d90 builtin/stash--helper.c 1072) ret = -1;
1f5a011d90 builtin/stash--helper.c 1073) goto done;
1f5a011d90 builtin/stash--helper.c 1084) ret = -1;
1f5a011d90 builtin/stash--helper.c 1085) goto done;
1f5a011d90 builtin/stash--helper.c 1090) ret = -1;
1f5a011d90 builtin/stash--helper.c 1091) goto done;
9a95010a11 builtin/stash--helper.c 1127) fprintf_ln(stderr, _("You do 
not have "
1f5a011d90 builtin/stash--helper.c 1136) ret = 1;
1f5a011d90 builtin/stash--helper.c 1137) goto done;
9a95010a11 builtin/stash--helper.c 1153) if (!quiet)
9a95010a11 builtin/stash--helper.c 1154) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1156) ret = -1;
1f5a011d90 builtin/stash--helper.c 1157) goto done;
9a95010a11 builtin/stash--helper.c 1162) if (!quiet)
9a95010a11 builtin/stash--helper.c 1163) fprintf_ln(stderr, _("Cannot save "
1f5a011d90 builtin/stash--helper.c 1165) ret = -1;
1f5a011d90 builtin/stash--helper.c 1166) goto done;
9a95010a11 builtin/stash--helper.c 1173) if (!quiet)
9a95010a11 builtin/stash--helper.c 1174) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1176) goto done;
9a95010a11 builtin/stash--helper.c 1182) if (!quiet)
9a95010a11 builtin/stash--helper.c 1183) fprintf_ln(stderr, _("Cannot 
save the current "
1f5a011d90 builtin/stash--helper.c 1185) ret = -1;
1f5a011d90 builtin/stash--helper.c 1186) goto done;
9a95010a11 builtin/stash--helper.c 1210) if (!quiet)
9a95010a11 builtin/stash--helper.c 1211) fprintf_ln(stderr, _("Cannot 
record "
1f5a011d90 builtin/stash--helper.c 1213) ret = -1;
1f5a011d90 builtin/stash--helper.c 1214) goto done;
fa38428f76 builtin/stash--helper.c 1283) ret = -1;
fa38428f76 builtin/stash--helper.c 1284) goto done;
fa38428f76 builtin/stash--helper.c 1294) ret = -1;
9a95010a11 builtin/stash--helper.c 1295) if (!quiet)
9a95010a11 builtin/stash--helper.c 1296) fprintf_ln(stderr, _("Cannot 
initialize stash"));
fa38428f76 builtin/stash--helper.c 1297) goto done;
fa38428f76 builtin/stash--helper.c 1309) ret = -1;
9a95010a11 builtin/stash--helper.c 1310) if (!quiet)
9a95010a11 builtin/stash--helper.c 1311) fprintf_ln(stderr, _("Cannot 
save the current status"));
fa38428f76 builtin/stash--helper.c 1312) goto done;
fa38428f76 builtin/stash--helper.c 1329) ret = -1;
fa38428f76 builtin/stash--helper.c 1348) ret = -1;
fa38428f76 builtin/stash--helper.c 1349) goto done;
fa38428f76 builtin/stash--helper.c 1358) ret = -1;
fa38428f76 builtin/stash--helper.c 1359) goto done;
fa38428f76 builtin/stash--helper.c 1367) ret = -1;
fa38428f76 builtin/stash--helper.c 1376) ret = -1;
fa38428f76 builtin/stash--helper.c 1387) ret = -1;
fa38428f76 builtin/stash--helper.c 1388) goto done;
fa38428f76 builtin/stash--helper.c 1397) ret = -1;
fa38428f76 builtin/stash--helper.c 1398) goto done;
fa38428f76 builtin/stash--helper.c 1406) ret = -1;
fa38428f76 builtin/stash--helper.c 1432) ret = -1;
bec65d5b78 builtin/stash.c         1524) return env;
26799a208f builtin/stash.c         1552) const char *path = 
mkpath("%s/git-legacy-stash",
26799a208f builtin/stash.c         1555) if (sane_execvp(path, (char 
**)argv) < 0)
26799a208f builtin/stash.c         1556) die_errno(_("could not exec 
%s"), path);
51809c70ca builtin/stash.c         1599) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
51809c70ca builtin/stash.c         1627) continue;

builtin/submodule--helper.c
date.c
080448fbe8  113) die("Timestamp too large for this system: %"PRItime, time);
080448fbe8  223) hide.date = 1;
080448fbe8  886) static int auto_date_style(void)
080448fbe8  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
080448fbe8  911) return auto_date_style();

fetch-pack.c
01f9ec64c8  154) die(_("git fetch-pack: expected a flush packet after 
shallow list"));
01f9ec64c8  353) die(_("invalid shallow line: %s"), reader.line);
01f9ec64c8  359) die(_("invalid unshallow line: %s"), reader.line);
01f9ec64c8  361) die(_("object not found: %s"), reader.line);
01f9ec64c8  364) die(_("error in object: %s"), reader.line);
01f9ec64c8  366) die(_("no shallow found: %s"), reader.line);
01f9ec64c8  369) die(_("expected shallow/unshallow, got %s"), reader.line);

list-objects-filter.c
adbdcc0768 118) if (include_it)
e34ec45cce 119) return oidset_remove(filter_data->omits, &obj->oid);
e34ec45cce 121) return oidset_insert(filter_data->omits, &obj->oid);
adbdcc0768 167) already_seen =
adbdcc0768 168) filter_data->current_depth >= seen_info->depth;
adbdcc0768 171) filter_res = LOFR_SKIP_TREE;
adbdcc0768 178) filter_res = LOFR_DO_SHOW;
adbdcc0768 184) filter_res = LOFR_ZERO;

list-objects.c
04dac00473 241) continue;
04dac00473 250) parent->object.flags |= SHOWN;
04dac00473 251) show_edge(parent);
04dac00473 274) tree->object.flags |= UNINTERESTING;

midx.c
0d8e91f58b  806) error(_("did not see pack-file %s to drop"),
0d8e91f58b  808) drop_index++;
0d8e91f58b  809) i--;
0d8e91f58b  810) missing_drops++;
0d8e91f58b  811) continue;
0d8e91f58b  827) error(_("did not see all pack-files to drop"));
0d8e91f58b  828) result = 1;
0d8e91f58b  829) goto cleanup;
0d8e91f58b 1077) return 0;
0d8e91f58b 1092) continue;
0d8e91f58b 1095) continue;
c9b3585980 1130) return 1;
c9b3585980 1146) return 0;
c9b3585980 1155) continue;
c9b3585980 1168) continue;
c9b3585980 1191) error(_("could not start pack-objects"));
c9b3585980 1192) result = 1;
c9b3585980 1193) goto cleanup;
c9b3585980 1210) error(_("could not finish pack-objects"));
c9b3585980 1211) result = 1;
c9b3585980 1212) goto cleanup;

packfile.c
9133688752  369) strbuf_release(&buf);
9133688752  370) return;

pretty.c
4681fe38e1 1069) return 0;
b755bf6f83 1107)     match_placeholder_arg(p, "=on", end) ||
b755bf6f83 1108)     match_placeholder_arg(p, "=true", end)) {

protocol.c
6da1f1a920  37) die(_("Unrecognized protocol version"));
6da1f1a920  39) die(_("Unrecognized protocol_version"));
63bb981502  49) enum protocol_version version = 
parse_protocol_version(git_test_v);
63bb981502  51) if (version == protocol_unknown_version)
63bb981502  52) die("unknown value for %s: %s", git_test_k,
63bb981502  55) return version;

read-cache.c
43bf1db73e 1302) return 0;
43bf1db73e 1323) oidcpy(&backup_prev, &istate->cache[pos]->oid);
43bf1db73e 1343) update_backup_log(istate, &backup_prev, ce);
43bf1db73e 3215) strbuf_release(&sb);
43bf1db73e 3216) return -1;

refs/files-backend.c
c67027c9a9 1892) return;
c67027c9a9 1895) return;

remote-curl.c
6da1f1a920  344) return 0;
34a9469d6a  373) die("invalid server response; expected service, got 
flush packet");
34a9469d6a  397) d->proto_git = 1;

revision.c
497f2693ab  149) return;
497f2693ab  152) return;
497f2693ab  175) break;
04dac00473  197) continue;

send-pack.c
01f9ec64c8 143) return error(_("unable to parse remote unpack status: 
%s"), reader->line);
01f9ec64c8 162) error("invalid ref status from remote: %s", reader->line);
01f9ec64c8 579) receive_unpack_status(&reader);

strbuf.c
bfc3fe33f6  259) die("`pos' is too far after the end of the buffer");
bfc3fe33f6  266) return; /* nothing to do */
bfc3fe33f6  268) die("you want to use way too much memory");
18f8e81091  448) return 0;

submodule.c
26f80ccfc1 1398) strbuf_release(&gitdir);
be76c21282 1521) struct fetch_task *task = task_cb;
be76c21282 1525) fetch_task_release(task);
898c2e65b7 1806) warning(_("Could not unset core.worktree setting in 
submodule '%s'"),

unpack-trees.c
cc14089d7c  206) oidclr(&null_hash);
cc14089d7c  207) new_hash = &null_hash;
6f41cc899b 1716) index_path(NULL, old_hash, ce->name, &st,
6f41cc899b 1972)     old_hash && !lstat(ce->name, &st))
6f41cc899b 1973) index_path(NULL, old_hash, ce->name, &st,
cc14089d7c 2291) if (verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_REMOVED,
cc14089d7c 2294) make_backup(ce, &old_hash, NULL, o);

upload-pack.c
01f9ec64c8  428) die("git upload-pack: expected SHA1 list, got '%s'", 
reader->line);

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      63bb98150: tests: add a special setup where 
for protocol.version
Anders Waldenborg      18f8e8109: strbuf: separate callback for 
strbuf_expand:ing literals
Anders Waldenborg      4681fe38e: pretty: allow showing specific trailers
Anders Waldenborg      b755bf6f8: pretty: allow %(trailers) options with 
explicit value
Derrick Stolee      04dac0047: list-objects: consume sparse tree walk
Derrick Stolee      0d8e91f58: multi-pack-index: implement 'expire' verb
Derrick Stolee      497f2693a: revision: implement sparse algorithm
Derrick Stolee      5532d59aa: multi-pack-index: prepare 'repack' subcommand
Derrick Stolee      913368875: repack: refactor pack deletion for future use
Derrick Stolee      c9b358598: midx: implement midx_repack()
Jeff King      34a9469d6: remote-curl: refactor smart-http discovery
Joel Teichroeb      cdca49bc4: stash: convert drop and clear to builtin
Joel Teichroeb      e1d01876a: stash: convert pop to builtin
Joel Teichroeb      f6bbd7812: stash: convert apply to builtin
Johannes Schindelin      26799a208: stash: optionally use the scripted 
version again
Johannes Schindelin      2ead83aef: rebase: move `reset_head()` into a 
better spot
Johannes Schindelin      3bd5f0710: built-in rebase: call `git am` directly
Johannes Schindelin      81ef8ee75: rebase: introduce a shortcut for 
--reschedule-failed-exec
Johannes Schindelin      bec65d5b7: tests: add a special setup where 
stash.useBuiltin is off
Johannes Schindelin      d421afa0c: rebase: introduce 
--reschedule-failed-exec
Jonathan Tan      4d0feb763: builtin/fetch-pack: support protocol version 2
Josh Steadmon      6da1f1a92: protocol: advertise multiple supported 
versions
Junio C Hamano      d6af6af1f: Merge branch 
'sb/submodule-recursive-fetch-gets-the-tip' into pu
Linus Torvalds      080448fbe: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Masaya Suzuki      01f9ec64c: Use packet_reader instead of packet_read_line
Matthew DeVore      adbdcc076: list-objects-filter: teach tree:# how to 
handle >0
Matthew DeVore      e34ec45cc: tree:<depth>: skip some trees even when 
collecting omits
Nguyễn Thái Ngọc Duy      102b7856e: backup-log.c: add API for walking 
backup log
Nguyễn Thái Ngọc Duy      1fcfdf84c: apply: support backup log with 
--keep-backup
Nguyễn Thái Ngọc Duy      43bf1db73: read-cache.c: new flag for 
add_index_entry() to write to backup log
Nguyễn Thái Ngọc Duy      45f3e0cd9: backup-log: add diff command
Nguyễn Thái Ngọc Duy      6a05b9ab7: backup-log: add cat command
Nguyễn Thái Ngọc Duy      6f41cc899: reset --hard: keep backup of 
overwritten files
Nguyễn Thái Ngọc Duy      7f1d166ee: backup-log: add log command
Nguyễn Thái Ngọc Duy      937d6bee9: config --edit: support backup log
Nguyễn Thái Ngọc Duy      b2069b6eb: backup-log: keep all blob 
references around
Nguyễn Thái Ngọc Duy      b86e9ac72: gc: prune backup logs
Nguyễn Thái Ngọc Duy      bde028c66: backup-log: add prune command
Nguyễn Thái Ngọc Duy      c67027c9a: refs: keep backup of deleted reflog
Nguyễn Thái Ngọc Duy      cc14089d7: unpack-trees.c: keep backup of 
ignored files being overwritten
Nguyễn Thái Ngọc Duy      fdbbdf809: backup-log: add "update" subcommand
Paul-Sebastian Ungureanu      1f5a011d9: stash: convert create to builtin
Paul-Sebastian Ungureanu      51809c70c: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      847eb0b0a: stash: convert store to builtin
Paul-Sebastian Ungureanu      9a95010a1: stash: make push -q quiet
Paul-Sebastian Ungureanu      b4493f269: stash: convert show to builtin
Paul-Sebastian Ungureanu      bfc3fe33f: strbuf.c: add 
`strbuf_insertf()` and `strbuf_vinsertf()`
Paul-Sebastian Ungureanu      fa38428f7: stash: convert push to builtin
Stefan Beller      26f80ccfc: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      898c2e65b: submodule: unset core.worktree if no 
working tree is present
Stefan Beller      be76c2128: fetch: ensure submodule objects fetched
Stefan Beller      d5498e087: repository: repo_submodule_init to take a 
submodule struct



Uncovered code in 'jch' not in 'next'
----------------------------------------

builtin/bisect--helper.c
5e82c3dd22 builtin/bisect--helper.c 162) if (get_oid_commit(commit, &oid))
5e82c3dd22 builtin/bisect--helper.c 163) return error(_("'%s' is not a 
valid commit"), commit);
5e82c3dd22 builtin/bisect--helper.c 164) strbuf_addstr(&branch, commit);
5e82c3dd22 builtin/bisect--helper.c 172) strbuf_release(&branch);
5e82c3dd22 builtin/bisect--helper.c 173) argv_array_clear(&argv);
5e82c3dd22 builtin/bisect--helper.c 174) return error(_("could not check 
out original"
0f30233a11 builtin/bisect--helper.c 215) retval = error(_("Bad 
bisect_write argument: %s"), state);
0f30233a11 builtin/bisect--helper.c 216) goto finish;
0f30233a11 builtin/bisect--helper.c 220) retval = error(_("couldn't get 
the oid of the rev '%s'"), rev);
0f30233a11 builtin/bisect--helper.c 221) goto finish;
0f30233a11 builtin/bisect--helper.c 226) retval = -1;
0f30233a11 builtin/bisect--helper.c 227) goto finish;
0f30233a11 builtin/bisect--helper.c 232) retval = 
error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
0f30233a11 builtin/bisect--helper.c 233) goto finish;
129a6cf344 builtin/bisect--helper.c 329) yesno = git_prompt(_("Are you 
sure [Y/n]? "), PROMPT_ECHO);
129a6cf344 builtin/bisect--helper.c 330) if (starts_with(yesno, "N") || 
starts_with(yesno, "n"))
129a6cf344 builtin/bisect--helper.c 331) retval = -1;
129a6cf344 builtin/bisect--helper.c 332) goto finish;
129a6cf344 builtin/bisect--helper.c 338) retval = 
error(_(need_bisect_start_warning),
450ebb7359 builtin/bisect--helper.c 389) return error(_("invalid 
argument %s for 'git bisect terms'.\n"
06f5608c14 builtin/bisect--helper.c 404) return -1;
06f5608c14 builtin/bisect--helper.c 407) retval = -1;
06f5608c14 builtin/bisect--helper.c 408) goto finish;
06f5608c14 builtin/bisect--helper.c 413) retval = -1;
06f5608c14 builtin/bisect--helper.c 452) no_checkout = 1;
06f5608c14 builtin/bisect--helper.c 474)  !one_of(arg, "--term-good", 
"--term-bad", NULL)) {
06f5608c14 builtin/bisect--helper.c 475) return error(_("unrecognized 
option: '%s'"), arg);
06f5608c14 builtin/bisect--helper.c 510) if (get_oid("HEAD", &head_oid))
06f5608c14 builtin/bisect--helper.c 511) return error(_("bad HEAD - I 
need a HEAD"));
06f5608c14 builtin/bisect--helper.c 526) retval = error(_("checking out 
'%s' failed."
06f5608c14 builtin/bisect--helper.c 547) return error(_("won't bisect on 
cg-seek'ed tree"));
06f5608c14 builtin/bisect--helper.c 550) return error(_("bad HEAD - 
strange symbolic ref"));
06f5608c14 builtin/bisect--helper.c 558) return -1;
06f5608c14 builtin/bisect--helper.c 576) retval = -1;
06f5608c14 builtin/bisect--helper.c 577) goto finish;
06f5608c14 builtin/bisect--helper.c 588) retval = -1;
06f5608c14 builtin/bisect--helper.c 589) goto finish;
06f5608c14 builtin/bisect--helper.c 600) retval = -1;
5e82c3dd22 builtin/bisect--helper.c 677) return error(_("--bisect-reset 
requires either no argument or a commit"));
0f30233a11 builtin/bisect--helper.c 681) return error(_("--bisect-write 
requires either 4 or 5 arguments"));
4fbdbd5bff builtin/bisect--helper.c 687) return 
error(_("--check-and-set-terms requires 3 arguments"));
129a6cf344 builtin/bisect--helper.c 693) return 
error(_("--bisect-next-check requires 2 or 3 arguments"));

builtin/branch.c
7bdbccf4cb builtin/branch.c 370) strbuf_addf(&local, 
"%s%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)%%(worktreepath) 
%%(end)%%(end)%s",
0ecb1fc726 builtin/branch.c 460) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 466) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/checkout.c
da1c1cf6f5 builtin/checkout.c  302) return;
da1c1cf6f5 builtin/checkout.c 1268) die(_("'%s' cannot be used with 
switching branches"),

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

builtin/remote.c
f39a9c6547 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
f39a9c6547 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

builtin/worktree.c
00a6d4d1d2 752) found_submodules = 1;
00a6d4d1d2 753) break;

commit-graph.c
721351787e  127) return NULL;
721351787e  130) return NULL;
721351787e  186) free(graph);
721351787e  187) return NULL;
721351787e  222) free(graph);
721351787e  223) return NULL;

config.c
7e43b32b58 1488) return git_ident_config(var, value, cb);
7e43b32b58 1491) return git_ident_config(var, value, cb);

entry.c
hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

http-walker.c
e3180fd0b9 http-walker.c 550) loose_object_path(the_repository, &buf, 
&req->oid);

http.c
168badebdd 2004) FILE *new_file = freopen(dest->filename, "w", dest->file);
168badebdd 2005) if (new_file == NULL) {
168badebdd 2006) error("Unable to open local file %s", dest->filename);
168badebdd 2007) return HTTP_ERROR;
168badebdd 2009) dest->file = new_file;

ident.c
7e43b32b58 373) email = git_author_email.buf;
7e43b32b58 375) email = git_committer_email.buf;
7e43b32b58 394) name = git_author_name.buf;
7e43b32b58 396) name = git_committer_name.buf;
7e43b32b58 504) if (!value)
7e43b32b58 505) return config_error_nonbool(var);
7e43b32b58 506) strbuf_reset(&git_author_name);
7e43b32b58 507) strbuf_addstr(&git_author_name, value);
7e43b32b58 508) author_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b58 509) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b58 510) return 0;
7e43b32b58 514) if (!value)
7e43b32b58 515) return config_error_nonbool(var);
7e43b32b58 516) strbuf_reset(&git_author_email);
7e43b32b58 517) strbuf_addstr(&git_author_email, value);
7e43b32b58 518) author_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b58 519) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b58 520) return 0;
7e43b32b58 524) if (!value)
7e43b32b58 525) return config_error_nonbool(var);
7e43b32b58 526) strbuf_reset(&git_committer_name);
7e43b32b58 527) strbuf_addstr(&git_committer_name, value);
7e43b32b58 528) committer_ident_explicitly_given |= IDENT_NAME_GIVEN;
7e43b32b58 529) ident_config_given |= IDENT_NAME_GIVEN;
7e43b32b58 530) return 0;
7e43b32b58 534) if (!value)
7e43b32b58 535) return config_error_nonbool(var);
7e43b32b58 536) strbuf_reset(&git_committer_email);
7e43b32b58 537) strbuf_addstr(&git_committer_email, value);
7e43b32b58 538) committer_ident_explicitly_given |= IDENT_MAIL_GIVEN;
7e43b32b58 539) ident_config_given |= IDENT_MAIL_GIVEN;
7e43b32b58 540) return 0;

read-cache.c
ee70c12820 1736) if (advice_unknown_index_extension) {
ee70c12820 1737) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1738) advise(_("This is likely due to the file having been 
written by a newer\n"

ref-filter.c
1867ce6cbe  254) oi_deref.info.sizep = &oi_deref.size;
1867ce6cbe  263) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
33311fa1ad  271) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
70550aa6d2  467) return 0;

remote-curl.c
168badebdd  566) return size;

sequencer.c
899b49c446 2393) opts->quiet = 1;

setup.c
07098b81a4 1093) if (!nongit_ok)
07098b81a4 1094) die(_("not a git repository (or any parent up to mount 
point %s)\n"
07098b81a4 1097) *nongit_ok = 1;
07098b81a4 1098) break;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;
e3180fd0b9 sha1-file.c 1294) status = error(_("unable to parse %s 
header"), oid_to_hex(oid));
aff8ab85b9 sha1-file.c 2312) the_hash_algo->final_fn(real_oid.hash, &c);
aff8ab85b9 sha1-file.c 2313) if (!oideq(expected_oid, &real_oid)) {

transport-helper.c
3b3357626e 1029) static int has_attribute(const char *attrs, const char 
*attr)

wrapper.c
e3b1e3bdc0 701) die_errno(_("could not stat %s"), filename);

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Denton Liu      f39a9c654: remote: add --save-to-push option to git 
remote set-url
Elijah Newren      899b49c44: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Erin Dahlgren      07098b81a: Simplify handling of 
setup_git_directory_gently() failure cases.
Jeff King      aff8ab85b: sha1-file: modernize loose header/stream functions
Jeff King      e3180fd0b: sha1-file: modernize loose object file functions
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Josh Steadmon      721351787: commit-graph, fuzz: add fuzzer for 
commit-graph
Masaya Suzuki      168badebd: Change how HTTP response body is returned
Nguyễn Thái Ngọc Duy      00a6d4d1d: worktree: allow to (re)move 
worktrees with uninitialized submodules
Nguyễn Thái Ngọc Duy      3b3357626: style: the opening '{' of a 
function is in a separate line
Nickolai Belakovski      70550aa6d: ref-filter: add worktreepath atom
Nickolai Belakovski      7bdbccf4c: branch: add an extra verbose output 
displaying worktree path for checked out branch
Olga Telezhnaya      1867ce6cb: ref-filter: add objectsize:disk option
Olga Telezhnaya      33311fa1a: ref-filter: add deltabase option
Pranit Bauva      06f5608c1: bisect--helper: `bisect_start` shell 
function partially in C
Pranit Bauva      0f30233a1: bisect--helper: `bisect_write` shell 
function in C
Pranit Bauva      129a6cf34: bisect--helper: `bisect_next_check` shell 
function in C
Pranit Bauva      450ebb735: bisect--helper: `get_terms` & 
`bisect_terms` shell function in C
Pranit Bauva      4fbdbd5bf: bisect--helper: `check_and_set_terms` shell 
function in C
Pranit Bauva      5e82c3dd2: bisect--helper: `bisect_reset` shell 
function in C
Pranit Bauva      e3b1e3bdc: wrapper: move is_empty_file() and rename it 
as is_empty_or_missing_file()
Thomas Gummerer      da1c1cf6f: checkout: introduce --{,no-}overlay option
William Hubbs      7e43b32b5: Add author and committer configuration 
settings



Uncovered code in 'next' not in 'master'
--------------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

pathspec.c
22af33bece 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
ec36c42a63 3498) const char *index = NULL;
ec36c42a63 3504) if (!offset)
ec36c42a63 3505) return NULL;
ec36c42a63 3506) while (offset <= mmap_size - the_hash_algo->rawsz - 8) {
ec36c42a63 3507) extsize = get_be32(mmap + offset + 4);
ec36c42a63 3508) if (CACHE_EXT((mmap + offset)) == 
CACHE_EXT_INDEXENTRYOFFSETTABLE) {
ec36c42a63 3509) index = mmap + offset + 4 + 4;
ec36c42a63 3510) break;
ec36c42a63 3512) offset += 8;
ec36c42a63 3513) offset += extsize;
ec36c42a63 3515) if (!index)
ec36c42a63 3516) return NULL;
ec36c42a63 3519) ext_version = get_be32(index);
ec36c42a63 3520) if (ext_version != IEOT_VERSION) {
ec36c42a63 3521) error("invalid IEOT version %d", ext_version);
ec36c42a63 3522) return NULL;
ec36c42a63 3524) index += sizeof(uint32_t);
ec36c42a63 3527) nr = (extsize - sizeof(uint32_t)) / (sizeof(uint32_t) + 
sizeof(uint32_t));
ec36c42a63 3528) if (!nr) {
ec36c42a63 3529) error("invalid number of IEOT entries %d", nr);
ec36c42a63 3530) return NULL;
ec36c42a63 3532) ieot = xmalloc(sizeof(struct index_entry_offset_table)
ec36c42a63 3533)        + (nr * sizeof(struct index_entry_offset)));
ec36c42a63 3534) ieot->nr = nr;
ec36c42a63 3535) for (i = 0; i < nr; i++) {
ec36c42a63 3536) ieot->entries[i].offset = get_be32(index);
ec36c42a63 3537) index += sizeof(uint32_t);
ec36c42a63 3538) ieot->entries[i].nr = get_be32(index);
ec36c42a63 3539) index += sizeof(uint32_t);
ec36c42a63 3542) return ieot;

tree.c
e092073d64 104) commit = lookup_commit(r, entry.oid);

Commits introducing uncovered code:
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths
Nguyễn Thái Ngọc Duy      22af33bec: dir.c: move, rename and export 
match_attrs()
Nguyễn Thái Ngọc Duy      e092073d6: tree.c: make read_tree*() take 
'struct repository *'
Nguyễn Thái Ngọc Duy      ec36c42a6: Indent code with TABs



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 420) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 459) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 583) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 618) fprintf_ln(stderr, _("Checking object 
directory"));
3813a89fae builtin/fsck.c 636) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
3813a89fae builtin/fsck.c 641) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 670) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 686) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
3813a89fae 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
3813a89fae 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
a965bb3116 1821) read_next_command();

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 653) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 787) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2251) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2286) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3100) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3247) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
9440b831ad 2330) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2139) return r;

Commits introducing uncovered code:
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Junio C Hamano      3813a89fa: Merge branch 'nd/i18n'
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository



^ permalink raw reply	[relevance 3%]

* Git Test Coverage Report (Saturday, Dec 29)
@ 2018-12-29 22:31  2% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-12-29 22:31 UTC (permalink / raw)
  To: git@vger.kernel.org

Here is today's test coverage report.

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=289

---


pu: e31bc98f4bb8c7cf2a943a3b3b3de69a34a4349c
jch: 5442582aa4fe91238d2c294660d08fc1e0efc8b7
next: 81188d93c3fce477216ba905bd37ab453a74b11d
master: b21ebb671bb7dea8d342225f0d66c41f4e54d5ca
master@{1}: 7a95a1cd084cb665c5c2586a415e42df0213af74

Uncovered code in 'pu' not in 'jch'
--------------------------------------

apply.c
1fcfdf84ce 4275) oidclr(&patch->old_oid);

backup-log.c
fdbbdf809f  25) return error_errno(_("unable to open %s"), path);
fdbbdf809f  27) close(fd);
fdbbdf809f  28) return error_errno(_("unable to update %s"), path);
fdbbdf809f  41) return -1;
102b7856e3  63) return -1;/* corrupt? */
102b7856e3  71) return -1; /* corrupt? */
102b7856e3  75) message += 6;
102b7856e3 105) if (errno == ENOENT || errno == ENOTDIR)
102b7856e3 106) return 0;
102b7856e3 107) return -1;
102b7856e3 112) ret = error_errno(_("cannot seek back in %s"), path);
102b7856e3 123) ret = error_errno(_("cannot seek back in %s"), path);
102b7856e3 124) break;
102b7856e3 128) ret = error_errno(_("cannot read %d bytes from %s"),
102b7856e3 130) break;
102b7856e3 189) strbuf_splice(&sb, 0, 0, buf, endp - buf);
102b7856e3 190) break;
102b7856e3 215) return -1;
102b7856e3 219) ret = parse(&sb, data);
bde028c667 232) static int good_oid(struct repository *r, const struct 
object_id *oid)
bde028c667 234) if (is_null_oid(oid))
bde028c667 235) return 1;
bde028c667 237) return oid_object_info(r, oid, NULL) == OBJ_BLOB;
bde028c667 240) static int prune_parse(struct strbuf *line, void *data)
bde028c667 242) struct prune_options *opts = data;
bde028c667 245) strbuf_reset(&opts->copy);
bde028c667 246) strbuf_addbuf(&opts->copy, line);
bde028c667 248) if (bkl_parse_entry(line, &entry))
bde028c667 249) return -1;
bde028c667 251) if (entry.timestamp < opts->expire)
bde028c667 252) return 0;
bde028c667 254) if (oideq(&entry.old_oid, &entry.new_oid))
bde028c667 255) return 0;
bde028c667 257) if (!good_oid(opts->repo, &entry.old_oid) ||
bde028c667 258)     !good_oid(opts->repo, &entry.new_oid))
bde028c667 259) return 0;
bde028c667 261) if (!opts->fp)
bde028c667 262) return -1;
bde028c667 264) fputs(opts->copy.buf, opts->fp);
bde028c667 265) return 0;
bde028c667 278) return error(_("failed to lock '%s'"), path);
bde028c667 287) rollback_lock_file(&lk);
b86e9ac723 301) die(_("failed to prune %s"), "gitdir.bkl");
b86e9ac723 309) if (wt->id)
b86e9ac723 310) die(_("failed to prune %s on working tree '%s'"),
b86e9ac723 313) die(_("failed to prune %s"), "index.bkl");
b86e9ac723 316) if (wt->id)
b86e9ac723 317) die(_("failed to prune %s on working tree '%s'"),
b86e9ac723 320) die(_("failed to prune %s"), "worktree.bkl");
b2069b6eb0 331) static void add_blob_to_pending(const struct object_id *oid,
b2069b6eb0 337) if (!good_oid(cb->revs->repo, oid))
b2069b6eb0 338) return;
b2069b6eb0 340) blob = lookup_blob(cb->revs->repo, oid);
b2069b6eb0 341) blob->object.flags |= cb->flags;
b2069b6eb0 342) add_pending_object(cb->revs, &blob->object, path);
b2069b6eb0 345) static int add_pending(struct strbuf *line, void *cb)
b2069b6eb0 349) if (bkl_parse_entry(line, &entry))
b2069b6eb0 350) return -1;
b2069b6eb0 352) add_blob_to_pending(&entry.old_oid, entry.path, cb);
b2069b6eb0 353) add_blob_to_pending(&entry.new_oid, entry.path, cb);
b2069b6eb0 354) return 0;

bisect.c
04dac00473  661) mark_edges_uninteresting(revs, NULL, 0);

builtin/backup-log.c
fdbbdf809f  28) usage_with_options(backup_log_usage, NULL);
fdbbdf809f  33) die(_("not a valid object name: %s"), argv[2]);
fdbbdf809f  36) die(_("not a valid object name: %s"), argv[3]);
6a05b9ab74  62) return -1;
6a05b9ab74  65) return 2;
6a05b9ab74  69) return 0;
6a05b9ab74  82) return 1;/* treat null oid like empty blob */
6a05b9ab74  86) die(_("object not found: %s"), oid_to_hex(oid));
6a05b9ab74  88) die(_("not a blob: %s"), oid_to_hex(oid));
6a05b9ab74 111) usage_with_options(backup_log_usage, options);
6a05b9ab74 114) die(_("not a valid change id: %s"), argv[0]);
6a05b9ab74 119) die(_("failed to parse '%s'"), log_path);
45f3e0cd9d 130) old = the_hash_algo->empty_blob;
45f3e0cd9d 135) new = the_hash_algo->empty_blob;
45f3e0cd9d 140) return;
45f3e0cd9d 156) return -1;
45f3e0cd9d 162) return 0;
45f3e0cd9d 183) found_dash_dash = 1;
45f3e0cd9d 184) i++;
45f3e0cd9d 185) continue;
45f3e0cd9d 189) exit(128);
45f3e0cd9d 196) die(_("not a valid change id: %s"), arg);
45f3e0cd9d 204) usage_with_options(backup_log_usage, NULL);
45f3e0cd9d 208) die(_("failed to parse '%s'"), log_path);
7f1d166ee1 252) return -1;
7f1d166ee1 255) return 1;
7f1d166ee1 260) return 0;
7f1d166ee1 283) opts.revs.diffopt.output_format = DIFF_FORMAT_PATCH;
7f1d166ee1 284) diff_setup_done(&opts.revs.diffopt);
7f1d166ee1 293) ret = bkl_parse_file(log_path, log_parse, &opts);
7f1d166ee1 298) die(_("failed to parse '%s'"), log_path);
bde028c667 304) static int prune(int argc, const char **argv,
bde028c667 307) timestamp_t expire = time(NULL) - 90 * 24 * 3600;
bde028c667 308) struct option options[] = {
bde028c667 314) argc = parse_options(argc, argv, prefix, options, 
backup_log_usage, 0);
bde028c667 316) return bkl_prune(the_repository, log_path, expire);
fdbbdf809f 323) else if (!strcmp(id, "worktree"))
fdbbdf809f 324) return git_pathdup("worktree.bkl");
fdbbdf809f 325) else if (!strcmp(id, "gitdir"))
fdbbdf809f 326) return git_pathdup("common/gitdir.bkl");
fdbbdf809f 328) die(_("backup log id '%s' is not recognized"), id);
fdbbdf809f 346) die(_("expected a subcommand"));
fdbbdf809f 350) die(_("--id and --path are incompatible"));
fdbbdf809f 354) die(_("either --id or --path is required"));
bde028c667 364) else if (!strcmp(argv[0], "prune"))
bde028c667 365) return prune(argc, argv, prefix, log_path);

builtin/blame.c
74e8221b52 builtin/blame.c    930) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    931) break;

builtin/checkout.c
20e835df5c builtin/checkout.c 1271) die(_("'%s' cannot be used with 
switching branches"),
4ed0c8eb49 builtin/checkout.c 1275) die(_("'%s' cannot be used with 
switching branches"),

builtin/config.c
937d6bee9e builtin/config.c      604) oidclr(oid);

builtin/multi-pack-index.c
e86a2be882 49) die(_("--batch-size option is only for 'repack' verb"));

builtin/rebase.c
81ef8ee75d  764) return -1;
d421afa0c6 1253) die(_("--reschedule-failed-exec requires an interactive 
rebase"));
d421afa0c6 1291) die(_("error: cannot combine '--preserve-merges' with "

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

entry.c
list-objects.c
04dac00473 241) continue;
04dac00473 250) parent->object.flags |= SHOWN;
04dac00473 251) show_edge(parent);
04dac00473 274) tree->object.flags |= UNINTERESTING;

midx.c
5518ac8ee4  806) error(_("did not see pack-file %s to drop"),
5518ac8ee4  808) drop_index++;
5518ac8ee4  809) i--;
5518ac8ee4  810) missing_drops++;
5518ac8ee4  826) error(_("did not see all pack-files to drop"));
5518ac8ee4  827) result = 1;
5518ac8ee4  828) goto cleanup;
5518ac8ee4 1078) return 0;
5518ac8ee4 1095) close_pack(m->packs[i]);
5518ac8ee4 1096) m->packs[i] = NULL;
b59c492264 1133) return -1;
b59c492264 1135) return 1;
b59c492264 1151) return 0;
b59c492264 1160) continue;
b59c492264 1173) continue;
b59c492264 1196) error(_("could not start pack-objects"));
b59c492264 1197) result = 1;
b59c492264 1198) goto cleanup;
b59c492264 1215) error(_("could not finish pack-objects"));
b59c492264 1216) result = 1;
b59c492264 1217) goto cleanup;

pretty.c
4681fe38e1 1069) return 0;
b755bf6f83 1107)     match_placeholder_arg(p, "=on", end) ||
b755bf6f83 1108)     match_placeholder_arg(p, "=true", end)) {

protocol.c
24c10f7473  37) die(_("Unrecognized protocol version"));
24c10f7473  39) die(_("Unrecognized protocol_version"));

read-cache.c
43bf1db73e 1323) oidcpy(&backup_prev, &istate->cache[pos]->oid);
43bf1db73e 1343) update_backup_log(istate, &backup_prev, ce);
43bf1db73e 3215) strbuf_release(&sb);
43bf1db73e 3216) return -1;

refs/files-backend.c
c67027c9a9 1892) return;
c67027c9a9 1895) return;

remote-curl.c
24c10f7473  400) return 0;

revision.c
497f2693ab  149) return;
497f2693ab  152) return;
497f2693ab  175) break;
04dac00473  197) continue;

strbuf.c
18f8e81091  397) return 0;

submodule.c
26f80ccfc1 1396) strbuf_release(&gitdir);
be76c21282 1519) struct fetch_task *task = task_cb;
be76c21282 1523) fetch_task_release(task);

unpack-trees.c
cc14089d7c  206) oidclr(&null_hash);
cc14089d7c  207) new_hash = &null_hash;
6f41cc899b 1716) index_path(NULL, old_hash, ce->name, &st,
6f41cc899b 1972)     old_hash && !lstat(ce->name, &st))
6f41cc899b 1973) index_path(NULL, old_hash, ce->name, &st,
cc14089d7c 2291) if (verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_REMOVED,
cc14089d7c 2294) make_backup(ce, &old_hash, NULL, o);

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Anders Waldenborg      18f8e8109: strbuf: separate callback for 
strbuf_expand:ing literals
Anders Waldenborg      4681fe38e: pretty: allow showing specific trailers
Anders Waldenborg      b755bf6f8: pretty: allow %(trailers) options with 
explicit value
Derrick Stolee      04dac0047: list-objects: consume sparse tree walk
Derrick Stolee      497f2693a: revision: implement sparse algorithm
Derrick Stolee      5518ac8ee: multi-pack-index: implement 'expire' verb
Derrick Stolee      b59c49226: multi-pack-index: implement midx_repack()
Derrick Stolee      e86a2be88: multi-pack-index: prepare 'repack' verb
Johannes Schindelin      81ef8ee75: rebase: introduce a shortcut for 
--reschedule-failed-exec
Johannes Schindelin      d421afa0c: rebase: introduce 
--reschedule-failed-exec
Josh Steadmon      24c10f747: protocol: advertise multiple supported 
versions
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      102b7856e: backup-log.c: add API for walking 
backup log
Nguyễn Thái Ngọc Duy      1fcfdf84c: apply: support backup log with 
--keep-backup
Nguyễn Thái Ngọc Duy      43bf1db73: read-cache.c: new flag for 
add_index_entry() to write to backup log
Nguyễn Thái Ngọc Duy      45f3e0cd9: backup-log: add diff command
Nguyễn Thái Ngọc Duy      6a05b9ab7: backup-log: add cat command
Nguyễn Thái Ngọc Duy      6f41cc899: reset --hard: keep backup of 
overwritten files
Nguyễn Thái Ngọc Duy      7f1d166ee: backup-log: add log command
Nguyễn Thái Ngọc Duy      937d6bee9: config --edit: support backup log
Nguyễn Thái Ngọc Duy      b2069b6eb: backup-log: keep all blob 
references around
Nguyễn Thái Ngọc Duy      b86e9ac72: gc: prune backup logs
Nguyễn Thái Ngọc Duy      bde028c66: backup-log: add prune command
Nguyễn Thái Ngọc Duy      c67027c9a: refs: keep backup of deleted reflog
Nguyễn Thái Ngọc Duy      cc14089d7: unpack-trees.c: keep backup of 
ignored files being overwritten
Nguyễn Thái Ngọc Duy      fdbbdf809: backup-log: add "update" subcommand
Stefan Beller      26f80ccfc: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      be76c2128: fetch: ensure submodule objects fetched
Thomas Gummerer      20e835df5: checkout: add --cached option
Thomas Gummerer      4ed0c8eb4: checkout: introduce --{,no-}overlay option



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

builtin/remote.c
f39a9c6547 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
f39a9c6547 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

commit-graph.c
721351787e  128) return NULL;
721351787e  131) return NULL;
721351787e  187) free(graph);
721351787e  188) return NULL;
721351787e  223) free(graph);
721351787e  224) return NULL;

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

pathspec.c
22af33bece 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
ee70c12820 1730) if (advice_unknown_index_extension) {
ee70c12820 1731) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1732) advise(_("This is likely due to the file having been 
written by a newer\n"
ec36c42a63 3508) const char *index = NULL;
ec36c42a63 3514) if (!offset)
ec36c42a63 3515) return NULL;
ec36c42a63 3516) while (offset <= mmap_size - the_hash_algo->rawsz - 8) {
ec36c42a63 3517) extsize = get_be32(mmap + offset + 4);
ec36c42a63 3518) if (CACHE_EXT((mmap + offset)) == 
CACHE_EXT_INDEXENTRYOFFSETTABLE) {
ec36c42a63 3519) index = mmap + offset + 4 + 4;
ec36c42a63 3520) break;
ec36c42a63 3522) offset += 8;
ec36c42a63 3523) offset += extsize;
ec36c42a63 3525) if (!index)
ec36c42a63 3526) return NULL;
ec36c42a63 3529) ext_version = get_be32(index);
ec36c42a63 3530) if (ext_version != IEOT_VERSION) {
ec36c42a63 3531) error("invalid IEOT version %d", ext_version);
ec36c42a63 3532) return NULL;
ec36c42a63 3534) index += sizeof(uint32_t);
ec36c42a63 3537) nr = (extsize - sizeof(uint32_t)) / (sizeof(uint32_t) + 
sizeof(uint32_t));
ec36c42a63 3538) if (!nr) {
ec36c42a63 3539) error("invalid number of IEOT entries %d", nr);
ec36c42a63 3540) return NULL;
ec36c42a63 3542) ieot = xmalloc(sizeof(struct index_entry_offset_table)
ec36c42a63 3543)        + (nr * sizeof(struct index_entry_offset)));
ec36c42a63 3544) ieot->nr = nr;
ec36c42a63 3545) for (i = 0; i < nr; i++) {
ec36c42a63 3546) ieot->entries[i].offset = get_be32(index);
ec36c42a63 3547) index += sizeof(uint32_t);
ec36c42a63 3548) ieot->entries[i].nr = get_be32(index);
ec36c42a63 3549) index += sizeof(uint32_t);
ec36c42a63 3552) return ieot;

ref-filter.c
bbfc042ef9  238) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  247) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  255) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));

remote-curl.c
80bb63786c  359) die("invalid server response; expected service, got 
flush packet");

sequencer.c
18e711a162 2389) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

transport-helper.c
3b3357626e 1029) static int has_attribute(const char *attrs, const char 
*attr)

tree.c
e092073d64 104) commit = lookup_commit(r, entry.oid);

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Denton Liu      f39a9c654: remote: add --save-to-push option to git 
remote set-url
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Jeff King      80bb63786: remote-curl: refactor smart-http discovery
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Josh Steadmon      721351787: commit-graph, fuzz: add fuzzer for 
commit-graph
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths
Nguyễn Thái Ngọc Duy      22af33bec: dir.c: move, rename and export 
match_attrs()
Nguyễn Thái Ngọc Duy      3b3357626: style: the opening '{' of a 
function is in a separate line
Nguyễn Thái Ngọc Duy      e092073d6: tree.c: make read_tree*() take 
'struct repository *'
Nguyễn Thái Ngọc Duy      ec36c42a6: Indent code with TABs
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option



Uncovered code in 'next' not in 'master'
--------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 420) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 459) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 583) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 618) fprintf_ln(stderr, _("Checking object 
directory"));
8e2de8338e builtin/fsck.c 636) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
8e2de8338e builtin/fsck.c 641) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 670) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 686) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
8e2de8338e 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
8e2de8338e 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
a965bb3116 1821) read_next_command();

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 653) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 787) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2251) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2286) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3100) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3247) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
9440b831ad 2330) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2139) return r;

Commits introducing uncovered code:
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Junio C Hamano      8e2de8338: Merge branch 'nd/i18n' into next
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository










^ permalink raw reply	[relevance 2%]

* Re: [PATCH 00/23] sb/more-repo-in-api
  2018-12-15  0:09  7% [PATCH 00/23] sb/more-repo-in-api Stefan Beller
  2018-12-15  0:09 20% ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
  2018-12-15  0:09 14% ` [PATCH 19/23] submodule: don't add submodule as odb for push Stefan Beller
@ 2018-12-26 18:42  2% ` Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-26 18:42 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> I realized next has not been rewound, so I can resend sb/more-repo-in-api,
> which I hereby do. The changes are minimal and address the only comment
> by Jonathan so far.

Yeah, the only change I see matches what is in your range-diff after
applying them to my tree.

Will rewind 'next' by the end of the year and replace the topic.  Thanks.

> 1:  99017ffac8 ! 1:  f24b120287 submodule: use submodule repos for object lookup
>     @@ -40,12 +40,13 @@
>      - * attempt to lookup both the left and right commits and put them into the
>      - * left and right pointers.
>      +/*
>     -+ * Initialize 'out' based on the provided submodule path.
>     ++ * Initialize a repository struct for a submodule based on the provided 'path'.
>      + *
>      + * Unlike repo_submodule_init, this tolerates submodules not present
>      + * in .gitmodules. This function exists only to preserve historical behavior,
>      + *
>     -+ * Returns 0 on success, -1 when the submodule is not present.
>     ++ * Returns the repository struct on success,
>     ++ * NULL when the submodule is not present.
>        */
>      -static void show_submodule_header(struct diff_options *o, const char *path,
>      +static struct repository *open_submodule(const char *path)
>     @@ -59,6 +60,7 @@
>      +		return NULL;
>      +	}
>      +
>     ++	/* Mark it as a submodule */
>      +	out->submodule_prefix = xstrdup(path);
>      +
>      +	strbuf_release(&sb);
> 2:  809765861c = 2:  25190d6174 submodule: don't add submodule as odb for push
> 3:  4a7735da72 = 3:  965421aab2 commit-graph: convert remaining functions to handle any repo
> 4:  aeeb1ba49e = 4:  bf31f32723 commit: prepare free_commit_buffer and release_commit_memory for any repo
> 5:  5ffebe9463 = 5:  c4e54e6b0d path.h: make REPO_GIT_PATH_FUNC repository agnostic
> 6:  9c89920c46 = 6:  a7ed0c57ba t/helper/test-repository: celebrate independence from the_repository

^ permalink raw reply	[relevance 2%]

* Re: [PATCH 2/4] submodule: unset core.worktree if no working tree is present
  2018-12-14 23:59 18%     ` [PATCH 2/4] submodule: unset core.worktree if no working tree is present Stefan Beller
@ 2018-12-26 18:27  4%       ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-26 18:27 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> 2018-09-07). The revert was needed as the nearby commit e98317508c
> (submodule: ensure core.worktree is set after update, 2018-06-18) is
> faulty and at the time of 7e25437d35 (Merge branch
> 'sb/submodule-core-worktree', 2018-07-18) we could not revert the faulty
> commit only, as they were depending on each other: If core.worktree is
> unset, we have to have ways to ensure that it is set again once
> the working tree reappears again.
>
> Now that 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17),
> specifically 74d4731da1 (submodule--helper: replace
> connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13) is
> present, we already check and ensure core.worktree is set when
> populating a new work tree, such that we can re-introduce the commits
> that unset core.worktree when removing the worktree.

Cleanly explained.  Will queue.  Thanks.

> Signed-off-by: Stefan Beller <sbeller@google.com>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c               | 14 ++++++++++++++
>  submodule.h               |  2 ++
>  t/lib-submodule-update.sh |  3 ++-
>  3 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/submodule.c b/submodule.c
> index 6415cc5580..d393e947e6 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1561,6 +1561,18 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
>  	return ret;
>  }
>  
> +void submodule_unset_core_worktree(const struct submodule *sub)
> +{
> +	char *config_path = xstrfmt("%s/modules/%s/config",
> +				    get_git_common_dir(), sub->name);
> +
> +	if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
> +		warning(_("Could not unset core.worktree setting in submodule '%s'"),
> +			  sub->path);
> +
> +	free(config_path);
> +}
> +
>  static const char *get_super_prefix_or_empty(void)
>  {
>  	const char *s = get_super_prefix();
> @@ -1726,6 +1738,8 @@ int submodule_move_head(const char *path,
>  
>  			if (is_empty_dir(path))
>  				rmdir_or_warn(path);
> +
> +			submodule_unset_core_worktree(sub);
>  		}
>  	}
>  out:
> diff --git a/submodule.h b/submodule.h
> index a680214c01..9e18e9b807 100644
> --- a/submodule.h
> +++ b/submodule.h
> @@ -131,6 +131,8 @@ int submodule_move_head(const char *path,
>  			const char *new_head,
>  			unsigned flags);
>  
> +void submodule_unset_core_worktree(const struct submodule *sub);
> +
>  /*
>   * Prepare the "env_array" parameter of a "struct child_process" for executing
>   * a submodule by clearing any repo-specific environment variables, but
> diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
> index 016391723c..51d4555549 100755
> --- a/t/lib-submodule-update.sh
> +++ b/t/lib-submodule-update.sh
> @@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() {
>  			git branch -t remove_sub1 origin/remove_sub1 &&
>  			$command remove_sub1 &&
>  			test_superproject_content origin/remove_sub1 &&
> -			! test -e sub1
> +			! test -e sub1 &&
> +			test_must_fail git config -f .git/modules/sub1/config core.worktree
>  		)
>  	'
>  	# ... absorbing a .git directory along the way.

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 1/4] submodule update: add regression test with old style setups
  2018-12-14 23:59 25%     ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
@ 2018-12-26 18:21  4%       ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-26 18:21 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> The place to add such a regression test may look odd in t7412, but
> that is the best place as there we setup old style submodule setups
> explicitly.

Makes sense; thanks.

>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  t/t7412-submodule-absorbgitdirs.sh | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
> index ce74c12da2..1cfa150768 100755
> --- a/t/t7412-submodule-absorbgitdirs.sh
> +++ b/t/t7412-submodule-absorbgitdirs.sh
> @@ -75,7 +75,12 @@ test_expect_success 're-setup nested submodule' '
>  	GIT_WORK_TREE=../../../nested git -C sub1/.git/modules/nested config \
>  		core.worktree "../../../nested" &&
>  	# make sure this re-setup is correct
> -	git status --ignore-submodules=none
> +	git status --ignore-submodules=none &&
> +
> +	# also make sure this old setup does not regress
> +	git submodule update --init --recursive >out 2>err &&
> +	test_must_be_empty out &&
> +	test_must_be_empty err
>  '
>  
>  test_expect_success 'absorb the git dir in a nested submodule' '

^ permalink raw reply	[relevance 4%]

* [PATCH 19/23] submodule: don't add submodule as odb for push
  2018-12-15  0:09  7% [PATCH 00/23] sb/more-repo-in-api Stefan Beller
  2018-12-15  0:09 20% ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-12-15  0:09 14% ` Stefan Beller
  2018-12-26 18:42  2% ` [PATCH 00/23] sb/more-repo-in-api Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-15  0:09 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, Junio C Hamano

In push_submodule(), because we do not actually need access to objects
in the submodule, do not invoke add_submodule_odb().
(for_each_remote_ref_submodule() does not require access to those
objects, and the actual push is done by spawning another process,
which handles object access by itself.)

This code of push_submodule() is exercised in t5531 and continues
to work, showing that the submodule odbc is not needed.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index 4486ff664b..d9c06767a1 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1023,9 +1023,6 @@ static int push_submodule(const char *path,
 			  const struct string_list *push_options,
 			  int dry_run)
 {
-	if (add_submodule_odb(path))
-		return 1;
-
 	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
 		struct child_process cp = CHILD_PROCESS_INIT;
 		argv_array_push(&cp.args, "push");
-- 
2.20.0.405.gbc1bbc6f85-goog


^ permalink raw reply related	[relevance 14%]

* [PATCH 18/23] submodule: use submodule repos for object lookup
  2018-12-15  0:09  7% [PATCH 00/23] sb/more-repo-in-api Stefan Beller
@ 2018-12-15  0:09 20% ` Stefan Beller
  2018-12-15  0:09 14% ` [PATCH 19/23] submodule: don't add submodule as odb for push Stefan Beller
  2018-12-26 18:42  2% ` [PATCH 00/23] sb/more-repo-in-api Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-15  0:09 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, Junio C Hamano

This converts the 'show_submodule_header' function to use
the repository API properly, such that the submodule objects
are not added to the main object store.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c | 75 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 60 insertions(+), 15 deletions(-)

diff --git a/submodule.c b/submodule.c
index d9d3046689..4486ff664b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
 	return prepare_revision_walk(rev);
 }
 
-static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
+static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
 {
 	static const char format[] = "  %m %s";
 	struct strbuf sb = STRBUF_INIT;
@@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
 		ctx.date_mode = rev->date_mode;
 		ctx.output_encoding = get_log_output_encoding();
 		strbuf_setlen(&sb, 0);
-		format_commit_message(commit, format, &sb, &ctx);
+		repo_format_commit_message(r, commit, format, &sb,
+				      &ctx);
 		strbuf_addch(&sb, '\n');
 		if (commit->object.flags & SYMMETRIC_LEFT)
 			diff_emit_submodule_del(o, sb.buf);
@@ -481,14 +482,46 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
-/* Helper function to display the submodule header line prior to the full
- * summary output. If it can locate the submodule objects directory it will
- * attempt to lookup both the left and right commits and put them into the
- * left and right pointers.
+/*
+ * Initialize a repository struct for a submodule based on the provided 'path'.
+ *
+ * Unlike repo_submodule_init, this tolerates submodules not present
+ * in .gitmodules. This function exists only to preserve historical behavior,
+ *
+ * Returns the repository struct on success,
+ * NULL when the submodule is not present.
  */
-static void show_submodule_header(struct diff_options *o, const char *path,
+static struct repository *open_submodule(const char *path)
+{
+	struct strbuf sb = STRBUF_INIT;
+	struct repository *out = xmalloc(sizeof(*out));
+
+	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
+		strbuf_release(&sb);
+		free(out);
+		return NULL;
+	}
+
+	/* Mark it as a submodule */
+	out->submodule_prefix = xstrdup(path);
+
+	strbuf_release(&sb);
+	return out;
+}
+
+/*
+ * Helper function to display the submodule header line prior to the full
+ * summary output.
+ *
+ * If it can locate the submodule git directory it will create a repository
+ * handle for the submodule and lookup both the left and right commits and
+ * put them into the left and right pointers.
+ */
+static void show_submodule_header(struct diff_options *o,
+		const char *path,
 		struct object_id *one, struct object_id *two,
 		unsigned dirty_submodule,
+		struct repository *sub,
 		struct commit **left, struct commit **right,
 		struct commit_list **merge_bases)
 {
@@ -507,7 +540,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	else if (is_null_oid(two))
 		message = "(submodule deleted)";
 
-	if (add_submodule_odb(path)) {
+	if (!sub) {
 		if (!message)
 			message = "(commits not present)";
 		goto output_header;
@@ -517,8 +550,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	 * Attempt to lookup the commit references, and determine if this is
 	 * a fast forward or fast backwards update.
 	 */
-	*left = lookup_commit_reference(the_repository, one);
-	*right = lookup_commit_reference(the_repository, two);
+	*left = lookup_commit_reference(sub, one);
+	*right = lookup_commit_reference(sub, two);
 
 	/*
 	 * Warn about missing commits in the submodule project, but only if
@@ -528,7 +561,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	     (!is_null_oid(two) && !*right))
 		message = "(commits not present)";
 
-	*merge_bases = get_merge_bases(*left, *right);
+	*merge_bases = repo_get_merge_bases(sub, *left, *right);
 	if (*merge_bases) {
 		if ((*merge_bases)->item == *left)
 			fast_forward = 1;
@@ -562,16 +595,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 	struct rev_info rev;
 	struct commit *left = NULL, *right = NULL;
 	struct commit_list *merge_bases = NULL;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/*
 	 * If we don't have both a left and a right pointer, there is no
 	 * reason to try and display a summary. The header line should contain
 	 * all the information the user needs.
 	 */
-	if (!left || !right)
+	if (!left || !right || !sub)
 		goto out;
 
 	/* Treat revision walker failure the same as missing commits */
@@ -580,13 +615,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 		goto out;
 	}
 
-	print_submodule_summary(&rev, o);
+	print_submodule_summary(sub, &rev, o);
 
 out:
 	if (merge_bases)
 		free_commit_list(merge_bases);
 	clear_commit_marks(left, ~0);
 	clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 void show_submodule_inline_diff(struct diff_options *o, const char *path,
@@ -598,9 +637,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 	struct commit_list *merge_bases = NULL;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strbuf sb = STRBUF_INIT;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/* We need a valid left and right commit to display a difference */
 	if (!(left || is_null_oid(one)) ||
@@ -661,6 +702,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 		clear_commit_marks(left, ~0);
 	if (right)
 		clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 int should_update_submodules(void)
-- 
2.20.0.405.gbc1bbc6f85-goog


^ permalink raw reply related	[relevance 20%]

* [PATCH 00/23] sb/more-repo-in-api
@ 2018-12-15  0:09  7% Stefan Beller
  2018-12-15  0:09 20% ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Stefan Beller @ 2018-12-15  0:09 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

I realized next has not been rewound, so I can resend sb/more-repo-in-api,
which I hereby do. The changes are minimal and address the only comment
by Jonathan so far.

Thanks,
Stefan

Stefan Beller (23):
  sha1_file: allow read_object to read objects in arbitrary repositories
  packfile: allow has_packed_and_bad to handle arbitrary repositories
  object-store: allow read_object_file_extended to read from any repo
  object-store: prepare read_object_file to deal with any repo
  object-store: prepare has_{sha1, object}_file to handle any repo
  object: parse_object to honor its repository argument
  commit: allow parse_commit* to handle any repo
  commit-reach.c: allow paint_down_to_common to handle any repo
  commit-reach.c: allow merge_bases_many to handle any repo
  commit-reach.c: allow remove_redundant to handle any repo
  commit-reach.c: allow get_merge_bases_many_0 to handle any repo
  commit-reach: prepare get_merge_bases to handle any repo
  commit-reach: prepare in_merge_bases[_many] to handle any repo
  commit: prepare get_commit_buffer to handle any repo
  commit: prepare repo_unuse_commit_buffer to handle any repo
  commit: prepare logmsg_reencode to handle arbitrary repositories
  pretty: prepare format_commit_message to handle arbitrary repositories
  submodule: use submodule repos for object lookup
  submodule: don't add submodule as odb for push
  commit-graph: convert remaining functions to handle any repo
  commit: prepare free_commit_buffer and release_commit_memory for any
    repo
  path.h: make REPO_GIT_PATH_FUNC repository agnostic
  t/helper/test-repository: celebrate independence from the_repository

 builtin/fsck.c                                |   3 +-
 builtin/log.c                                 |   6 +-
 builtin/rev-list.c                            |   3 +-
 cache.h                                       |   2 +
 commit-graph.c                                |  40 +++--
 commit-reach.c                                |  73 +++++----
 commit-reach.h                                |  38 +++--
 commit.c                                      |  41 ++---
 commit.h                                      |  43 +++++-
 .../coccinelle/the_repository.pending.cocci   | 144 ++++++++++++++++++
 object-store.h                                |  35 ++++-
 object.c                                      |   8 +-
 packfile.c                                    |   5 +-
 packfile.h                                    |   2 +-
 path.h                                        |   2 +-
 pretty.c                                      |  28 ++--
 pretty.h                                      |   7 +-
 sha1-file.c                                   |  34 +++--
 streaming.c                                   |   2 +-
 submodule.c                                   |  78 +++++++---
 t/helper/test-repository.c                    |  10 ++
 21 files changed, 454 insertions(+), 150 deletions(-)
 create mode 100644 contrib/coccinelle/the_repository.pending.cocci

 git range-diff origin/sb/more-repo-in-api... >>0000-cover-letter.patch
 
1:  99017ffac8 ! 1:  f24b120287 submodule: use submodule repos for object lookup
    @@ -40,12 +40,13 @@
     - * attempt to lookup both the left and right commits and put them into the
     - * left and right pointers.
     +/*
    -+ * Initialize 'out' based on the provided submodule path.
    ++ * Initialize a repository struct for a submodule based on the provided 'path'.
     + *
     + * Unlike repo_submodule_init, this tolerates submodules not present
     + * in .gitmodules. This function exists only to preserve historical behavior,
     + *
    -+ * Returns 0 on success, -1 when the submodule is not present.
    ++ * Returns the repository struct on success,
    ++ * NULL when the submodule is not present.
       */
     -static void show_submodule_header(struct diff_options *o, const char *path,
     +static struct repository *open_submodule(const char *path)
    @@ -59,6 +60,7 @@
     +		return NULL;
     +	}
     +
    ++	/* Mark it as a submodule */
     +	out->submodule_prefix = xstrdup(path);
     +
     +	strbuf_release(&sb);
2:  809765861c = 2:  25190d6174 submodule: don't add submodule as odb for push
3:  4a7735da72 = 3:  965421aab2 commit-graph: convert remaining functions to handle any repo
4:  aeeb1ba49e = 4:  bf31f32723 commit: prepare free_commit_buffer and release_commit_memory for any repo
5:  5ffebe9463 = 5:  c4e54e6b0d path.h: make REPO_GIT_PATH_FUNC repository agnostic
6:  9c89920c46 = 6:  a7ed0c57ba t/helper/test-repository: celebrate independence from the_repository

^ permalink raw reply	[relevance 7%]

* [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree
  2018-12-14 23:59  9%   ` [PATCH 0/4] submodules: unset core.worktree when no working tree present Stefan Beller
  2018-12-14 23:59 25%     ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
  2018-12-14 23:59 18%     ` [PATCH 2/4] submodule: unset core.worktree if no working tree is present Stefan Beller
@ 2018-12-14 23:59 19%     ` Stefan Beller
  2018-12-14 23:59 23%     ` [PATCH 4/4] submodule deinit: unset core.worktree Stefan Beller
  3 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-14 23:59 UTC (permalink / raw)
  To: gitster; +Cc: git, sbeller

74d4731da1 (submodule--helper: replace connect-gitdir-workingtree by
ensure-core-worktree, 2018-08-13) missed to update the BUG message.
Fix it.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index d38113a31a..31ac30cf2f 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2045,7 +2045,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
 	struct repository subrepo;
 
 	if (argc != 2)
-		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
+		BUG("submodule--helper ensure-core-worktree <path>");
 
 	path = argv[1];
 
-- 
2.20.0.405.gbc1bbc6f85-goog


^ permalink raw reply related	[relevance 19%]

* [PATCH 4/4] submodule deinit: unset core.worktree
  2018-12-14 23:59  9%   ` [PATCH 0/4] submodules: unset core.worktree when no working tree present Stefan Beller
                       ` (2 preceding siblings ...)
  2018-12-14 23:59 19%     ` [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree Stefan Beller
@ 2018-12-14 23:59 23%     ` Stefan Beller
  3 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-14 23:59 UTC (permalink / raw)
  To: gitster; +Cc: git, sbeller

When a submodule is deinit'd, the working tree is gone, so the setting of
core.worktree is bogus. Unset it. As we covered the only other case in
which a submodule loses its working tree in the earlier step
(i.e. switching branches of top-level project to move to a commit that did
not have the submodule), this makes the code always maintain
core.worktree correctly unset when there is no working tree
for a submodule.

This re-introduces 984cd77ddb (submodule deinit: unset core.worktree,
2018-06-18), which was reverted as part of f178c13fda (Revert "Merge
branch 'sb/submodule-core-worktree'", 2018-09-07)

The whole series was reverted as the offending commit e98317508c
(submodule: ensure core.worktree is set after update, 2018-06-18)
was relied on by other commits such as 984cd77ddb.

Keep the offending commit reverted, but its functionality came back via
4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17), such
that we can reintroduce 984cd77ddb now.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 2 ++
 t/lib-submodule-update.sh   | 2 +-
 t/t7400-submodule-basic.sh  | 5 +++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 31ac30cf2f..672b74db89 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1131,6 +1131,8 @@ static void deinit_submodule(const char *path, const char *prefix,
 		if (!(flags & OPT_QUIET))
 			printf(format, displaypath);
 
+		submodule_unset_core_worktree(sub);
+
 		strbuf_release(&sb_rm);
 	}
 
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 51d4555549..5b56b23166 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -235,7 +235,7 @@ reset_work_tree_to_interested () {
 	then
 		mkdir -p submodule_update/.git/modules/sub1/modules &&
 		cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2
-		GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree
+		# core.worktree is unset for sub2 as it is not checked out
 	fi &&
 	# indicate we are interested in the submodule:
 	git -C submodule_update config submodule.sub1.url "bogus" &&
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 76a7cb0af7..aba2d4d6ee 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -984,6 +984,11 @@ test_expect_success 'submodule deinit should remove the whole submodule section
 	rmdir init
 '
 
+test_expect_success 'submodule deinit should unset core.worktree' '
+	test_path_is_file .git/modules/example/config &&
+	test_must_fail git config -f .git/modules/example/config core.worktree
+'
+
 test_expect_success 'submodule deinit from subdirectory' '
 	git submodule update --init &&
 	git config submodule.example.foo bar &&
-- 
2.20.0.405.gbc1bbc6f85-goog


^ permalink raw reply related	[relevance 23%]

* [PATCH 2/4] submodule: unset core.worktree if no working tree is present
  2018-12-14 23:59  9%   ` [PATCH 0/4] submodules: unset core.worktree when no working tree present Stefan Beller
  2018-12-14 23:59 25%     ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
@ 2018-12-14 23:59 18%     ` Stefan Beller
  2018-12-26 18:27  4%       ` Junio C Hamano
  2018-12-14 23:59 19%     ` [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree Stefan Beller
  2018-12-14 23:59 23%     ` [PATCH 4/4] submodule deinit: unset core.worktree Stefan Beller
  3 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-14 23:59 UTC (permalink / raw)
  To: gitster; +Cc: git, sbeller

When a submodules work tree is removed, we should unset its core.worktree
setting as the worktree is no longer present. This is not just in line
with the conceptual view of submodules, but it fixes an inconvenience
for looking at submodules that are not checked out:

    git clone --recurse-submodules git://github.com/git/git && cd git &&
    git checkout --recurse-submodules v2.13.0
    git -C .git/modules/sha1collisiondetection log
    fatal: cannot chdir to '../../../sha1collisiondetection': \
        No such file or directory

With this patch applied, the final call to git log works instead of dying
in its setup, as the checkout will unset the core.worktree setting such
that following log will be run in a bare repository.

This patch covers all commands that are in the unpack machinery, i.e.
checkout, read-tree, reset. A follow up patch will address
"git submodule deinit", which will also make use of the new function
submodule_unset_core_worktree(), which is why we expose it in this patch.

This patch was authored as 4fa4f90ccd (submodule: unset core.worktree if
no working tree is present, 2018-06-12), which was reverted as part of
f178c13fda (Revert "Merge branch 'sb/submodule-core-worktree'",
2018-09-07). The revert was needed as the nearby commit e98317508c
(submodule: ensure core.worktree is set after update, 2018-06-18) is
faulty and at the time of 7e25437d35 (Merge branch
'sb/submodule-core-worktree', 2018-07-18) we could not revert the faulty
commit only, as they were depending on each other: If core.worktree is
unset, we have to have ways to ensure that it is set again once
the working tree reappears again.

Now that 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17),
specifically 74d4731da1 (submodule--helper: replace
connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13) is
present, we already check and ensure core.worktree is set when
populating a new work tree, such that we can re-introduce the commits
that unset core.worktree when removing the worktree.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c               | 14 ++++++++++++++
 submodule.h               |  2 ++
 t/lib-submodule-update.sh |  3 ++-
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/submodule.c b/submodule.c
index 6415cc5580..d393e947e6 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1561,6 +1561,18 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
 	return ret;
 }
 
+void submodule_unset_core_worktree(const struct submodule *sub)
+{
+	char *config_path = xstrfmt("%s/modules/%s/config",
+				    get_git_common_dir(), sub->name);
+
+	if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
+		warning(_("Could not unset core.worktree setting in submodule '%s'"),
+			  sub->path);
+
+	free(config_path);
+}
+
 static const char *get_super_prefix_or_empty(void)
 {
 	const char *s = get_super_prefix();
@@ -1726,6 +1738,8 @@ int submodule_move_head(const char *path,
 
 			if (is_empty_dir(path))
 				rmdir_or_warn(path);
+
+			submodule_unset_core_worktree(sub);
 		}
 	}
 out:
diff --git a/submodule.h b/submodule.h
index a680214c01..9e18e9b807 100644
--- a/submodule.h
+++ b/submodule.h
@@ -131,6 +131,8 @@ int submodule_move_head(const char *path,
 			const char *new_head,
 			unsigned flags);
 
+void submodule_unset_core_worktree(const struct submodule *sub);
+
 /*
  * Prepare the "env_array" parameter of a "struct child_process" for executing
  * a submodule by clearing any repo-specific environment variables, but
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 016391723c..51d4555549 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() {
 			git branch -t remove_sub1 origin/remove_sub1 &&
 			$command remove_sub1 &&
 			test_superproject_content origin/remove_sub1 &&
-			! test -e sub1
+			! test -e sub1 &&
+			test_must_fail git config -f .git/modules/sub1/config core.worktree
 		)
 	'
 	# ... absorbing a .git directory along the way.
-- 
2.20.0.405.gbc1bbc6f85-goog


^ permalink raw reply related	[relevance 18%]

* [PATCH 1/4] submodule update: add regression test with old style setups
  2018-12-14 23:59  9%   ` [PATCH 0/4] submodules: unset core.worktree when no working tree present Stefan Beller
@ 2018-12-14 23:59 25%     ` Stefan Beller
  2018-12-26 18:21  4%       ` Junio C Hamano
  2018-12-14 23:59 18%     ` [PATCH 2/4] submodule: unset core.worktree if no working tree is present Stefan Beller
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-14 23:59 UTC (permalink / raw)
  To: gitster; +Cc: git, sbeller

As f178c13fda (Revert "Merge branch 'sb/submodule-core-worktree'",
2018-09-07) was produced shortly before a release, nobody asked for
a regression test to be included. Add a regression test that makes sure
that the invocation of `git submodule update` on old setups doesn't
produce errors as pointed out in f178c13fda.

The place to add such a regression test may look odd in t7412, but
that is the best place as there we setup old style submodule setups
explicitly.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 t/t7412-submodule-absorbgitdirs.sh | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
index ce74c12da2..1cfa150768 100755
--- a/t/t7412-submodule-absorbgitdirs.sh
+++ b/t/t7412-submodule-absorbgitdirs.sh
@@ -75,7 +75,12 @@ test_expect_success 're-setup nested submodule' '
 	GIT_WORK_TREE=../../../nested git -C sub1/.git/modules/nested config \
 		core.worktree "../../../nested" &&
 	# make sure this re-setup is correct
-	git status --ignore-submodules=none
+	git status --ignore-submodules=none &&
+
+	# also make sure this old setup does not regress
+	git submodule update --init --recursive >out 2>err &&
+	test_must_be_empty out &&
+	test_must_be_empty err
 '
 
 test_expect_success 'absorb the git dir in a nested submodule' '
-- 
2.20.0.405.gbc1bbc6f85-goog


^ permalink raw reply related	[relevance 25%]

* [PATCH 0/4] submodules: unset core.worktree when no working tree present
  2018-12-08  5:57  2% ` [PATCH 0/4] Junio C Hamano
  2018-12-12 22:35  4%   ` Stefan Beller
@ 2018-12-14 23:59  9%   ` Stefan Beller
  2018-12-14 23:59 25%     ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
                       ` (3 more replies)
  1 sibling, 4 replies; 200+ results
From: Stefan Beller @ 2018-12-14 23:59 UTC (permalink / raw)
  To: gitster; +Cc: git, sbeller

v2:
I reworded the commit messages to explain the patches from the ground up
instead of only linking to the old commits, that got reverted.

> Just pretend that the ealier commits and their reversion never
> happened, and further pretend that we are doing the best thing that
> should happen to our codebase.

I disagree with that first stance (I can freely admit those commits happened),
but agree on the second point, so I explained why the code is the best
for the code base now. So I kept those pointers in there, too, to make it
easier for future code archeologists. 

v1:

A couple days before the 2.19 release we had a bug report about
broken submodules[1] and reverted[2] the commits leading up to them.

The behavior of said bug fixed itself by taking a different approach[3],
specifically by a weaker enforcement of having `core.worktree` set in a
submodule [4].

The revert [2] was overly broad as we neared the release, such that we wanted
to rather keep the known buggy behavior of always having `core.worktree` set,
rather than figuring out how to fix the new bug of having 'git submodule update'
not working in old style repository setups.

This series re-introduces those reverted patches, with no changes in code,
but with drastically changed commit messages, as those focus on why it is safe
to re-introduce them instead of explaining the desire for the change.

[1] https://public-inbox.org/git/2659750.rG6xLiZASK@twilight
[2] f178c13fda (Revert "Merge branch 'sb/submodule-core-worktree'", 2018-09-07)
[3] 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17)
[4] 74d4731da1 (submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13)
Stefan Beller (4):
  submodule update: add regression test with old style setups
  submodule: unset core.worktree if no working tree is present
  submodule--helper: fix BUG message in ensure_core_worktree
  submodule deinit: unset core.worktree

 builtin/submodule--helper.c        |  4 +++-
 submodule.c                        | 14 ++++++++++++++
 submodule.h                        |  2 ++
 t/lib-submodule-update.sh          |  5 +++--
 t/t7400-submodule-basic.sh         |  5 +++++
 t/t7412-submodule-absorbgitdirs.sh |  7 ++++++-
 6 files changed, 33 insertions(+), 4 deletions(-)

-- 
2.20.0.405.gbc1bbc6f85-goog


^ permalink raw reply	[relevance 9%]

* Re: [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact
  2018-12-13 23:58  7%                             ` Stefan Beller
@ 2018-12-14  4:22  7%                               ` Yaroslav O Halchenko
  0 siblings, 0 replies; 200+ results
From: Yaroslav O Halchenko @ 2018-12-14  4:22 UTC (permalink / raw)
  To: git


On Thu, 13 Dec 2018, Stefan Beller wrote:

> > cool, thanks for the feedback - I will then try to make it happen

> > quick one (so when I get to it I know):  should I replicate all those
> > tests you have for other update strategies? (treating of config
> > specifications etc)

> If there is a sensible way to do so?
> I have the impression that there are enough differences, that it
> may not be possible to replicate all tests meaningfully from the
> other modes.

oh, by replicate I just meant to copy/paste and adjust for expected for
--reset-hard test behavior (and possibly introduced helper),
nothing fancy, just duplication as for replication ;-) 

> > There is no easy way to parametrize them somehow?

> There is t/lib-submodule-update.sh, which brings this to
> an extreme, as it makes a "test suite in a test suite"; and I would
> not follow that example for this change.

ok

> > ;)    In Python world I might have mocked the actual underlying call to
> > update, to see what option it would be getting and assure that it is the
> > one I specified via config, and then sweepped through all of them
> > to make sure nothing interim changes it.  Just wondering if may be
> > something like that exists in git's tests support.

> gits tests are very heavy on end to end testing, i.e. run a whole command
> and observe its output. This makes our command setup code, (i.e. finding
> the repository, parsing options, reading possible config, etc) a really well
> exercised code path. ;-)

> There is a recent push towards testing only units, most of
> t/helper is used for that, e.g. c.f. 4c7bb45269 (test-reach:
> test get_reachable_subset, 2018-11-02).

> So if you have a good idea how to focus the submodule
> tests more on the (new) unit that you add, that would be cool.

no, not really any good ideas -- I am new here, but I will keep an eye open.

> > BTW - sorry if RTFM and unrelated, is there  a way to

> >     update --merge

> > but allowing only  fast-forwards?  My use case is collection of this
> > submodules: http://datasets.datalad.org/?dir=/openneuro  which all
> > should come from github and I should not have any changes of my own.

> So you want the merge option  --ff-only
> to be passed to the submodule merge command. I guess you could make
> a patch, that update takes another option (--ff-only, only useful when
> --merge is given), which is then propagated.

> I am not sure if we could have a more generalized option passing,
> which would allow to pass any option (for its respective command)
> to the command that is run in the update mode.

wouldn't it be (theoretically) possible, in principle, to pass
them via some config variable?  e.g. instead of  

submodule update --reset-hard

have

-c submodule.update.reset.opts=--hard update --reset

and then analogously

-c submodule.update.merge.opts=--ff-only update --merge

(--ff-only I guess would make no sense for any "supermodule" - a repo
with submodules)

> > Sure thing if all is clean etc, merge should result in fast-forward.  I
> > just do not want to miss a case where there was some (temporary?) "dirt"
> > which I forgot to reset and it would then get merged etc.

> maybe use --rebase, such that your potential change would bubble
> up and possibly produce a merge conflict?

that is a good idea as a workaround, thanks!

-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] submodule update: run at most one fetch job unless otherwise set
  2018-12-13 19:02 19%     ` [PATCH] submodule update: run at most one fetch job unless otherwise set Stefan Beller
  2018-12-13 19:04  4%       ` Eric Sunshine
@ 2018-12-14  2:53  7%       ` Junio C Hamano
  1 sibling, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-14  2:53 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, sjon

Stefan Beller <sbeller@google.com> writes:

> From: Junio C Hamano <gitster@pobox.com>
>
> In a028a1930c (fetching submodules: respect `submodule.fetchJobs`
> config option, 2016-02-29), we made sure to keep the default behavior
> of a fetching at most one submodule at once when not setting the
> newly introduced `submodule.fetchJobs` config.
>
> This regressed in 90efe595c5 (builtin/submodule--helper: factor
> out submodule updating, 2018-08-03). Fix it.
>
> Reported-by: Sjon Hortensius <sjon@parse.nl>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---

Thanks for tying the loose ends.

We may want to convert the _INIT macro to use the designated
initializers; I had to count the fields twice to make sure I was
tweaking the right one.  

It did not help that I saw, before looking at the current code, that
90efe595c5 added one field at the end to the struct but did not
touch _INIT macro at all.  That made me guess that max_jobs=0 was
due to _missing_ initialization value, leading me to an incorrect
fix to append an extra 1 at the end, but that was bogus.  The
missing initialization left by 90efe595 ("builtin/submodule--helper:
factor out submodule updating", 2018-08-03) was silently fixed by
f1d15713 ("builtin/submodule--helper: store update_clone information
in a struct", 2018-08-03), I think, so replacing the 0 at the end is
1 happens to be the right fix, but with designated initializers, all
these confusions are more easily avoided.


>  builtin/submodule--helper.c | 2 +-
>  t/t5526-fetch-submodules.sh | 2 ++
>  2 files changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index d38113a31a..1f8a4a9d52 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -1551,7 +1551,7 @@ struct submodule_update_clone {
>  #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
>  	SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
>  	NULL, NULL, NULL, \
> -	NULL, 0, 0, 0, NULL, 0, 0, 0}
> +	NULL, 0, 0, 0, NULL, 0, 0, 1}
>  
>  
>  static void next_submodule_warn_missing(struct submodule_update_clone *suc,
> diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
> index 6c2f9b2ba2..a0317556c6 100755
> --- a/t/t5526-fetch-submodules.sh
> +++ b/t/t5526-fetch-submodules.sh
> @@ -524,6 +524,8 @@ test_expect_success 'fetching submodules respects parallel settings' '
>  	git config fetch.recurseSubmodules true &&
>  	(
>  		cd downstream &&
> +		GIT_TRACE=$(pwd)/trace.out git fetch &&
> +		grep "1 tasks" trace.out &&
>  		GIT_TRACE=$(pwd)/trace.out git fetch --jobs 7 &&
>  		grep "7 tasks" trace.out &&
>  		git config submodule.fetchJobs 8 &&

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact
  2018-12-13 22:43  6%                           ` Yaroslav O Halchenko
@ 2018-12-13 23:58  7%                             ` Stefan Beller
  2018-12-14  4:22  7%                               ` Yaroslav O Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-13 23:58 UTC (permalink / raw)
  To: debian; +Cc: git

On Thu, Dec 13, 2018 at 2:44 PM Yaroslav O Halchenko
<debian@onerussian.com> wrote:
>
>
> On Thu, 13 Dec 2018, Stefan Beller wrote:
>
> > > and kaboom -- we have a new test.  If we decide to test more -- just tune up
> > > test_expect_unchanged_submodule_status and done -- all the tests remain
> > > sufficiently prescribed.
>
> > > What do you think?
>
> > That is pretty cool. Maybe my gut reaction on the previous patch
> > also had to do with the numbers, i.e. having 2 extra function for
> > only having 2 tests more legible. A framework is definitely better
> > once we have more tests.
>
> cool, thanks for the feedback - I will then try to make it happen
>
> quick one (so when I get to it I know):  should I replicate all those
> tests you have for other update strategies? (treating of config
> specifications etc)

If there is a sensible way to do so?
I have the impression that there are enough differences, that it
may not be possible to replicate all tests meaningfully from the
other modes.

> There is no easy way to parametrize them somehow?

There is t/lib-submodule-update.sh, which brings this to
an extreme, as it makes a "test suite in a test suite"; and I would
not follow that example for this change.

> ;)    In Python world I might have mocked the actual underlying call to
> update, to see what option it would be getting and assure that it is the
> one I specified via config, and then sweepped through all of them
> to make sure nothing interim changes it.  Just wondering if may be
> something like that exists in git's tests support.

gits tests are very heavy on end to end testing, i.e. run a whole command
and observe its output. This makes our command setup code, (i.e. finding
the repository, parsing options, reading possible config, etc) a really well
exercised code path. ;-)

There is a recent push towards testing only units, most of
t/helper is used for that, e.g. c.f. 4c7bb45269 (test-reach:
test get_reachable_subset, 2018-11-02).

So if you have a good idea how to focus the submodule
tests more on the (new) unit that you add, that would be cool.

> BTW - sorry if RTFM and unrelated, is there  a way to
>
>     update --merge
>
> but allowing only  fast-forwards?  My use case is collection of this
> submodules: http://datasets.datalad.org/?dir=/openneuro  which all
> should come from github and I should not have any changes of my own.

So you want the merge option  --ff-only
to be passed to the submodule merge command. I guess you could make
a patch, that update takes another option (--ff-only, only useful when
--merge is given), which is then propagated.

I am not sure if we could have a more generalized option passing,
which would allow to pass any option (for its respective command)
to the command that is run in the update mode.

> Sure thing if all is clean etc, merge should result in fast-forward.  I
> just do not want to miss a case where there was some (temporary?) "dirt"
> which I forgot to reset and it would then get merged etc.

maybe use --rebase, such that your potential change would bubble
up and possibly produce a merge conflict?

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact
  2018-12-13 20:44  7%                         ` Stefan Beller
@ 2018-12-13 22:43  6%                           ` Yaroslav O Halchenko
  2018-12-13 23:58  7%                             ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Yaroslav O Halchenko @ 2018-12-13 22:43 UTC (permalink / raw)
  To: git


On Thu, 13 Dec 2018, Stefan Beller wrote:

> > and kaboom -- we have a new test.  If we decide to test more -- just tune up
> > test_expect_unchanged_submodule_status and done -- all the tests remain
> > sufficiently prescribed.

> > What do you think?

> That is pretty cool. Maybe my gut reaction on the previous patch
> also had to do with the numbers, i.e. having 2 extra function for
> only having 2 tests more legible. A framework is definitely better
> once we have more tests.

cool, thanks for the feedback - I will then try to make it happen

quick one (so when I get to it I know):  should I replicate all those
tests you have for other update strategies? (treating of config
specifications etc)  There is no easy way to parametrize them somehow?
;)    In Python world I might have mocked the actual underlying call to
update, to see what option it would be getting and assure that it is the
one I specified via config, and then sweepped through all of them
to make sure nothing interim changes it.  Just wondering if may be
something like that exists in git's tests support.


BTW - sorry if RTFM and unrelated, is there  a way to  

    update --merge  

but allowing only  fast-forwards?  My use case is collection of this
submodules: http://datasets.datalad.org/?dir=/openneuro  which all
should come from github and I should not have any changes of my own.
Sure thing if all is clean etc, merge should result in fast-forward.  I
just do not want to miss a case where there was some (temporary?) "dirt"
which I forgot to reset and it would then get merged etc.


-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 6%]

* Re: [wishlist] support of cloning recursively from non-bare submodule hierarchies?
  @ 2018-12-13 21:59  7% ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-13 21:59 UTC (permalink / raw)
  To: Yaroslav Halchenko; +Cc: git

On Thu, Dec 13, 2018 at 9:19 AM Yaroslav Halchenko <yoh@onerussian.com> wrote:
>
> Example - on http://datasets.datalad.org we have a few hundred datasets
> organized into a hierarchy as git submodules.  Each  git submodules carries its
> own .git/ directory so they are "self sufficient" and we could readily assess
> their sizes, and "cut the tree" at any level without looking for the
> supermodule somewhere high up in the tree.
>
> .gitmodules typically has relative paths for the url and path for the
> submodules there, the form which I think we chose because it used to work (I
> could be utterly wrong! but I think it was done in an informed fashion)
> for git clone --recursive:
>
>         $> curl http://datasets.datalad.org/labs/gobbini/famface/.gitmodules
>         [submodule "data"]
>                 path = data
>                 url = ./data
>
> and possibly outside:
>
>         $> curl http://datasets.datalad.org/labs/gobbini/famface/data/.gitmodules
>         [submodule "scripts/mridefacer"]
>                 path = scripts/mridefacer
>                 url = https://github.com/yarikoptic/mridefacer

So far so good.

> But unfortunately git doesn't even consider such (valid AFAIK) situation
> while cloning where url has to have .git suffix but repository is not bare and
> a relative "data" path (or "./data" url) is referring to the worktree.
>
>         $> git clone --recursive http://datasets.datalad.org/labs/gobbini/famface/.git
[..]
>         Submodule 'data' (http://datasets.datalad.org/labs/gobbini/famface/.git/data) registered for path 'data'

and here it goes wrong, and you would have expected to see
.../gobbini/famface/data, eliding the .git ?

I just checked and this did not work neither in v2.18.0 nor v2.0.0 of
Git, so it is
either a real old regression in submodules, or something else.
Is it possible that the clone worked once without the additional .git
in the superproject URL?

> on the server I use the "smart HTTP" git backend, but not sure if that is the one to blame, since
> I do not see in the logs any attempt to get the /data from not under .git/:

If we want to strip off "/.git" of urls to make submodules work,
we'd want to look at builtin/submodule--helper.c::compute_submodule_clone_url
that was recently introduced.

I wonder if we'd just want to cut off the "/.git" and assume the submodule
is there in the worktree. Or if we need to see if the submodule was
absorbed into .git/modules/<name> on the remote side. (But if the
submodule is checked out both would work)

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact
  2018-12-13 16:42  6%                       ` Yaroslav O Halchenko
@ 2018-12-13 20:44  7%                         ` Stefan Beller
  2018-12-13 22:43  6%                           ` Yaroslav O Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-13 20:44 UTC (permalink / raw)
  To: debian; +Cc: git

On Thu, Dec 13, 2018 at 8:42 AM Yaroslav O Halchenko
<debian@onerussian.com> wrote:
>
> Thank you Stefan for the review and please pardon my delay with the
> reply, and sorry it got a bit too long by the end ;)
>
> On Wed, 12 Dec 2018, Stefan Beller wrote:
> > Thanks for the patches. The first patch looks good to me!
>
> Great!
>
> > > [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact
>
> > The subject is a bit cryptic (specifically the first part before the
> > colon), maybe
>
> >   t7406: compare entire submodule status for --reset-hard mode
>
> > ?
>
>
> > > For submodule update --reset-hard the best test is comparison of the
> > > entire status as shown by submodule status --recursive.  Upon update
> > > --reset-hard we should get back to the original state, with all the
> > > branches being the same (no detached HEAD) and commits identical to
> > > original  (so no merges, new commits, etc).
>
> > "original state" can mean different things to different people. I'd think
> > we could be more precise:
>
> >    ... we should get to the state that the submodule is reset to the
> >     object id as the superprojects gitlink points at, irrespective of the
> >     submodule branch.
>
> ok, I will update the description.  But I wonder if there could be some
> short term to be used to describe the composite "git submodule status"
> and "git status" (refers to below ;)).
>
> > >  test_expect_success 'submodule update --merge staying on master' '
> > >         (cd super/submodule &&
> > > -         git reset --hard HEAD~1
> > > +        git reset --hard HEAD~1
>
> > unrelated white space change?
>
> I was tuning formatting to be uniform and I guess missed that this is in
> the other (not my) test.  I will revert that piece, thanks!

The tests in that file are not quite following the coding style that is
currently deemed the best. So if you want to clean that up
as a preparatory patch, feel welcome to do so. :-)
(c.f. t/t7400-submodule-basic.sh for good style, specifically
indentation by tabs and the cd <path> on its own line in
a subshell)
The latest style update I found is
80938c39e2 (pack-objects test: modernize style, 2018-10-30)
and submodule related test style
31158c7efc (t7410: update to new style, 2018-08-15)

So I was not opposed to have style changes, but to have
multiple unrelated things in one patch (feature work vs
cleanup).

> BTW -- should I just squash to PATCHes now?  I kept them separate primarily to
> show the use of those helpers:

That would make sense.

> compare_submodules_status  is already a compound action, so code would
> become quite more "loaded" if it is expanded, e.g. instead of
...
> it would become something like this I guess?
...
>          ! {git submodule status --recursive >actual &&

you could keep the status out of the negation.

>         test_i18ncmp expect actual;} &&
>          git submodule update --reset-hard submodule &&
>          {git submodule status --recursive >actual &&
>       test_i18ncmp expect actual;}
>         )
>
> IMHO a bit mouth full.  I was thinking also to extend compare_ with additional
> testing e.g. using "git status" since "git submodule status" does not care
> about untracked files etc.  For --reset-hard I would like to assure that it is
> not just some kind of a mixed reset leaving files behind.  That would make
> tests even more overloaded.

ok, that makes sense.

> On that point: Although I also like explicit calls at times, I also do
> like test fixtures as a concept to do more testing around the actual
> test-specific code block, thus minimizing boiler plate, which even if explicit
> makes code actually harder to grasp (at least to me).
>
> Since for the majority of the --reset-hard tests the fixture and test(s) are
> pretty much the same, actually ideally I would have liked to have
> something like this:
>
> test_expect_unchanged_submodule_status 'submodule update --reset-hard staying on master' \
>   super \
>   '(cd submodule && git reset --hard HEAD~1)' \
>   'git submodule update --reset-hard submodule'
>
> where I just pass
>   the path to work in,
>   the test setup function,
>   and the test action.
>
> The rest (initial cd, record, run setup, verify that there is a change, run
> action, verify there is no changes) is done by the
> test_expect_unchanged_submodule_status in a uniform way, absorbing all the
> boiler plate.  (I am not married to the name, could be more descriptive/generic
> may be)

The issue with submodules is that we're already deviating from the
'standard' git test suite at times (See the submodule test suite
lib-submodule-update.sh that is used via t1013, t2013 or t3906
and others).

I guess if we keep the test_expect_unchanged_submodule_status
as a file local function, it could be okay.

> Then we could breed a good number of tests with little to no boiler plate, with
> only relevant pieces and as extended as needed testing done by this
> test_expect_unchanged_submodule_status helper. e.g smth like
>
> test_expect_unchanged_submodule_status 'submodule update --reset-hard staying on master when I do a new commit' \
>   super \
>   '(cd submodule && git commit --allow-empty -m "new one"' \

In new tests we're a big fan of using -C, as that can save the
subshell, i.e. replace the whole line by

    git -C submodule commit --allow-empty -m "new one"'  &&


>   'git submodule update --reset-hard submodule'
>
> and kaboom -- we have a new test.  If we decide to test more -- just tune up
> test_expect_unchanged_submodule_status and done -- all the tests remain
> sufficiently prescribed.
>
> What do you think?

That is pretty cool. Maybe my gut reaction on the previous patch
also had to do with the numbers, i.e. having 2 extra function for
only having 2 tests more legible. A framework is definitely better
once we have more tests.

Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] submodule update: run at most one fetch job unless otherwise set
  2018-12-13 19:02 19%     ` [PATCH] submodule update: run at most one fetch job unless otherwise set Stefan Beller
@ 2018-12-13 19:04  4%       ` Eric Sunshine
  2018-12-14  2:53  7%       ` Junio C Hamano
  1 sibling, 0 replies; 200+ results
From: Eric Sunshine @ 2018-12-13 19:04 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Git List, Junio C Hamano, sjon

On Thu, Dec 13, 2018 at 2:03 PM Stefan Beller <sbeller@google.com> wrote:
> In a028a1930c (fetching submodules: respect `submodule.fetchJobs`
> config option, 2016-02-29), we made sure to keep the default behavior
> of a fetching at most one submodule at once when not setting the

s/of a/of/

> newly introduced `submodule.fetchJobs` config.
>
> This regressed in 90efe595c5 (builtin/submodule--helper: factor
> out submodule updating, 2018-08-03). Fix it.
>
> Reported-by: Sjon Hortensius <sjon@parse.nl>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>

^ permalink raw reply	[relevance 4%]

* [PATCH] submodule update: run at most one fetch job unless otherwise set
  2018-12-13 18:50  8%   ` Stefan Beller
@ 2018-12-13 19:02 19%     ` Stefan Beller
  2018-12-13 19:04  4%       ` Eric Sunshine
  2018-12-14  2:53  7%       ` Junio C Hamano
  0 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-12-13 19:02 UTC (permalink / raw)
  To: sbeller; +Cc: git, gitster, sjon

From: Junio C Hamano <gitster@pobox.com>

In a028a1930c (fetching submodules: respect `submodule.fetchJobs`
config option, 2016-02-29), we made sure to keep the default behavior
of a fetching at most one submodule at once when not setting the
newly introduced `submodule.fetchJobs` config.

This regressed in 90efe595c5 (builtin/submodule--helper: factor
out submodule updating, 2018-08-03). Fix it.

Reported-by: Sjon Hortensius <sjon@parse.nl>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 2 +-
 t/t5526-fetch-submodules.sh | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index d38113a31a..1f8a4a9d52 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1551,7 +1551,7 @@ struct submodule_update_clone {
 #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
 	SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
 	NULL, NULL, NULL, \
-	NULL, 0, 0, 0, NULL, 0, 0, 0}
+	NULL, 0, 0, 0, NULL, 0, 0, 1}
 
 
 static void next_submodule_warn_missing(struct submodule_update_clone *suc,
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 6c2f9b2ba2..a0317556c6 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -524,6 +524,8 @@ test_expect_success 'fetching submodules respects parallel settings' '
 	git config fetch.recurseSubmodules true &&
 	(
 		cd downstream &&
+		GIT_TRACE=$(pwd)/trace.out git fetch &&
+		grep "1 tasks" trace.out &&
 		GIT_TRACE=$(pwd)/trace.out git fetch --jobs 7 &&
 		grep "7 tasks" trace.out &&
 		git config submodule.fetchJobs 8 &&
-- 
2.20.0.rc2.230.gc28305e538


^ permalink raw reply related	[relevance 19%]

* Re: 2.20.0 - Undocumented change in submodule update wrt # parallel jobs
  @ 2018-12-13 18:50  8%   ` Stefan Beller
  2018-12-13 19:02 19%     ` [PATCH] submodule update: run at most one fetch job unless otherwise set Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-13 18:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, sjon

On Thu, Dec 13, 2018 at 6:17 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Sjon Hortensius <sjon@parse.nl> writes:
>
> > When switching to 2.20 our `git submodule update' (which clones
> > through ssh) broke because our ssh-server rejected the ~20
> > simultaneous connections the git-client makes. This seems to be caused
> > by a (possibly unintended) change in
> > https://github.com/git/git/commit/90efe595c53f4bb1851371344c35eff71f604d2b
> > which removed the default of max_jobs=1
> >
> > While this can easily be fixed by configuring submodule.fetchJobs I
> > think this change should be documented - or reverted back to it's
> > previous default of 1
>
> The commit in question does not look like it _wanted_ to change the
> default; rather, it appears to me that it wanted to be bug-to-bug
> compatible with the original, and any such change of behaviour is
> entirely unintended.

Indeed.

> I think the attached may be sufficient to change the default
> max_jobs back to 1.

I think so, too. I can wrap it into a commit with a proper message.

>
> By the way, is there a place where we document that the default
> value for fetchjobs, when unconfigured, is 1?

`man git config`

    submodule.fetchJobs
           Specifies how many submodules are fetched/cloned at the
           same time. A positive integer allows up to that number of
           submodules fetched in parallel. A value of 0 will give some
           reasonable default. If unset, it defaults to 1.

and that seems to be the only place, other places only reference
this place:

    Documentation$ git grep submodule.fetch
    config/submodule.txt:66:submodule.fetchJobs::
    git-clone.txt:259:      Defaults to the `submodule.fetchJobs` option.
    git-submodule.txt:408:  Defaults to the `submodule.fetchJobs` option.

The behavior of that seems to have been there since the beginning of
a028a1930c (fetching submodules: respect `submodule.fetchJobs`
config option, 2016-02-29)


> If we are not making
> such a concrete promise, then I would think it is OK to update the
> default without any fanfare, as long as we have good reasons to do
> so.  For this particular one, however, as I already said, I do not
> think we wanted to change the default to unlimited or anything like
> that, so...

We definitely want the diff below as a proper patch.

>  builtin/submodule--helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index 789d00d87d..e8cdf84f1c 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -1552,7 +1552,7 @@ struct submodule_update_clone {
>  #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
>         SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
>         NULL, NULL, NULL, \
> -       NULL, 0, 0, 0, NULL, 0, 0, 0}
> +       NULL, 0, 0, 0, NULL, 0, 0, 1}
>
>
>  static void next_submodule_warn_missing(struct submodule_update_clone *suc,

^ permalink raw reply	[relevance 8%]

* Re: [PATCH] Re: [wishlist] submodule.update config
  2018-12-12 19:31  7%         ` Stefan Beller
@ 2018-12-13 16:50  7%           ` Yaroslav Halchenko
  0 siblings, 0 replies; 200+ results
From: Yaroslav Halchenko @ 2018-12-13 16:50 UTC (permalink / raw)
  To: git


On Wed, 12 Dec 2018, Stefan Beller wrote:

> > But again, I must confess, that either I forgot or just do not see a
> > clear use-case/demand for submodule.update config myself any longer,

> ok, let's drop that patch then.

ok, But I will cherish it in my memory so whenever the use case
comes back to me -- I will be back too ;)

> > Probably I need to try "submodules update --merge" to see what is that
> > rough edge which makes it different from the potential "merge
> > --recurse-submodules", or is it easy to describe? ;-)

> I think the branch handling would be the difference. I'd expect
> "merge --recurse-submodules" to be sensible about staying on
> the branch both in the superproject and submodule, whereas
> "submodule update --merge" is too much plumbing, that we'd
> expect a sensible branch handling (detached HEAD is just fine,
> right?)

re "detached HEAD is just fine" -- I guess "it depends"...  E.g.  why
should it get detached if it was not detached to start with?  Why not
just to perform a regular "git merge --recurse-submodules" within
the submodule thus making it all consistent across?

If there is a need in detached HEADs handling of merges etc, get
them detached and then they would stay detached - no surprises.

> The merge result would be the same, I'd think.

it better be ;)

> > I wonder if may be instead of pestering you about this config one, I
> > should ask about pointers on how to accomplish "revert
> > --recurse-submodules"

> What do you want to do in revert --recurse-submodules?
> When you have "revert --recurse-submodules $COMMIT",
> would that revert all submodule commits introduced in
> that commit as well as the regular superproject revert?

That is correct

> This would require either opening multiple editors
> (once per submodule and at last for the superproject)
> or we'd have to do fancy snip-snapping of the user input,
> e.g. providing a template like:

>     Revert "$title"

>     This reverts commit $COMMIT.

>     # The above is for the superproject commit
>     # Please enter the commit message  ...

>     # Changes to be committed:
>     #       ...
>     # --8<-- DO NOT DELETE THIS LINE
>     # Below is the commit for submodule $submodule:
>     Revert $submodule_range

>     This reverts commits $maybe_many

>     # The above is for the submodule commit
>     # Please ...

> I guess it may be easier to just have multiple
> editors opened sequentially to give a commit
> message.

yeap - that would be beautiful.  Now I just need to do that all manually
;)

> >  or where to poke to make it possible to clone
> > recursively from  http://datasets.datalad.org/ where  we do not place
> > submodules all under the very top /.git/modules ;-)

> Not sure what you mean there?

sorry I was not clear... I will start a new thread for a complete
description.

-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact
  2018-12-12 19:48  7%                     ` Stefan Beller
@ 2018-12-13 16:42  6%                       ` Yaroslav O Halchenko
  2018-12-13 20:44  7%                         ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Yaroslav O Halchenko @ 2018-12-13 16:42 UTC (permalink / raw)
  To: git

Thank you Stefan for the review and please pardon my delay with the
reply, and sorry it got a bit too long by the end ;)

On Wed, 12 Dec 2018, Stefan Beller wrote:
> Thanks for the patches. The first patch looks good to me!

Great!

> > [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact

> The subject is a bit cryptic (specifically the first part before the
> colon), maybe

>   t7406: compare entire submodule status for --reset-hard mode

> ?


> > For submodule update --reset-hard the best test is comparison of the
> > entire status as shown by submodule status --recursive.  Upon update
> > --reset-hard we should get back to the original state, with all the
> > branches being the same (no detached HEAD) and commits identical to
> > original  (so no merges, new commits, etc).

> "original state" can mean different things to different people. I'd think
> we could be more precise:

>    ... we should get to the state that the submodule is reset to the
>     object id as the superprojects gitlink points at, irrespective of the
>     submodule branch.

ok, I will update the description.  But I wonder if there could be some
short term to be used to describe the composite "git submodule status"
and "git status" (refers to below ;)).

> >  test_expect_success 'submodule update --merge staying on master' '
> >         (cd super/submodule &&
> > -         git reset --hard HEAD~1
> > +        git reset --hard HEAD~1

> unrelated white space change?

I was tuning formatting to be uniform and I guess missed that this is in
the other (not my) test.  I will revert that piece, thanks!

BTW -- should I just squash to PATCHes now?  I kept them separate primarily to
show the use of those helpers:

> >         ) &&
> >         (cd super &&
> >          (cd submodule &&
> > @@ -307,16 +318,28 @@ test_expect_success 'submodule update --merge staying on master' '
> >  '

> >  test_expect_success 'submodule update --reset-hard staying on master' '
> > [..]
> > +'
> > +

> The tests look good to me, though I wonder if we'd rather want to inline
> {record/compare}_submodule_status as then you'd not need to look it up
> and the functions are rather short?

compare_submodules_status  is already a compound action, so code would
become quite more "loaded" if it is expanded, e.g. instead of 

	(cd super &&
	 record_submodules_status &&
	 (cd submodule &&
	  git reset --hard HEAD~1
	 ) &&
	 ! compare_submodules_status &&
	 git submodule update --reset-hard submodule &&
	 compare_submodules_status
	)

it would become something like this I guess?

	(cd super &&
	 git submodule status --recursive >expect &&
	 (cd submodule &&
	  git reset --hard HEAD~1
	 ) &&
	 ! {git submodule status --recursive >actual && 
        test_i18ncmp expect actual;} &&
	 git submodule update --reset-hard submodule &&
	 {git submodule status --recursive >actual && 
      test_i18ncmp expect actual;}
	)

IMHO a bit mouth full.  I was thinking also to extend compare_ with additional
testing e.g. using "git status" since "git submodule status" does not care
about untracked files etc.  For --reset-hard I would like to assure that it is
not just some kind of a mixed reset leaving files behind.  That would make
tests even more overloaded.

On that point: Although I also like explicit calls at times, I also do
like test fixtures as a concept to do more testing around the actual
test-specific code block, thus minimizing boiler plate, which even if explicit
makes code actually harder to grasp (at least to me).  

Since for the majority of the --reset-hard tests the fixture and test(s) are
pretty much the same, actually ideally I would have liked to have
something like this:

test_expect_unchanged_submodule_status 'submodule update --reset-hard staying on master' \
  super \
  '(cd submodule && git reset --hard HEAD~1)' \
  'git submodule update --reset-hard submodule'

where I just pass 
  the path to work in, 
  the test setup function, 
  and the test action.  

The rest (initial cd, record, run setup, verify that there is a change, run
action, verify there is no changes) is done by the
test_expect_unchanged_submodule_status in a uniform way, absorbing all the
boiler plate.  (I am not married to the name, could be more descriptive/generic
may be)

Then we could breed a good number of tests with little to no boiler plate, with
only relevant pieces and as extended as needed testing done by this
test_expect_unchanged_submodule_status helper. e.g smth like

test_expect_unchanged_submodule_status 'submodule update --reset-hard staying on master when I do a new commit' \
  super \
  '(cd submodule && git commit --allow-empty -m "new one"' \
  'git submodule update --reset-hard submodule'

and kaboom -- we have a new test.  If we decide to test more -- just tune up
test_expect_unchanged_submodule_status and done -- all the tests remain
sufficiently prescribed.

What do you think?
-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 6%]

* Re: [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree
  2018-12-12 22:46  4%     ` Stefan Beller
@ 2018-12-13  3:14  4%       ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-13  3:14 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

>> Unlike the step 2/4 I commented on, this does explain what this
>> wants to do and why, at least when looked from sideways.  Is the
>> above saying the same as the following two-liner?
>>
>>         An ealier mistake while rebasing to produce 74d4731da1
>>         failed to update this BUG message.  Fix this.
>
> I am not sure if it was rebasing, which was executed mistakenly.
> So maybe just saying "74d4731da1 contains a faulty BUG
> message. Fix it." would do.
>
> The intent of the longer message was to shed light in how I found
> the BUG (ie. I did not see the BUG message, which would ask me
> to actually fix a bug, but found it via code inspection), which I
> thought was valuable information, too.

I guess that it could be stated in a way to make it valuable, but in
the presented text, I somehow found it was making the more important
part of the description (i.e. "this patch fixes a mistake made by
74d4731da1") buried and harder to grok.

Thanks.

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree
  2018-12-08  6:55  4%   ` Junio C Hamano
@ 2018-12-12 22:46  4%     ` Stefan Beller
  2018-12-13  3:14  4%       ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-12 22:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

> Unlike the step 2/4 I commented on, this does explain what this
> wants to do and why, at least when looked from sideways.  Is the
> above saying the same as the following two-liner?
>
>         An ealier mistake while rebasing to produce 74d4731da1
>         failed to update this BUG message.  Fix this.

I am not sure if it was rebasing, which was executed mistakenly.
So maybe just saying "74d4731da1 contains a faulty BUG
message. Fix it." would do.

The intent of the longer message was to shed light in how I found
the BUG (ie. I did not see the BUG message, which would ask me
to actually fix a bug, but found it via code inspection), which I
thought was valuable information, too.

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 0/4]
  2018-12-08  5:57  2% ` [PATCH 0/4] Junio C Hamano
@ 2018-12-12 22:35  4%   ` Stefan Beller
  2018-12-14 23:59  9%   ` [PATCH 0/4] submodules: unset core.worktree when no working tree present Stefan Beller
  1 sibling, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-12 22:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Fri, Dec 7, 2018 at 9:57 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > A couple days before the 2.19 release we had a bug report about
> > broken submodules[1] and reverted[2] the commits leading up to them.
> >
> > The behavior of said bug fixed itself by taking a different approach[3],
> > specifically by a weaker enforcement of having `core.worktree` set in a
> > submodule [4].
> >
> > The revert [2] was overly broad as we neared the release, such that we wanted
> > to rather keep the known buggy behavior of always having `core.worktree` set,
> > rather than figuring out how to fix the new bug of having 'git submodule update'
> > not working in old style repository setups.
> >
> > This series re-introduces those reverted patches, with no changes in code,
> > but with drastically changed commit messages, as those focus on why it is safe
> > to re-introduce them instead of explaining the desire for the change.
>
> The above was a bit too cryptic for me to grok, so let me try
> rephrasing to see if I got them all correctly.
>
>  - three-patch series leading to 984cd77ddb were meant to fix some
>    bug, but the series itself was buggy and caused problems; we got
>    rid of them

yes.

>  - the problem 984cd77ddb wanted to fix was fixed differently

e98317508c02*

>    without reintroducing the problem three-patch series introduced.
>    That fix is already with us since 4d6d6ef1fc.

yes.

>  - now these three changes that were problematic in the past is
>    resent without any update (other than that it has one preparatory
>    patch to add tests).

One of the three changes was problematic, (e98317508c02),
the other two are good (in company of the third).

But those two were not good on their own, which is why we
reverted all three at once.

Now that we have a different approach for the third,
we could re-introduce the two.
(4fa4f90ccd8, 984cd77ddbf0)

We do that, but with precaution (an extra test);
additional careful reading found a typo, hence
we have "a third" patch, but that is totally different
than what above was referred to "one of three".


> Is that what is going on?  Obviously I am not getting "the other"
> benefit we wanted to gain out of these three patches (because the
> above description fails to explain what that is), other than to fix
> the issue that was fixed by 4d6d6ef1fc.

The other benefit refers to
7e25437d35 (Merge branch 'sb/submodule-core-worktree', 2018-07-18)
which was reverted as a whole.
It's goal was to handle core.worktree appropriately.

(Instead of having it there all the time, only have it when
a working tree is present)

> Sorry for being puzzled...

This means I need to revamp the commit messages and
cover letter altogether.

Stefan

^ permalink raw reply	[relevance 4%]

* [PATCH] submodule: correct documentation for open_submodule
  2018-12-12 20:22 24%       ` Stefan Beller
@ 2018-12-12 20:58 23%         ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-12 20:58 UTC (permalink / raw)
  To: sbeller; +Cc: git, gitster, jonathantanmy

When 99017ffac8 (submodule: use submodule repos for object lookup, 2018-11-13)
was merged, I had not yet addressed all outstanding review comments, such
as adapting the documentation for the function `open_submodule`, which
changed its signature during the development of that series.
Fix the documentation, and annotate setting of `submodule_prefix`
to indicate we're dealing with a submodule repository.

Signed-off-by: Stefan Beller <sbeller@google.com>
---

> I'll incorporate these changes once resending.

... only to realize it hit next already, so we'd prefer updates instead
of resending the whole series.

Maybe a patch like this?

 submodule.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/submodule.c b/submodule.c
index 262f03f118..4486ff664b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -483,12 +483,13 @@ void prepare_submodule_repo_env(struct argv_array *out)
 }
 
 /*
- * Initialize 'out' based on the provided submodule path.
+ * Initialize a repository struct for a submodule based on the provided 'path'.
  *
  * Unlike repo_submodule_init, this tolerates submodules not present
  * in .gitmodules. This function exists only to preserve historical behavior,
  *
- * Returns 0 on success, -1 when the submodule is not present.
+ * Returns the repository struct on success,
+ * NULL when the submodule is not present.
  */
 static struct repository *open_submodule(const char *path)
 {
@@ -501,6 +502,7 @@ static struct repository *open_submodule(const char *path)
 		return NULL;
 	}
 
+	/* Mark it as a submodule */
 	out->submodule_prefix = xstrdup(path);
 
 	strbuf_release(&sb);
-- 
2.20.0.rc2.230.gc28305e538


^ permalink raw reply related	[relevance 23%]

* Re: [PATCH 18/23] submodule: use submodule repos for object lookup
  2018-11-15 20:36  7%     ` Stefan Beller
@ 2018-12-12 20:22 24%       ` Stefan Beller
  2018-12-12 20:58 23%         ` [PATCH] submodule: correct documentation for open_submodule Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-12 20:22 UTC (permalink / raw)
  To: sbeller; +Cc: git, gitster, jonathantanmy

Signed-off-by: Stefan Beller <sbeller@google.com>
---

On Thu, Nov 15, 2018 at 11:54 AM Jonathan Tan <jonathantanmy@google.com> wrote:
> Other than that, this patch looks good.

I'll incorporate these changes once resending.

Stefan


 submodule.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/submodule.c b/submodule.c
index 262f03f118..4486ff664b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -483,12 +483,13 @@ void prepare_submodule_repo_env(struct argv_array *out)
 }
 
 /*
- * Initialize 'out' based on the provided submodule path.
+ * Initialize a repository struct for a submodule based on the provided 'path'.
  *
  * Unlike repo_submodule_init, this tolerates submodules not present
  * in .gitmodules. This function exists only to preserve historical behavior,
  *
- * Returns 0 on success, -1 when the submodule is not present.
+ * Returns the repository struct on success,
+ * NULL when the submodule is not present.
  */
 static struct repository *open_submodule(const char *path)
 {
@@ -501,6 +502,7 @@ static struct repository *open_submodule(const char *path)
 		return NULL;
 	}
 
+	/* Mark it as a submodule */
 	out->submodule_prefix = xstrdup(path);
 
 	strbuf_release(&sb);
-- 
2.20.0.rc2.230.gc28305e538


^ permalink raw reply related	[relevance 24%]

* Re: [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact
  @ 2018-12-12 19:48  7%                     ` Stefan Beller
  2018-12-13 16:42  6%                       ` Yaroslav O Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-12 19:48 UTC (permalink / raw)
  To: debian; +Cc: git

On Mon, Dec 10, 2018 at 8:09 PM Yaroslav Halchenko
<debian@onerussian.com> wrote:

Thanks for the patches. The first patch looks good to me!

> [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact

The subject is a bit cryptic (specifically the first part before the
colon), maybe

  t7406: compare entire submodule status for --reset-hard mode

?


> For submodule update --reset-hard the best test is comparison of the
> entire status as shown by submodule status --recursive.  Upon update
> --reset-hard we should get back to the original state, with all the
> branches being the same (no detached HEAD) and commits identical to
> original  (so no merges, new commits, etc).

"original state" can mean different things to different people. I'd think
we could be more precise:

   ... we should get to the state that the submodule is reset to the
    object id as the superprojects gitlink points at, irrespective of the
    submodule branch.


>  test_expect_success 'submodule update --merge staying on master' '
>         (cd super/submodule &&
> -         git reset --hard HEAD~1
> +        git reset --hard HEAD~1

unrelated white space change?

>         ) &&
>         (cd super &&
>          (cd submodule &&
> @@ -307,16 +318,28 @@ test_expect_success 'submodule update --merge staying on master' '
>  '
>
>  test_expect_success 'submodule update --reset-hard staying on master' '
> [..]
> +'
> +

The tests look good to me, though I wonder if we'd rather want to inline
{record/compare}_submodule_status as then you'd not need to look it up
and the functions are rather short?

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] Re: [wishlist] submodule.update config
  2018-12-11  5:10  7%       ` Yaroslav O Halchenko
@ 2018-12-12 19:31  7%         ` Stefan Beller
  2018-12-13 16:50  7%           ` Yaroslav Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-12 19:31 UTC (permalink / raw)
  To: Yaroslav Halchenko; +Cc: git

> But again, I must confess, that either I forgot or just do not see a
> clear use-case/demand for submodule.update config myself any longer,

ok, let's drop that patch then.

> Probably I need to try "submodules update --merge" to see what is that
> rough edge which makes it different from the potential "merge
> --recurse-submodules", or is it easy to describe? ;-)

I think the branch handling would be the difference. I'd expect
"merge --recurse-submodules" to be sensible about staying on
the branch both in the superproject and submodule, whereas
"submodule update --merge" is too much plumbing, that we'd
expect a sensible branch handling (detached HEAD is just fine,
right?)

The merge result would be the same, I'd think.

>
> I wonder if may be instead of pestering you about this config one, I
> should ask about pointers on how to accomplish "revert
> --recurse-submodules"

What do you want to do in revert --recurse-submodules?
When you have "revert --recurse-submodules $COMMIT",
would that revert all submodule commits introduced in
that commit as well as the regular superproject revert?

This would require either opening multiple editors
(once per submodule and at last for the superproject)
or we'd have to do fancy snip-snapping of the user input,
e.g. providing a template like:

    Revert "$title"

    This reverts commit $COMMIT.

    # The above is for the superproject commit
    # Please enter the commit message  ...
    #
    # Changes to be committed:
    #       ...
    # --8<-- DO NOT DELETE THIS LINE
    # Below is the commit for submodule $submodule:
    Revert $submodule_range

    This reverts commits $maybe_many

    # The above is for the submodule commit
    # Please ...

I guess it may be easier to just have multiple
editors opened sequentially to give a commit
message.

>  or where to poke to make it possible to clone
> recursively from  http://datasets.datalad.org/ where  we do not place
> submodules all under the very top /.git/modules ;-)

Not sure what you mean there?

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] Re: [wishlist] submodule.update config
  2018-12-11  0:08 23%     ` [PATCH] " Stefan Beller
@ 2018-12-11  5:10  7%       ` Yaroslav O Halchenko
  2018-12-12 19:31  7%         ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Yaroslav O Halchenko @ 2018-12-11  5:10 UTC (permalink / raw)
  To: git


On Mon, 10 Dec 2018, Stefan Beller wrote:

> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---

> > > So you are proposing a variable like submodule.update
> > [...]

> > Glad to hear that. Not sure though I would know where to stick my
> > nose to figure out what to change. ;-)

> The update_module is computed via the submodule--helpers
> update-module-mode command, which is a small wrapper
> around determine_submodule_update_strategy()
> which you already touched in the other patch that makes
> --reset-hard another mode.

> This contains code and tests, but we'd need some docs as well.
> I am not sure about this patch as it allows for easier experimentation
> with submodules (e.g. "git config submodule.update '!git reset --hard'"
> sounds like what you're trying to get)

;-) it was indeed one of the original approaches I considered instead of
having "update --reset-hard"...

> and using them, but as discussed
> below this might be too much convenience already and we'd rather want to
> have it properly integrated into the real commands.

indeed, having "update --reset-hard" provides necessary to me
convenience for my use cases.  Motivation behind  submodule.update  was
primarily to allow for heterogeneous (but still simple to define)
strategies, where for some subproject I could just define
submodule.update to be "reset-hard" (I do not expect my local commits
matter) and in the others -- "merge" (I carry my changes on top).

But again, I must confess, that either I forgot or just do not see a
clear use-case/demand for submodule.update config myself any longer,
besides providing a potentially useful default over
submodule.MODULE.update config.

> > Well, not sure... In the long run, if UX is to be tuned up, I wonder if
> > it would be more worthwhile to look toward making all those git commands
> > (git merge, git checkout, git rebase, ..., git revert, git cherry-pick)
> > support --recurse-submodules with a consistent with the non-recursive
> > operation by default behavior

> That is the end goal, very much.

> > (e.g.  not introducing detached HEADs or
> > controlling that via a set of additional options where needed).

> As with the discussion of the submodule.repoLike option (the patch I
> referenced in the other discussion), this is tricky to get the right
> behavior, so it takes some more time to do.

> Also what is right for a "git merge --recursive" might be totally different
> from a "git submodule update --merge" as the former is not centered around
> submodules but merging, such that a sensible default would be expected,
> whereas the "submodule update" is allowed to have a rough edge.

Probably I need to try "submodules update --merge" to see what is that
rough edge which makes it different from the potential "merge
--recurse-submodules", or is it easy to describe? ;-)

I wonder if may be instead of pestering you about this config one, I
should ask about pointers on how to accomplish "revert
--recurse-submodules" or where to poke to make it possible to clone
recursively from  http://datasets.datalad.org/ where  we do not place
submodules all under the very top /.git/modules ;-)

-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 7%]

* Re: What's cooking in git.git (Dec 2018, #01; Sun, 9)
  @ 2018-12-11  2:00  2% ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-11  2:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

> * sb/more-repo-in-api (2018-11-14) 23 commits
>   (merged to 'next' on 2018-11-19 at e5d2a129da)
> [..]
>  The in-core repository instances are passed through more codepaths.
>
>  Will cook in 'next'.
>  cf. <20181115221254.45373-1-jonathantanmy@google.com>

Looking into that.

> * sb/submodule-recursive-fetch-gets-the-tip (2018-12-09) 9 commits
> [..]
>  "git fetch --recurse-submodules" may not fetch the necessary commit
>  that is bound to the superproject, which is getting corrected.
>
>  Ready?

I saw you picked up the latest iteration of the last patch at
https://public-inbox.org/git/20181206212655.145586-1-sbeller@google.com/
which has received no review comments, yet, and you seem to have
just taken it for replacement without looking closely.

I think it is ready, but I seem to be an optimist at times
when it comes to my own code. :-)

^ permalink raw reply	[relevance 2%]

* [PATCH] Re: [wishlist] submodule.update config
  2018-12-10 22:49  7%   ` Yaroslav Halchenko
@ 2018-12-11  0:08 23%     ` Stefan Beller
  2018-12-11  5:10  7%       ` Yaroslav O Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-11  0:08 UTC (permalink / raw)
  To: yoh; +Cc: git, Stefan Beller

Signed-off-by: Stefan Beller <sbeller@google.com>
---

> > So you are proposing a variable like submodule.update
> [...]
>
> Glad to hear that. Not sure though I would know where to stick my
> nose to figure out what to change. ;-)

The update_module is computed via the submodule--helpers
update-module-mode command, which is a small wrapper
around determine_submodule_update_strategy()
which you already touched in the other patch that makes
--reset-hard another mode.

This contains code and tests, but we'd need some docs as well.
I am not sure about this patch as it allows for easier experimentation
with submodules (e.g. "git config submodule.update '!git reset --hard'"
sounds like what you're trying to get) and using them, but as discussed
below this might be too much convenience already and we'd rather want to
have it properly integrated into the real commands.

> Well, not sure... In the long run, if UX is to be tuned up, I wonder if
> it would be more worthwhile to look toward making all those git commands
> (git merge, git checkout, git rebase, ..., git revert, git cherry-pick)
> support --recurse-submodules with a consistent with the non-recursive
> operation by default behavior

That is the end goal, very much.

> (e.g.  not introducing detached HEADs or
> controlling that via a set of additional options where needed).

As with the discussion of the submodule.repoLike option (the patch I
referenced in the other discussion), this is tricky to get the right
behavior, so it takes some more time to do.

Also what is right for a "git merge --recursive" might be totally different
from a "git submodule update --merge" as the former is not centered around
submodules but merging, such that a sensible default would be expected,
whereas the "submodule update" is allowed to have a rough edge.

From what I get from this discussion is that the submodule.repoLike patch 
needs to offer different modes of submodule operation.

Currently the submodules are handled with the "detached HEAD, period" mode,
whereas that patch proposes a "follow the submodule branch, trust me they're
in sync with the superproject magically" mode, but what you'd rather want to
see is a "don't mess with submodules HEAD detachments, but still have
superproject powers come to be".

As soon as we have one of these modes in place, adding another one
"should be easy", famous last words.

Stefan

 builtin/submodule--helper.c |  4 ++++
 t/t7406-submodule-update.sh | 41 +++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index d38113a31a..e1aa3a9995 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1472,6 +1472,10 @@ static void determine_submodule_update_strategy(struct repository *r,
 		if (parse_submodule_update_strategy(val, out) < 0)
 			die(_("Invalid update mode '%s' configured for submodule path '%s'"),
 				val, path);
+	} else if (!repo_config_get_string_const(r, "submodule.update", &val)) {
+		if (parse_submodule_update_strategy(val, out) < 0)
+			die(_("Invalid update mode '%s' configured for 'submodule.update'"),
+				val);
 	} else if (sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
 		out->type = sub->update_strategy.type;
 		out->command = sub->update_strategy.command;
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index e87164aa8f..05880fd48f 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -322,6 +322,33 @@ test_expect_success 'submodule update - rebase in .git/config' '
 	)
 '
 
+test_expect_success 'submodule update - rebase in generic .git/config' '
+	git -C super config submodule.update rebase &&
+	git -C super/submodule reset --hard HEAD~1 &&
+	(cd super &&
+	 (cd submodule &&
+	  compare_head
+	 ) &&
+	 git submodule update submodule &&
+	 cd submodule &&
+	 compare_head
+	)
+'
+
+test_expect_success 'submodule.<name>.update overrides submodule.update' '
+	git -C super config submodule.update merge &&
+	git -C super config submodule.submodule.update rebase &&
+	git -C super/submodule reset --hard HEAD~1 &&
+	(cd super &&
+	 (cd submodule &&
+	  compare_head
+	 ) &&
+	 git submodule update submodule &&
+	 cd submodule &&
+	 compare_head
+	)
+'
+
 test_expect_success 'submodule update - checkout in .git/config but --rebase given' '
 	(cd super &&
 	 git config submodule.submodule.update checkout
@@ -339,6 +366,20 @@ test_expect_success 'submodule update - checkout in .git/config but --rebase giv
 	)
 '
 
+test_expect_success 'submodule update - checkout in submodule.update in .git/config but --rebase given' '
+	test_when_finished "git -C super config --unset submodule.update" &&
+	git -C super config submodule.update checkout &&
+	git -C super/submodule reset --hard HEAD~1 &&
+	(cd super &&
+	 (cd submodule &&
+	  compare_head
+	 ) &&
+	 git submodule update --rebase submodule &&
+	 cd submodule &&
+	 compare_head
+	)
+'
+
 test_expect_success 'submodule update - merge in .git/config' '
 	(cd super &&
 	 git config submodule.submodule.update merge
-- 
2.20.0.rc2.403.gdbc3b29805-goog


^ permalink raw reply related	[relevance 23%]

* Re: [wishlist] submodule.update config
  2018-12-10 20:40  8% ` Stefan Beller
@ 2018-12-10 22:49  7%   ` Yaroslav Halchenko
  2018-12-11  0:08 23%     ` [PATCH] " Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Yaroslav Halchenko @ 2018-12-10 22:49 UTC (permalink / raw)
  To: git


On Mon, 10 Dec 2018, Stefan Beller wrote:
> > I wondered, if you think it would be sensible to also add of
> > submodule.update which would be considered before submodule.SUBMODULE.update
> > variable possibly defined per submodule.  That would be more inline with desire
> > to use any of the --merge, --rebase (and hopefully soon --reset-hard)
> > strategies specified as an option for submodule update, where no per-submodule
> > handling  is happening.

> > Thanks in advance for the consideration!

> So you are proposing a variable like submodule.update
> without the .<name>. that would apply to any submodule?

yes

> The precedence in descending order of these
> configs that modify the behavior of "git submodule update"
> would be:

> * the command line flag (--merge/--rebase/--checkout)
> * submodule specific instructions (submodule.<name>.update)
> * generic submodule config (the new submodule.update)
> * default as --checkout

sound great

> I first hesitated in thinking this would be a good addition,
> as there is no plumbing command for submodules,
> to easily modify submodules irrespective of the user
> config. But that is out already with the submodule
> specific update configs.
> So I think it may be a good addition.

Glad to hear that. Not sure though I would know where to stick my
nose to figure out what to change. ;-)

> I wonder if we'd be better off to re-invent the UX instead
> of hiding your intentions in a config setting for a command
> that is already long to type. What about

>   git submodule merge
>   git submodule rebase
>   git submodule checkout
>   git submodule reset (--hard)

> as aliases for
>   git submodule update (...)

Well, not sure... In the long run, if UX is to be tuned up, I wonder if
it would be more worthwhile to look toward making all those git commands
(git merge, git checkout, git rebase, ..., git revert, git cherry-pick)
support --recurse-submodules with a consistent with the non-recursive
operation by default behavior (e.g.  not introducing detached HEADs or
controlling that via a set of additional options where needed).  I feel
that "git-submodule" ideally should not get its interface extended to
complement everything "git" commands can do, although that might need to
be extended to provide necessary plumbing.  As for the UX, it should
provide only the set of additional commands, which could not be present
in the main API (e.g. pure "git submodule" itself to list
submodules, and "submodule foreach", "init", "deinit").

-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 7%]

* Re: [wishlist] submodule.update config
  @ 2018-12-10 20:40  8% ` Stefan Beller
  2018-12-10 22:49  7%   ` Yaroslav Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-10 20:40 UTC (permalink / raw)
  To: Yaroslav Halchenko; +Cc: git

On Sat, Dec 8, 2018 at 7:45 AM Yaroslav Halchenko <yoh@onerussian.com> wrote:

> I wondered, if you think it would be sensible to also add of
> submodule.update which would be considered before submodule.SUBMODULE.update
> variable possibly defined per submodule.  That would be more inline with desire
> to use any of the --merge, --rebase (and hopefully soon --reset-hard)
> strategies specified as an option for submodule update, where no per-submodule
> handling  is happening.
>
> Thanks in advance for the consideration!

So you are proposing a variable like submodule.update
without the .<name>. that would apply to any submodule?

The precedence in descending order of these
configs that modify the behavior of "git submodule update"
would be:

* the command line flag (--merge/--rebase/--checkout)
* submodule specific instructions (submodule.<name>.update)
* generic submodule config (the new submodule.update)
* default as --checkout

I first hesitated in thinking this would be a good addition,
as there is no plumbing command for submodules,
to easily modify submodules irrespective of the user
config. But that is out already with the submodule
specific update configs.
So I think it may be a good addition.

I wonder if we'd be better off to re-invent the UX instead
of hiding your intentions in a config setting for a command
that is already long to type. What about

  git submodule merge
  git submodule rebase
  git submodule checkout
  git submodule reset (--hard)

as aliases for
  git submodule update (...)

^ permalink raw reply	[relevance 8%]

* Re: [wishlist] git submodule update --reset-hard
  2018-12-08  4:21 29%             ` Yaroslav Halchenko
@ 2018-12-10 18:58  6%               ` Stefan Beller
    0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-10 18:58 UTC (permalink / raw)
  To: Yaroslav Halchenko; +Cc: git

On Fri, Dec 7, 2018 at 8:21 PM Yaroslav Halchenko <yoh@onerussian.com> wrote:
>
>
> On Fri, 07 Dec 2018, Yaroslav Halchenko wrote:
>
>
> > On Fri, 07 Dec 2018, Stefan Beller wrote:
> > > > the initial "git submodule update --reset-hard" is pretty much a
> > > > crude workaround for some of those cases, so I would just go earlier in
> > > > the history, and redo some things, whenever I could just drop or revert
> > > > some selected set of commits.
>
> > > That makes sense.
> > > Do you want to give the implementation a try for the --reset-hard switch?
>
> > ok, will do, thanks for the blessing ;-)
>
> The patch is attached (please advise if should be done
> differently) and also submitted as PR
> https://github.com/git/git/pull/563

Yes, usually we send patches inline
(Random example:
https://public-inbox.org/git/244bdf2a6fc300f2b535ac8edfc2fbdaf5260266.1544465177.git.gitgitgadget@gmail.com/T/#u
compared to https://public-inbox.org/git/20181208042139.GA4827@hopa.kiewit.dartmouth.edu/
(which I am replying to))

See Documentation/SubmittingPatches.

There are some tools that provide a GithubPR -> emailPatch workflow at
https://github.com/gitgitgadget/git
I think if you'd open your pull request there, then it would be automatically
mailed to the list correctly.

I left some comments on the PR.

>
> I guess it would need more tests.

Writing tests is hard, as we don't know what we expect to break. ;-)

> Took me some time to figure out
> why I was getting
>
>         fatal: bad value for update parameter
>
> after all my changes to the git-submodule.sh script after looking at an
> example commit 42b491786260eb17d97ea9fb1c4b70075bca9523 which introduced
> --merge to the update ;-)

Yeah I saw you also updated the submodule related C code, was that
fatal message related to that?

Thanks,
Stefan

^ permalink raw reply	[relevance 6%]

* Git Test Coverage Report (Sunday, Dec 9)
@ 2018-12-09 18:04  2% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-12-09 18:04 UTC (permalink / raw)
  To: git@vger.kernel.org

Here is today's coverage report.

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=287

---

pu: dfcf84ebfa17eb0bb3b57806fa530e87d8c8f1b8
jch: dd824ca506dbdf198282714b0bd21665c5825b4d
next: bc1bbc6f855c3b5ef7fcbd0f688f647c4e5b208b
master: 5d826e972970a784bd7a7bdf587512510097b8c7
master@{1}: 7068cbc4abac53d9c3675dfba81c1e97d25e8eeb

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

commit-graph.c
721351787e  128) return NULL;
721351787e  131) return NULL;
721351787e  187) free(graph);
721351787e  188) return NULL;
721351787e  223) free(graph);
721351787e  224) return NULL;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

pretty.c
4681fe38e1 1069) return 0;
b755bf6f83 1107)     match_placeholder_arg(p, "=on", end) ||
b755bf6f83 1108)     match_placeholder_arg(p, "=true", end)) {

protocol.c
24c10f7473  37) die(_("Unrecognized protocol version"));
24c10f7473  39) die(_("Unrecognized protocol_version"));

remote-curl.c
24c10f7473  403) return 0;

strbuf.c
18f8e81091  397) return 0;

submodule.c
26f80ccfc1 1396) strbuf_release(&gitdir);
be76c21282 1519) struct fetch_task *task = task_cb;
be76c21282 1523) fetch_task_release(task);

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Anders Waldenborg      18f8e8109: strbuf: separate callback for 
strbuf_expand:ing literals
Anders Waldenborg      4681fe38e: pretty: allow showing specific trailers
Anders Waldenborg      b755bf6f8: pretty: allow %(trailers) options with 
explicit value
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Josh Steadmon      24c10f747: protocol: advertise multiple supported 
versions
Josh Steadmon      721351787: commit-graph, fuzz: add fuzzer for 
commit-graph
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      26f80ccfc: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      be76c2128: fetch: ensure submodule objects fetched



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

pathspec.c
22af33bece 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
ee70c12820 1730) if (advice_unknown_index_extension) {
ee70c12820 1731) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1732) advise(_("This is likely due to the file having been 
written by a newer\n"
ec36c42a63 3508) const char *index = NULL;
ec36c42a63 3514) if (!offset)
ec36c42a63 3515) return NULL;
ec36c42a63 3516) while (offset <= mmap_size - the_hash_algo->rawsz - 8) {
ec36c42a63 3517) extsize = get_be32(mmap + offset + 4);
ec36c42a63 3518) if (CACHE_EXT((mmap + offset)) == 
CACHE_EXT_INDEXENTRYOFFSETTABLE) {
ec36c42a63 3519) index = mmap + offset + 4 + 4;
ec36c42a63 3520) break;
ec36c42a63 3522) offset += 8;
ec36c42a63 3523) offset += extsize;
ec36c42a63 3525) if (!index)
ec36c42a63 3526) return NULL;
ec36c42a63 3529) ext_version = get_be32(index);
ec36c42a63 3530) if (ext_version != IEOT_VERSION) {
ec36c42a63 3531) error("invalid IEOT version %d", ext_version);
ec36c42a63 3532) return NULL;
ec36c42a63 3534) index += sizeof(uint32_t);
ec36c42a63 3537) nr = (extsize - sizeof(uint32_t)) / (sizeof(uint32_t) + 
sizeof(uint32_t));
ec36c42a63 3538) if (!nr) {
ec36c42a63 3539) error("invalid number of IEOT entries %d", nr);
ec36c42a63 3540) return NULL;
ec36c42a63 3542) ieot = xmalloc(sizeof(struct index_entry_offset_table)
ec36c42a63 3543)        + (nr * sizeof(struct index_entry_offset)));
ec36c42a63 3544) ieot->nr = nr;
ec36c42a63 3545) for (i = 0; i < nr; i++) {
ec36c42a63 3546) ieot->entries[i].offset = get_be32(index);
ec36c42a63 3547) index += sizeof(uint32_t);
ec36c42a63 3548) ieot->entries[i].nr = get_be32(index);
ec36c42a63 3549) index += sizeof(uint32_t);
ec36c42a63 3552) return ieot;

sequencer.c
18e711a162 2387) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

tree.c
e092073d64 104) commit = lookup_commit(r, entry.oid);

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths
Nguyễn Thái Ngọc Duy      22af33bec: dir.c: move, rename and export 
match_attrs()
Nguyễn Thái Ngọc Duy      e092073d6: tree.c: make read_tree*() take 
'struct repository *'
Nguyễn Thái Ngọc Duy      ec36c42a6: Indent code with TABs



Uncovered code in 'next' not in 'master'
--------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 421) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 460) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 584) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 619) fprintf_ln(stderr, _("Checking object 
directory"));
5215bd2f7d builtin/fsck.c 637) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
5215bd2f7d builtin/fsck.c 642) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 671) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 687) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  135) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
5215bd2f7d 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
5215bd2f7d 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
a965bb3116 1821) read_next_command();

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2251) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2286) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3100) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3247) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  236) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2353) return error(_("option `%s' is incompatible with 
--no-merged"),

remote-curl.c
afa5d74929  359) die("invalid server response; expected service, got 
flush packet");

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2145) return r;

Commits introducing uncovered code:
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      afa5d7492: remote-curl: refactor smart-http discovery
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Junio C Hamano      5215bd2f7: Merge branch 'nd/i18n' into next
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/rebase.c
13a5a9f0fd  789) return; /* only override it if it is "rebase" */

range-diff.c
d8981c3f88 466) diff_setup(&opts);

Commits introducing uncovered code:
Johannes Schindelin      13a5a9f0f: rebase: fix GIT_REFLOG_ACTION regression
Junio C Hamano      d8981c3f8: format-patch: do not let its diff-options 
affect --range-diff




^ permalink raw reply	[relevance 2%]

* [ANNOUNCE] Git v2.20.0
@ 2018-12-09  8:43  2% Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-09  8:43 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

The latest feature release Git v2.20.0 is now available at the usual
places.  It is comprised of 962 non-merge commits since v2.19.0
(this is by far the largest release in v2.x.x series), contributed
by 83 people, 26 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/

The following public repositories all have a copy of the 'v2.20.0'
tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.19.0 are as follows.
Welcome to the Git development community!

  Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan
  Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis,
  David Zych, Đoàn Trần Công Danh, Frederick Eaton, Greg
  Hurrell, James Knight, Jann Horn, Joshua Watt, Loo Rong Jie,
  Lucas De Marchi, Matthew DeVore, Mihir Mehta, Minh Nguyen,
  Nickolai Belakovski, Roger Strain, Sam McKelvie, Saulius Gurklys,
  Shulhan, Steven Fernandez, Strain, Roger L, and Tim Schumacher.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Alban Gruin, Alexander Shopov,
  Andreas Gruenbacher, Andreas Heiduk, Antonio Ospite, Ben Peart,
  Brandon Williams, brian m. carlson, Christian Couder, Christian
  Hesse, Christopher Díaz Riveros, Denton Liu, Derrick Stolee,
  Elijah Newren, Eric Sunshine, Jean-Noël Avila, Jeff Hostetler,
  Jeff King, Jiang Xin, Johannes Schindelin, Johannes Sixt,
  Jonathan Nieder, Jonathan Tan, Jordi Mas, Josh Steadmon,
  Junio C Hamano, Karsten Blees, Luke Diamand, Martin Ågren,
  Max Kirillov, Michael Witten, Michał Górny, Nguyễn Thái
  Ngọc Duy, Noam Postavsky, Olga Telezhnaya, Peter Krefting,
  Phillip Wood, Pratik Karki, Rafael Ascensão, Ralf Thielow,
  Ramsay Jones, Rasmus Villemoes, René Scharfe, Sebastian Staudt,
  Stefan Beller, Stephen P. Smith, Steve Hoelzer, Sven Strickroth,
  SZEDER Gábor, Tao Qingyun, Taylor Blau, Thomas Gummerer,
  Todd Zullinger, Torsten Bögershausen, Trần Ngọc Quân,
  and Uwe Kleine-König.

----------------------------------------------------------------

Git 2.20 Release Notes
======================

Backward Compatibility Notes
----------------------------

 * "git branch -l <foo>" used to be a way to ask a reflog to be
   created while creating a new branch, but that is no longer the
   case.  It is a short-hand for "git branch --list <foo>" now.

 * "git push" into refs/tags/* hierarchy is rejected without getting
   forced, but "git fetch" (misguidedly) used the "fast forwarding"
   rule used for the refs/heads/* hierarchy; this has been corrected,
   which means some fetches of tags that did not fail with older
   version of Git will fail without "--force" with this version.

 * "git help -a" now gives verbose output (same as "git help -av").
   Those who want the old output may say "git help --no-verbose -a"..

 * "git cpn --help", when "cpn" is an alias to, say, "cherry-pick -n",
   reported only the alias expansion of "cpn" in earlier versions of
   Git.  It now runs "git cherry-pick --help" to show the manual page
   of the command, while sending the alias expansion to the standard
   error stream.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by". This is a backward-incompatible
   change.  Adding "--suppress-cc=misc-by" on the command line, or
   setting sendemail.suppresscc configuration variable to "misc-by",
   can be used to disable this behaviour.


Updates since v2.19
-------------------

UI, Workflows & Features

 * Running "git clone" against a project that contain two files with
   pathnames that differ only in cases on a case insensitive
   filesystem would result in one of the files lost because the
   underlying filesystem is incapable of holding both at the same
   time.  An attempt is made to detect such a case and warn.

 * "git checkout -b newbranch [HEAD]" should not have to do as much as
   checking out a commit different from HEAD.  An attempt is made to
   optimize this special case.

 * "git rev-list --stdin </dev/null" used to be an error; it now shows
   no output without an error.  "git rev-list --stdin --default HEAD"
   still falls back to the given default when nothing is given on the
   standard input.

 * Lift code from GitHub to restrict delta computation so that an
   object that exists in one fork is not made into a delta against
   another object that does not appear in the same forked repository.

 * "git format-patch" learned new "--interdiff" and "--range-diff"
   options to explain the difference between this version and the
   previous attempt in the cover letter (or after the three-dashes as
   a comment).

 * "git mailinfo" used in "git am" learned to make a best-effort
   recovery of a patch corrupted by MUA that sends text/plain with
   format=flawed option.
   (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).

 * The rules used by "git push" and "git fetch" to determine if a ref
   can or cannot be updated were inconsistent; specifically, fetching
   to update existing tags were allowed even though tags are supposed
   to be unmoving anchoring points.  "git fetch" was taught to forbid
   updates to existing tags without the "--force" option.

 * "git multi-pack-index" learned to detect corruption in the .midx
   file it uses, and this feature has been integrated into "git fsck".

 * Generation of (experimental) commit-graph files have so far been
   fairly silent, even though it takes noticeable amount of time in a
   meaningfully large repository.  The users will now see progress
   output.

 * The minimum version of Windows supported by Windows port of Git is
   now set to Vista.

 * The completion script (in contrib/) learned to complete a handful of
   options "git stash list" command takes.

 * The completion script (in contrib/) learned that "git fetch
   --multiple" only takes remote names as arguments and no refspecs.

 * "git status" learns to show progress bar when refreshing the index
   takes a long time.
   (merge ae9af12287 nd/status-refresh-progress later to maint).

 * "git help -a" and "git help -av" give different pieces of
   information, and generally the "verbose" version is more friendly
   to the new users.  "git help -a" by default now uses the more
   verbose output (with "--no-verbose", you can go back to the
   original).  Also "git help -av" now lists aliases and external
   commands, which it did not used to.

 * Unlike "grep", "git grep" by default recurses to the whole tree.
   The command learned "git grep --recursive" option, so that "git
   grep --no-recursive" can serve as a synonym to setting the
   max-depth to 0.

 * When pushing into a repository that borrows its objects from an
   alternate object store, "git receive-pack" that responds to the
   push request on the other side lists the tips of refs in the
   alternate to reduce the amount of objects transferred.  This
   sometimes is detrimental when the number of refs in the alternate
   is absurdly large, in which case the bandwidth saved in potentially
   fewer objects transferred is wasted in excessively large ref
   advertisement.  The alternate refs that are advertised are now
   configurable with a pair of configuration variables.

 * "git cmd --help" when "cmd" is aliased used to only say "cmd is
   aliased to ...".  Now it shows that to the standard error stream
   and runs "git $cmd --help" where $cmd is the first word of the
   alias expansion.

 * The documentation of "git gc" has been updated to mention that it
   is no longer limited to "pruning away crufts" but also updates
   ancillary files like commit-graph as a part of repository
   optimization.

 * "git p4 unshelve" improvements.

 * The logic to select the default user name and e-mail on Windows has
   been improved.
   (merge 501afcb8b0 js/mingw-default-ident later to maint).

 * The "rev-list --filter" feature learned to exclude all trees via
   "tree:0" filter.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by"; --suppress-cc=misc-by on the
   command line, or setting sendemail.suppresscc configuration
   variable to "misc-by", can be used to disable this behaviour.

 * "git mergetool" learned to take the "--[no-]gui" option, just like
   "git difftool" does.

 * "git rebase -i" learned a new insn, 'break', that the user can
   insert in the to-do list.  Upon hitting it, the command returns
   control back to the user.

 * New "--pretty=format:" placeholders %GF and %GP that show the GPG
   key fingerprints have been invented.

 * On platforms with recent cURL library, http.sslBackend configuration
   variable can be used to choose a different SSL backend at runtime.
   The Windows port uses this mechanism to switch between OpenSSL and
   Secure Channel while talking over the HTTPS protocol.

 * "git send-email" learned to disable SMTP authentication via the
   "--smtp-auth=none" option, even when the smtp username is given
   (which turns the authentication on by default).

 * A fourth class of configuration files (in addition to the
   traditional "system wide", "per user in the $HOME directory" and
   "per repository in the $GIT_DIR/config") has been introduced so
   that different worktrees that share the same repository (hence the
   same $GIT_DIR/config file) can use different customization.

 * A pattern with '**' that does not have a slash on either side used
   to be an invalid one, but the code now treats such double-asterisks
   the same way as two normal asterisks that happen to be adjacent to
   each other.
   (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).

 * The "--no-patch" option, which can be used to get a high-level
   overview without the actual line-by-line patch difference shown, of
   the "range-diff" command was earlier broken, which has been
   corrected.

 * The recently merged "rebase in C" has an escape hatch to use the
   scripted version when necessary, but it hasn't been documented,
   which has been corrected.


Performance, Internal Implementation, Development Support etc.

 * Developer builds now use -Wunused-function compilation option.

 * One of our CI tests to run with "unusual/experimental/random"
   settings now also uses commit-graph and midx.

 * When there are too many packfiles in a repository (which is not
   recommended), looking up an object in these would require
   consulting many pack .idx files; a new mechanism to have a single
   file that consolidates all of these .idx files is introduced.

 * "git submodule update" is getting rewritten piece-by-piece into C.

 * The code for computing history reachability has been shuffled,
   obtained a bunch of new tests to cover them, and then being
   improved.

 * The unpack_trees() API used in checking out a branch and merging
   walks one or more trees along with the index.  When the cache-tree
   in the index tells us that we are walking a tree whose flattened
   contents is known (i.e. matches a span in the index), as linearly
   scanning a span in the index is much more efficient than having to
   open tree objects recursively and listing their entries, the walk
   can be optimized, which has been done.

 * When creating a thin pack, which allows objects to be made into a
   delta against another object that is not in the resulting pack but
   is known to be present on the receiving end, the code learned to
   take advantage of the reachability bitmap; this allows the server
   to send a delta against a base beyond the "boundary" commit.

 * spatch transformation to replace boolean uses of !hashcmp() to
   newly introduced oideq() is added, and applied, to regain
   performance lost due to support of multiple hash algorithms.

 * Fix a bug in which the same path could be registered under multiple
   worktree entries if the path was missing (for instance, was removed
   manually).  Also, as a convenience, expand the number of cases in
   which --force is applicable.

 * Split Documentation/config.txt for easier maintenance.
   (merge 6014363f0b nd/config-split later to maint).

 * Test helper binaries clean-up.
   (merge c9a1f4161f nd/test-tool later to maint).

 * Various tests have been updated to make it easier to swap the
   hash function used for object identification.
   (merge ae0c89d41b bc/hash-independent-tests later to maint).

 * Update fsck.skipList implementation and documentation.
   (merge 371a655074 ab/fsck-skiplist later to maint).

 * An alias that expands to another alias has so far been forbidden,
   but now it is allowed to create such an alias.

 * Various test scripts have been updated for style and also correct
   handling of exit status of various commands.

 * "gc --auto" ended up calling exit(-1) upon error, which has been
   corrected to use exit(1).  Also the error reporting behaviour when
   daemonized has been updated to exit with zero status when stopping
   due to a previously discovered error (which implies there is no
   point running gc to improve the situation); we used to exit with
   failure in such a case.

 * Various codepaths in the core-ish part learned to work on an
   arbitrary in-core index structure, not necessarily the default
   instance "the_index".
   (merge b3c7eef9b0 nd/the-index later to maint).

 * Code clean-up in the internal machinery used by "git status" and
   "git commit --dry-run".
   (merge 73ba5d78b4 ss/wt-status-committable later to maint).

 * Some environment variables that control the runtime options of Git
   used during tests are getting renamed for consistency.
   (merge 4231d1ba99 bp/rename-test-env-var later to maint).

 * A pair of new extensions to the index file have been introduced.
   They allow the index file to be read in parallel for performance.

 * The oidset API was built on top of the oidmap API which in turn is
   on the hashmap API.  Replace the implementation to build on top of
   the khash API and gain performance.

 * Over some transports, fetching objects with an exact commit object
   name can be done without first seeing the ref advertisements.  The
   code has been optimized to exploit this.

 * In a partial clone that will lazily be hydrated from the
   originating repository, we generally want to avoid "does this
   object exist (locally)?" on objects that we deliberately omitted
   when we created the clone.  The cache-tree codepath (which is used
   to write a tree object out of the index) however insisted that the
   object exists, even for paths that are outside of the partial
   checkout area.  The code has been updated to avoid such a check.

 * To help developers, an EditorConfig file that attempts to follow
   the project convention has been added.
   (merge b548d698a0 bc/editorconfig later to maint).

 * The result of coverage test can be combined with "git blame" to
   check the test coverage of code introduced recently with a new
   'coverage-diff' tool (in contrib/).
   (merge 783faedd65 ds/coverage-diff later to maint).

 * An experiment to fuzz test a few areas, hopefully we can gain more
   coverage to various areas.

 * More codepaths are moving away from hardcoded hash sizes.

 * The way the Windows port figures out the current directory has been
   improved.

 * The way DLLs are loaded on the Windows port has been improved.

 * Some tests have been reorganized and renamed; "ls t/" now gives a
   better overview of what is tested for these scripts than before.

 * "git rebase" and "git rebase -i" have been reimplemented in C.

 * Windows port learned to use nano-second resolution file timestamps.

 * The overly large Documentation/config.txt file have been split into
   million little pieces.  This potentially allows each individual piece
   to be included into the manual page of the command it affects more easily.

 * Replace three string-list instances used as look-up tables in "git
   fetch" with hashmaps.

 * Unify code to read the author-script used in "git am" and the
   commands that use the sequencer machinery, e.g. "git rebase -i".

 * In preparation to the day when we can deprecate and remove the
   "rebase -p", make sure we can skip and later remove tests for
   it.

 * The history traversal used to implement the tag-following has been
   optimized by introducing a new helper.

 * The helper function to refresh the cached stat information in the
   in-core index has learned to perform the lstat() part of the
   operation in parallel on multi-core platforms.

 * The code to traverse objects for reachability, used to decide what
   objects are unreferenced and expendable, have been taught to also
   consider per-worktree refs of other worktrees as starting points to
   prevent data loss.

 * "git add" needs to internally run "diff-files" equivalent, and the
   codepath learned the same optimization as "diff-files" has to run
   lstat(2) in parallel to find which paths have been updated in the
   working tree.

 * The procedure to install dependencies before testing at Travis CI
   is getting revamped for both simplicity and flexibility, taking
   advantage of the recent move to the vm-based environment.

 * The support for format-patch (and send-email) by the command-line
   completion script (in contrib/) has been simplified a bit.

 * The revision walker machinery learned to take advantage of the
   commit generation numbers stored in the commit-graph file.

 * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".

 * The way -lcurl library gets linked has been simplified by taking
   advantage of the fact that we can just ask curl-config command how.

 * Various functions have been audited for "-Wunused-parameter" warnings
   and bugs in them got fixed.

 * A sanity check for start-up sequence has been added in the config
   API codepath.

 * The build procedure to link for fuzzing test has been made
   customizable with a new Makefile variable.

 * The way "git rebase" parses and forwards the command line options
   meant for underlying "git am" has been revamped, which fixed for
   options with parameters that were not passed correctly.

 * Our testing framework uses a special i18n "poisoned localization"
   feature to find messages that ought to stay constant but are
   incorrectly marked to be translated.  This feature has been made
   into a runtime option (it used to be a compile-time option).

 * "git push" used to check ambiguities between object-names and
   refnames while processing the list of refs' old and new values,
   which was unnecessary (as it knew that it is feeding raw object
   names).  This has been optimized out.

 * The xcurl_off_t() helper function is used to cast size_t to
   curl_off_t, but some compilers gave warnings against the code to
   ensure the casting is done without wraparound, when size_t is
   narrower than curl_off_t.  This warning has been squelched.

 * Code preparation to replace ulong vars with size_t vars where
   appropriate continues.

 * The "test installed Git" mode of our test suite has been updated to
   work better.

 * A coding convention around the Coccinelle semantic patches to have
   two classes to ease code migration process has been proposed and
   its support has been added to the Makefile.

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.
   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.
   (merge a5f52c6dab sg/test-verbose-log later to maint).


Fixes since v2.19
-----------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.
   (merge 66e83d9b41 jk/trailer-fixes later to maint).

 * Malformed or crafted data in packstream can make our code attempt
   to read or write past the allocated buffer and abort, instead of
   reporting an error, which has been fixed.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.
   (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.
   (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.
   (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).

 * Further fix for O_APPEND emulation on Windows
   (merge eeaf7ddac7 js/mingw-o-append later to maint).

 * A corner case bugfix in "git rerere" code.
   (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.
   (merge 84d938b732 nd/attr-pathspec-fix later to maint).

 * Recent update broke the reachability algorithm when refs (e.g.
   tags) that point at objects that are not commit were involved,
   which has been fixed.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.
   (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.
   (merge e68302011c jt/lazy-object-fetch-fix later to maint).

 * Update error messages given by "git remote" and make them consistent.
   (merge 5025425dff ms/remote-error-message-update later to maint).

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.
   (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.
   (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.
   (merge 829a321569 ds/commit-graph-with-grafts later to maint).

 * The mailmap file update.
   (merge 255eb03edf jn/mailmap-update later to maint).

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.
   (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).

 * "git fetch $repo $object" in a partial clone did not correctly
   fetch the asked-for object that is referenced by an object in
   promisor packfile, which has been fixed.

 * A corner-case bugfix.
   (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).

 * Various fixes to "diff --color-moved-ws".

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.
   (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.
   (merge 4c490f3d32 sg/split-index-racefix later to maint).

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.
   (merge 04005834ed np/log-graph-octopus-fix later to maint).

 * "git range-diff" did not work well when the compared ranges had
   changes in submodules and the "--submodule=log" was used.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.
   (merge f67b980771 jk/run-command-notdot later to maint).

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.
   (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.
   (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.
   (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).

 * The logic to determine the archive type "git archive" uses did not
   correctly kick in for "git archive --remote", which has been
   corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.
   (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).

 * Some codepaths failed to form a proper URL when .gitmodules record
   the URL to a submodule repository as relative to the repository of
   superproject, which has been corrected.
   (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).

 * "git fetch" over protocol v2 into a shallow repository failed to
   fetch full history behind a new tip of history that was diverged
   before the cut-off point of the history that was previously fetched
   shallowly.

 * The command line completion machinery (in contrib/) has been
   updated to allow the completion script to tweak the list of options
   that are reported by the parse-options machinery correctly.
   (merge 276b49ff34 nd/completion-negation later to maint).

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.
   (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.
   (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).

 * "git ls-remote $there foo" was broken by recent update for the
   protocol v2 and stopped showing refs that match 'foo' that are not
   refs/{heads,tags}/foo, which has been fixed.
   (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).

 * Additional comment on a tricky piece of code to help developers.
   (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).

 * A couple of tests used to leave the repository in a state that is
   deliberately corrupt, which have been corrected.
   (merge aa984dbe5e ab/pack-tests-cleanup later to maint).

 * The submodule support has been updated to read from the blob at
   HEAD:.gitmodules when the .gitmodules file is missing from the
   working tree.
   (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).

 * "git fetch" was a bit loose in parsing responses from the other side
   when talking over the protocol v2.

 * "git rev-parse --exclude=* --branches --branches"  (i.e. first
   saying "add only things that do not match '*' out of all branches"
   and then adding all branches, without any exclusion this time)
   worked as expected, but "--exclude=* --all --all" did not work the
   same way, which has been fixed.
   (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).

 * "git send-email --transfer-encoding=..." in recent versions of Git
   sometimes produced an empty "Content-Transfer-Encoding:" header,
   which has been corrected.
   (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).

 * The interface into "xdiff" library used to discover the offset and
   size of a generated patch hunk by first formatting it into the
   textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
   out.  A new interface has been introduced to allow callers a more
   direct access to them.
   (merge 5eade0746e jk/xdiff-interface later to maint).

 * Pathspec matching against a tree object were buggy when negative
   pathspec elements were involved, which has been fixed.
   (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).

 * "git merge" and "git pull" that merges into an unborn branch used
   to completely ignore "--verify-signatures", which has been
   corrected.
   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).

 * "git rebase --autostash" did not correctly re-attach the HEAD at times.

 * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
   quite work, which has been corrected.
   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).

 * When editing a patch in a "git add -i" session, a hunk could be
   made to no-op.  The "git apply" program used to reject a patch with
   such a no-op hunk to catch user mistakes, but it is now updated to
   explicitly allow a no-op hunk in an edited patch.
   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).

 * The URL to an MSDN page in a comment has been updated.
   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).

 * "git ls-remote --sort=<thing>" can feed an object that is not yet
   available into the comparison machinery and segfault, which has
   been corrected to check such a request upfront and reject it.

 * When "git bundle" aborts due to an empty commit ranges
   (i.e. resulting in an empty pack), it left a file descriptor to an
   lockfile open, which resulted in leftover lockfile on Windows where
   you cannot remove a file with an open file descriptor.  This has
   been corrected.
   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).

 * "git format-patch --stat=<width>" can be used to specify the width
   used by the diffstat (shown in the cover letter).
   (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).

 * The way .git/index and .git/sharedindex* files were initially
   created gave these files different perm bits until they were
   adjusted for shared repository settings.  This was made consistent.
   (merge c9d6c78870 cc/shared-index-permbits later to maint).

 * "git rebase --stat" to transplant a piece of history onto a totally
   unrelated history were not working before and silently showed wrong
   result.  With the recent reimplementation in C, it started to instead
   die with an error message, as the original logic was not prepared
   to cope with this case.  This has now been fixed.

 * The advice message to tell the user to migrate an existing graft
   file to the replace system when a graft file was read was shown
   even when "git replace --convert-graft-file" command, which is the
   way the message suggests to use, was running, which made little
   sense.
   (merge 8821e90a09 ab/replace-graft-with-replace-advice later to maint).

 * "git diff --raw" lost ellipses to adjust the output columns for
   some time now, but the documentation still showed them.

 * Code cleanup, docfix, build fix, etc.
   (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
   (merge b9b07efdb2 tg/conflict-marker-size later to maint).
   (merge fa0aeea770 sg/doc-trace-appends later to maint).
   (merge d64324cb60 tb/void-check-attr later to maint).
   (merge c3b9bc94b9 en/double-semicolon-fix later to maint).
   (merge 79336116f5 sg/t3701-tighten-trace later to maint).
   (merge 801fa63a90 jk/dev-build-format-security later to maint).
   (merge 0597dd62ba sb/string-list-remove-unused later to maint).
   (merge db2d36fad8 bw/protocol-v2 later to maint).
   (merge 456d7cd3a9 sg/split-index-test later to maint).
   (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).
   (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).
   (merge 55f6bce2c9 fe/doc-updates later to maint).
   (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).
   (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).
   (merge 4c399442f7 ma/commit-graph-docs later to maint).
   (merge fc0503b04e ma/t1400-undebug-test later to maint).
   (merge e56b53553a nd/packobjectshook-doc-fix later to maint).
   (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).
   (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).
   (merge ad0b8f9575 mw/doc-typofixes later to maint).
   (merge d9f079ad1a jc/how-to-document-api later to maint).
   (merge b1492bf315 ma/t7005-bash-workaround later to maint).
   (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).
   (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).
   (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).
   (merge 61018fe9e0 du/cherry-is-plumbing later to maint).
   (merge c7e5fe79b9 sb/strbuf-h-update later to maint).
   (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).
   (merge 2e3c894f4b tq/branch-style-fix later to maint).
   (merge c5d844af9c sg/doc-show-branch-typofix later to maint).
   (merge 081d91618b ah/doc-updates later to maint).
   (merge b84c783882 jc/cocci-preincr later to maint).
   (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).
   (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).
   (merge 3063477445 tb/char-may-be-unsigned later to maint).
   (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
   (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).
   (merge 3006f5ee16 ma/reset-doc-rendering-fix later to maint).
   (merge 4c2eb06419 sg/daemon-test-signal-fix later to maint).
   (merge d27525e519 ss/msvc-strcasecmp later to maint).

----------------------------------------------------------------

Changes since v2.19.0 are as follows:

Aaron Lindsay (1):
      send-email: avoid empty transfer encoding header

Alban Gruin (21):
      sequencer: make three functions and an enum from sequencer.c public
      rebase -i: rewrite append_todo_help() in C
      editor: add a function to launch the sequence editor
      rebase -i: rewrite the edit-todo functionality in C
      sequencer: add a new function to silence a command, except if it fails
      rebase -i: rewrite setup_reflog_action() in C
      rebase -i: rewrite checkout_onto() in C
      sequencer: refactor append_todo_help() to write its message to a buffer
      sequencer: change the way skip_unnecessary_picks() returns its result
      t3404: todo list with commented-out commands only aborts
      rebase -i: rewrite complete_action() in C
      rebase -i: remove unused modes and functions
      rebase -i: implement the logic to initialize $revisions in C
      rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C
      rebase -i: rewrite write_basic_state() in C
      rebase -i: rewrite init_basic_state() in C
      rebase -i: implement the main part of interactive rebase as a builtin
      rebase--interactive2: rewrite the submodes of interactive rebase in C
      rebase -i: remove git-rebase--interactive.sh
      rebase -i: move rebase--helper modes to rebase--interactive
      p3400: replace calls to `git checkout -b' by `git checkout -B'

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Alexander Shopov (3):
      l10n: bg.po: Updated Bulgarian translation (4185t)
      l10n: bg.po: Updated Bulgarian translation (4185t)
      l10n: bg.po: Updated Bulgarian translation (4187t)

Andreas Gruenbacher (1):
      rev-parse: clear --exclude list after 'git rev-parse --all'

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Anton Serbulov (1):
      mingw: fix getcwd when the parent directory cannot be queried

Antonio Ospite (10):
      submodule: add a print_config_from_gitmodules() helper
      submodule: factor out a config_set_in_gitmodules_file_gently function
      t7411: merge tests 5 and 6
      t7411: be nicer to future tests and really clean things up
      submodule--helper: add a new 'config' subcommand
      submodule: use the 'submodule--helper config' command
      t7506: clean up .gitmodules properly before setting up new scenario
      submodule: add a helper to check if it is safe to write to .gitmodules
      submodule: support reading .gitmodules when it's not in the working tree
      t/helper: add test-submodule-nested-repo-config

Ben Peart (19):
      checkout: optimize "git checkout -b <new_branch>"
      git-mv: allow submodules and fsmonitor to work together
      t/README: correct spelling of "uncommon"
      preload-index: use git_env_bool() not getenv() for customization
      fsmonitor: update GIT_TEST_FSMONITOR support
      read-cache: update TEST_GIT_INDEX_VERSION support
      preload-index: update GIT_FORCE_PRELOAD_TEST support
      read-cache: clean up casting and byte decoding
      eoie: add End of Index Entry (EOIE) extension
      config: add new index.threads config setting
      read-cache: load cache extensions on a worker thread
      ieot: add Index Entry Offset Table (IEOT) extension
      read-cache: load cache entries on worker threads
      reset: don't compute unstaged changes after reset when --quiet
      reset: add new reset.quiet config setting
      reset: warn when refresh_index() takes more than 2 seconds
      speed up refresh_index() by utilizing preload_index()
      add: speed up cmd_add() by utilizing read_cache_preload()
      refresh_index: remove unnecessary calls to preload_index()

Brandon Williams (1):
      config: document value 2 for protocol.version

Brendan Forster (1):
      http: add support for disabling SSL revocation checks in cURL

Carlo Marcelo Arenas Belón (8):
      unpack-trees: avoid dead store for struct progress
      multi-pack-index: avoid dead store for struct progress
      read-cache: use of memory after it is freed
      commit-slabs: move MAYBE_UNUSED out
      khash: silence -Wunused-function for delta-islands
      compat: make sure git_mmap is not expected to write
      sequencer: cleanup for gcc warning in non developer mode
      builtin/notes: remove unnecessary free

Christian Couder (3):
      pack-objects: refactor code into compute_layer_order()
      pack-objects: move tree_depth into 'struct packing_data'
      pack-objects: move 'layer' into 'struct packing_data'

Christian Hesse (2):
      subtree: add build targets 'man' and 'html'
      subtree: make install targets depend on build targets

Christopher Díaz Riveros (2):
      l10n: es.po v2.20.0 round 1
      l10n: es.po v2.20.0 round 3

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Denton Liu (3):
      mergetool: accept -g/--[no-]gui as arguments
      completion: support `git mergetool --[no-]gui`
      doc: document diff/merge.guitool config keys

Derrick Stolee (93):
      multi-pack-index: add design document
      multi-pack-index: add format details
      multi-pack-index: add builtin
      multi-pack-index: add 'write' verb
      midx: write header information to lockfile
      multi-pack-index: load into memory
      t5319: expand test data
      packfile: generalize pack directory list
      multi-pack-index: read packfile list
      multi-pack-index: write pack names in chunk
      midx: read pack names into array
      midx: sort and deduplicate objects from packfiles
      midx: write object ids in a chunk
      midx: write object id fanout chunk
      midx: write object offsets
      config: create core.multiPackIndex setting
      midx: read objects from multi-pack-index
      midx: use midx in abbreviation calculations
      midx: use existing midx when writing new one
      midx: use midx in approximate_object_count
      midx: prevent duplicate packfile loads
      packfile: skip loading index if in multi-pack-index
      midx: clear midx on repack
      commit-reach: move walk methods from commit.c
      commit.h: remove method declarations
      commit-reach: move ref_newer from remote.c
      commit-reach: move commit_contains from ref-filter
      upload-pack: make reachable() more generic
      upload-pack: refactor ok_to_give_up()
      upload-pack: generalize commit date cutoff
      commit-reach: move can_all_from_reach_with_flags
      test-reach: create new test tool for ref_newer
      test-reach: test in_merge_bases
      test-reach: test is_descendant_of
      test-reach: test get_merge_bases_many
      test-reach: test reduce_heads
      test-reach: test can_all_from_reach_with_flags
      test-reach: test commit_contains
      commit-reach: replace ref_newer logic
      commit-reach: make can_all_from_reach... linear
      commit-reach: use can_all_from_reach
      multi-pack-index: provide more helpful usage info
      multi-pack-index: store local property
      midx: mark bad packed objects
      midx: stop reporting garbage
      midx: fix bug that skips midx with alternates
      packfile: add all_packs list
      treewide: use get_all_packs
      midx: test a few commands that use get_all_packs
      pack-objects: consider packs in multi-pack-index
      commit-graph: update design document
      test-repository: properly init repo
      commit-graph: not compatible with replace objects
      commit-graph: not compatible with grafts
      commit-graph: not compatible with uninitialized repo
      commit-graph: close_commit_graph before shallow walk
      commit-graph: define GIT_TEST_COMMIT_GRAPH
      t3206-range-diff.sh: cover single-patch case
      t5318: use test_oid for HASH_LEN
      multi-pack-index: add 'verify' verb
      multi-pack-index: verify bad header
      multi-pack-index: verify corrupt chunk lookup table
      multi-pack-index: verify packname order
      multi-pack-index: verify missing pack
      multi-pack-index: verify oid fanout order
      multi-pack-index: verify oid lookup order
      multi-pack-index: fix 32-bit vs 64-bit size check
      multi-pack-index: verify object offsets
      multi-pack-index: report progress during 'verify'
      fsck: verify multi-pack-index
      commit-reach: properly peel tags
      commit-reach: fix memory and flag leaks
      commit-reach: cleanups in can_all_from_reach...
      commit-graph: clean up leaked memory during write
      commit-graph: reduce initial oid allocation
      midx: fix broken free() in close_midx()
      contrib: add coverage-diff script
      ci: add optional test variables
      commit-reach: fix first-parent heuristic
      midx: close multi-pack-index on repack
      multi-pack-index: define GIT_TEST_MULTI_PACK_INDEX
      packfile: close multi-pack-index in close_all_packs
      prio-queue: add 'peek' operation
      test-reach: add run_three_modes method
      test-reach: add rev-list tests
      revision.c: begin refactoring --topo-order logic
      commit/revisions: bookkeeping before refactoring
      revision.c: generation-based topo-order algorithm
      t6012: make rev-list tests more interesting
      commit-reach: implement get_reachable_subset
      test-reach: test get_reachable_subset
      remote: make add_missing_tags() linear
      pack-objects: ignore ambiguous object warnings

Elijah Newren (14):
      Remove superfluous trailing semicolons
      t4200: demonstrate rerere segfault on specially crafted merge
      rerere: avoid buffer overrun
      update-ref: fix type of update_flags variable to match its usage
      update-ref: allow --no-deref with --stdin
      sequencer: fix --allow-empty-message behavior, make it smarter
      merge-recursive: set paths correctly when three-way merging content
      merge-recursive: avoid wrapper function when unnecessary and wasteful
      merge-recursive: remove final remaining caller of merge_file_one()
      merge-recursive: rename merge_file_1() and merge_content()
      commit: fix erroneous BUG, 'multiple renames on the same target? how?'
      merge-recursive: improve auto-merging messages with path collisions
      merge-recursive: avoid showing conflicts with merge branch before HEAD
      fsck: move fsck_head_link() to get_default_heads() to avoid some globals

Eric Sunshine (26):
      format-patch: allow additional generated content in make_cover_letter()
      format-patch: add --interdiff option to embed diff in cover letter
      format-patch: teach --interdiff to respect -v/--reroll-count
      interdiff: teach show_interdiff() to indent interdiff
      log-tree: show_log: make commentary block delimiting reusable
      format-patch: allow --interdiff to apply to a lone-patch
      range-diff: respect diff_option.file rather than assuming 'stdout'
      range-diff: publish default creation factor
      range-diff: relieve callers of low-level configuration burden
      format-patch: add --range-diff option to embed diff in cover letter
      format-patch: extend --range-diff to accept revision range
      format-patch: teach --range-diff to respect -v/--reroll-count
      format-patch: add --creation-factor tweak for --range-diff
      format-patch: allow --range-diff to apply to a lone-patch
      worktree: don't die() in library function find_worktree()
      worktree: move delete_git_dir() earlier in file for upcoming new callers
      worktree: generalize delete_git_dir() to reduce code duplication
      worktree: prepare for more checks of whether path can become worktree
      worktree: disallow adding same path multiple times
      worktree: teach 'add' to respect --force for registered but missing path
      worktree: teach 'move' to override lock when --force given twice
      worktree: teach 'remove' to override lock when --force given twice
      worktree: delete .git/worktrees if empty after 'remove'
      doc-diff: fix non-portable 'man' invocation
      doc-diff: add --clean mode to remove temporary working gunk
      doc/Makefile: drop doc-diff worktree and temporary files on "make clean"

Frederick Eaton (3):
      git-archimport.1: specify what kind of Arch we're talking about
      git-column.1: clarify initial description, provide examples
      git-describe.1: clarify that "human readable" is also git-readable

Greg Hurrell (1):
      doc: update diff-format.txt for removed ellipses in --raw

James Knight (1):
      build: link with curl-defined linker flags

Jann Horn (2):
      patch-delta: fix oob read
      patch-delta: consistently report corruption

Jean-Noël Avila (3):
      l10n: fr.po v2.20 rnd 1
      i18n: fix small typos
      l10n: fr.po v2.20.0 round 3

Jeff Hostetler (2):
      t0051: test GIT_TRACE to a windows named pipe
      mingw: fix mingw_open_append to work with named pipes

Jeff King (98):
      branch: make "-l" a synonym for "--list"
      Add delta-islands.{c,h}
      pack-objects: add delta-islands support
      repack: add delta-islands support
      t5320: tests for delta islands
      t/perf: factor boilerplate out of test_perf
      t/perf: factor out percent calculations
      t/perf: add infrastructure for measuring sizes
      t/perf: add perf tests for fetches from a bitmapped server
      pack-bitmap: save "have" bitmap from walk
      pack-objects: reuse on-disk deltas for thin "have" objects
      SubmittingPatches: mention doc-diff
      rev-list: make empty --stdin not an error
      trailer: use size_t for string offsets
      trailer: use size_t for iterating trailer list
      trailer: pass process_trailer_opts to trailer_info_get()
      interpret-trailers: tighten check for "---" patch boundary
      interpret-trailers: allow suppressing "---" divider
      pretty, ref-filter: format %(trailers) with no_divider option
      sequencer: ignore "---" divider when parsing trailers
      append_signoff: use size_t for string offsets
      coccinelle: use <...> for function exclusion
      introduce hasheq() and oideq()
      convert "oidcmp() == 0" to oideq()
      convert "hashcmp() == 0" to hasheq()
      convert "oidcmp() != 0" to "!oideq()"
      convert "hashcmp() != 0" to "!hasheq()"
      convert hashmap comparison functions to oideq()
      read-cache: use oideq() in ce_compare functions
      show_dirstat: simplify same-content check
      doc-diff: always use oids inside worktree
      test-delta: read input into a heap buffer
      t5303: test some corrupt deltas
      patch-delta: handle truncated copy parameters
      t5303: use printf to generate delta bases
      doc/git-branch: remove obsolete "-l" references
      bitmap_has_sha1_in_uninteresting(): drop BUG check
      t5310: test delta reuse with bitmaps
      traverse_bitmap_commit_list(): don't free result
      pack-bitmap: drop "loaded" flag
      reopen_tempfile(): truncate opened file
      doc-diff: force worktree add
      config.mak.dev: add -Wformat-security
      pack-objects: handle island check for "external" delta base
      receive-pack: update comment with check_everything_connected
      submodule--helper: use "--" to signal end of clone options
      submodule-config: ban submodule urls that start with dash
      submodule-config: ban submodule paths that start with a dash
      fsck: detect submodule urls starting with dash
      fsck: detect submodule paths starting with dash
      more oideq/hasheq conversions
      transport: drop refnames from for_each_alternate_ref
      test-tool: show tool list on error
      config.mak.dev: enable -Wunused-function
      run-command: mark path lookup errors with ENOENT
      t5410: use longer path for sample script
      upload-pack: fix broken if/else chain in config callback
      t1450: check large blob in trailing-garbage test
      check_stream_sha1(): handle input underflow
      cat-file: handle streaming failures consistently
      ls-remote: do not send ref prefixes for patterns
      ls-remote: pass heads/tags prefixes to transport
      read_istream_pack_non_delta(): document input handling
      xdiff: provide a separate emit callback for hunks
      xdiff-interface: provide a separate consume callback for hunks
      rev-list: handle flags for --indexed-objects
      approxidate: handle pending number for "specials"
      pathspec: handle non-terminated strings with :(attr)
      diff: avoid generating unused hunk header lines
      diff: discard hunk headers for patch-ids earlier
      diff: use hunk callback for word-diff
      combine-diff: use an xdiff hunk callback
      diff: convert --check to use a hunk callback
      range-diff: use a hunk callback
      xdiff-interface: drop parse_hunk_header()
      apply: mark include/exclude options as NONEG
      am: handle --no-patch-format option
      ls-files: mark exclude options as NONEG
      pack-objects: mark index-version option as NONEG
      cat-file: mark batch options with NONEG
      status: mark --find-renames option with NONEG
      format-patch: mark "--no-numbered" option with NONEG
      show-branch: mark --reflog option as NONEG
      tag: mark "--message" option with NONEG
      cat-file: report an error on multiple --batch options
      apply: return -1 from option callback instead of calling exit(1)
      parse-options: drop OPT_DATE()
      assert NOARG/NONEG behavior of parse-options callbacks
      midx: double-check large object write loop
      merge: extract verify_merge_signature() helper
      merge: handle --verify-signatures for unborn branch
      pull: handle --verify-signatures for unborn branch
      approxidate: fix NULL dereference in date_time()
      bundle: dup() output descriptor closer to point-of-use
      pack-objects: fix tree_depth and layer invariants
      pack-objects: zero-initialize tree_depth/layer arrays
      pack-objects: fix off-by-one in delta-island tree-depth computation
      t5562: fix perl path

Jiang Xin (5):
      l10n: zh_CN: review for git v2.19.0 l10n
      l10n: git.pot: v2.20.0 round 1 (254 new, 27 removed)
      l10n: git.pot: v2.20.0 round 2 (2 new, 2 removed)
      l10n: git.pot: v2.20.0 round 3 (5 new, 3 removed)
      l10n: zh_CN: for git v2.20.0 l10n round 1 to 3

Johannes Schindelin (64):
      rebase -i --autosquash: demonstrate a problem skipping the last squash
      rebase -i: be careful to wrap up fixup/squash chains
      compat/poll: prepare for targeting Windows Vista
      mingw: set _WIN32_WINNT explicitly for Git for Windows
      mingw: bump the minimum Windows version to Vista
      builtin rebase: prepare for builtin rebase -i
      rebase -i: clarify what happens on a failed `exec`
      rebase -i: introduce the 'break' command
      getpwuid(mingw): initialize the structure only once
      getpwuid(mingw): provide a better default for the user name
      mingw: use domain information for default email
      http: add support for selecting SSL backends at runtime
      pack-objects: fix typo 'detla' -> 'delta'
      pack-objects (mingw): demonstrate a segmentation fault with large deltas
      pack-objects (mingw): initialize `packing_data` mutex in the correct spot
      rebase (autostash): avoid duplicate call to state_dir_path()
      rebase (autostash): store the full OID in <state-dir>/autostash
      rebase (autostash): use an explicit OID to apply the stash
      mingw: factor out code to set stat() data
      rebase --autostash: demonstrate a problem with dirty submodules
      rebase --autostash: fix issue with dirty submodules
      mingw: load system libraries the recommended way
      mingw: ensure `getcwd()` reports the correct case
      repack: point out a bug handling stale shallow info
      shallow: offer to prune only non-existing entries
      repack -ad: prune the list of shallow commits
      http: when using Secure Channel, ignore sslCAInfo by default
      t7800: fix quoting
      mingw: reencode environment variables on the fly (UTF-16 <-> UTF-8)
      config: rename `dummy` parameter to `cb` in git_default_config()
      config: allow for platform-specific core.* config settings
      config: move Windows-specific config settings into compat/mingw.c
      mingw: unset PERL5LIB by default
      mingw: fix isatty() after dup2()
      t3404: decouple some test cases from outcomes of previous test cases
      t3418: decouple test cases from a previous `rebase -p` test case
      tests: optionally skip `git rebase -p` tests
      Windows: force-recompile git.res for differing architectures
      built-in rebase: demonstrate regression with --autostash
      built-in rebase --autostash: leave the current branch alone if possible
      Update .mailmap
      rebase -r: demonstrate bug with conflicting merges
      rebase -r: do not write MERGE_HEAD unless needed
      rebase -i: include MERGE_HEAD into files to clean up
      built-in rebase --skip/--abort: clean up stale .git/<name> files
      status: rebase and merge can be in progress at the same time
      apply --recount: allow "no-op hunks"
      rebase: consolidate clean-up code before leaving reset_head()
      rebase: prepare reset_head() for more flags
      built-in rebase: reinstate `checkout -q` behavior where appropriate
      tests: fix GIT_TEST_INSTALLED's PATH to include t/helper/
      tests: respect GIT_TEST_INSTALLED when initializing repositories
      t/lib-gettext: test installed git-sh-i18n if GIT_TEST_INSTALLED is set
      mingw: use `CreateHardLink()` directly
      rebase: really just passthru the `git am` options
      rebase: validate -C<n> and --whitespace=<mode> parameters early
      config: report a bug if git_dir exists without commondir
      tests: do not require Git to be built when testing an installed Git
      tests: explicitly use `git.exe` on Windows
      mingw: replace an obsolete link with the superseding one
      legacy-rebase: backport -C<n> and --whitespace=<option> checks
      rebase: warn about the correct tree's OID
      rebase: fix GIT_REFLOG_ACTION regression
      rebase --stat: fix when rebasing to an unrelated history

Johannes Sixt (4):
      diff: don't attempt to strip prefix from absolute Windows paths
      rebase -i: recognize short commands without arguments
      t3404-rebase-interactive: test abbreviated commands
      rebase docs: fix incorrect format of the section Behavioral Differences

Jonathan Nieder (9):
      gc: improve handling of errors reading gc.log
      gc: exit with status 128 on failure
      gc: do not return error for prior errors in daemonized mode
      commit-reach: correct accidental #include of C file
      mailmap: consistently normalize brian m. carlson's name
      git doc: direct bug reporters to mailing list archive
      eoie: default to not writing EOIE section
      ieot: default to not writing IEOT section
      index: make index.threads=true enable ieot and eoie

Jonathan Tan (15):
      fetch-object: unify fetch_object[s] functions
      fetch-object: set exact_oid when fetching
      connected: document connectivity in partial clones
      fetch: in partial clone, check presence of targets
      fetch-pack: avoid object flags if no_dependents
      fetch-pack: exclude blobs when lazy-fetching trees
      transport: allow skipping of ref listing
      transport: do not list refs if possible
      transport: list refs before fetch if necessary
      fetch: do not list refs if fetching only hashes
      cache-tree: skip some blob checks in partial clone
      upload-pack: make have_obj not global
      upload-pack: make want_obj not global
      upload-pack: clear flags before each v2 request
      fetch-pack: be more precise in parsing v2 response

Jordi Mas (2):
      l10n: Update Catalan translation
      l10n: Update Catalan translation

Josh Steadmon (4):
      fuzz: add basic fuzz testing target.
      fuzz: add fuzz testing for packfile indices.
      archive: initialize archivers earlier
      Makefile: use FUZZ_CXXFLAGS for linking fuzzers

Joshua Watt (1):
      send-email: explicitly disable authentication

Junio C Hamano (37):
      Revert "doc/Makefile: drop doc-diff worktree and temporary files on "make clean""
      Initial batch post 2.19
      Second batch post 2.19
      Git 2.14.5
      Git 2.15.3
      Git 2.16.5
      Git 2.17.2
      Git 2.18.1
      Git 2.19.1
      t0000: do not get self-test disrupted by environment warnings
      CodingGuidelines: document the API in *.h files
      Declare that the next one will be named 2.20
      Third batch for 2.20
      rebase: fix typoes in error messages
      Fourth batch for 2.20
      Revert "subtree: make install targets depend on build targets"
      Fifth batch for 2.20
      receive: denyCurrentBranch=updateinstead should not blindly update
      cocci: simplify "if (++u > 1)" to "if (u++)"
      fsck: s/++i > 1/i++/
      http: give curl version warnings consistently
      Sixth batch for 2.20
      Seventh batch for 2.20
      fetch: replace string-list used as a look-up table with a hashmap
      rebase: apply cocci patch
      Eighth batch for 2.20
      Ninth batch for 2.20
      Makefile: ease dynamic-gettext-poison transition
      Tenth batch for 2.20
      Git 2.20-rc0
      RelNotes: name the release properly
      Prepare for 2.20-rc1
      Git 2.19.2
      Git 2.20-rc1
      format-patch: do not let its diff-options affect --range-diff
      Git 2.20-rc2
      Git 2.20

Karsten Blees (2):
      mingw: replace MSVCRT's fstat() with a Win32-based implementation
      mingw: implement nanosecond-precision file times

Loo Rong Jie (1):
      win32: replace pthread_cond_*() with much simpler code

Lucas De Marchi (1):
      range-diff: allow to diff files regardless of submodule config

Luke Diamand (3):
      git-p4: do not fail in verbose mode for missing 'fileSize' key
      git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved
      git-p4: fully support unshelving changelists

Martin Ågren (15):
      Doc: use `--type=bool` instead of `--bool`
      git-config.txt: fix 'see: above' note
      git-commit-graph.txt: fix bullet lists
      git-commit-graph.txt: typeset more in monospace
      git-commit-graph.txt: refer to "*commit*-graph file"
      Doc: refer to the "commit-graph file" with dash
      t1400: drop debug `echo` to actually execute `test`
      builtin/commit-graph.c: UNLEAK variables
      sequencer: break out of loop explicitly
      git-reset.txt: render tables correctly under Asciidoctor
      git-reset.txt: render literal examples as monospace
      range-diff: always pass at least minimal diff options
      RelNotes 2.20: move some items between sections
      RelNotes 2.20: clarify sentence
      RelNotes 2.20: drop spurious double quote

Matthew DeVore (19):
      list-objects: store common func args in struct
      list-objects: refactor to process_tree_contents
      list-objects: always parse trees gently
      t/README: reformat Do, Don't, Keep in mind lists
      Documentation: add shell guidelines
      tests: standardize pipe placement
      t/*: fix ordering of expected/observed arguments
      tests: don't swallow Git errors upstream of pipes
      t9109: don't swallow Git errors upstream of pipes
      tests: order arguments to git-rev-list properly
      rev-list: handle missing tree objects properly
      revision: mark non-user-given objects instead
      list-objects-filter: use BUG rather than die
      list-objects-filter-options: do not over-strbuf_init
      list-objects-filter: implement filter tree:0
      filter-trees: code clean-up of tests
      list-objects: support for skipping tree traversal
      Documentation/git-log.txt: do not show --exclude-promisor-objects
      exclude-promisor-objects: declare when option is allowed

Max Kirillov (1):
      http-backend test: make empty CONTENT_LENGTH test more realistic

Michael Witten (3):
      docs: typo: s/go/to/
      docs: graph: remove unnecessary `graph_update()' call
      docs: typo: s/isimilar/similar/

Michał Górny (6):
      gpg-interface.c: detect and reject multiple signatures on commits
      gpg-interface.c: use flags to determine key/signer info presence
      gpg-interface.c: support getting key fingerprint via %GF format
      gpg-interface.c: obtain primary key fingerprint as well
      t/t7510-signed-commit.sh: Add %GP to custom format checks
      t/t7510-signed-commit.sh: add signing subkey to Eris Discordia key

Mihir Mehta (1):
      doc: fix a typo and clarify a sentence

Minh Nguyen (1):
      l10n: vi.po: fix typo in pack-objects

Nguyễn Thái Ngọc Duy (170):
      clone: report duplicate entries on case-insensitive filesystems
      trace.h: support nested performance tracing
      unpack-trees: add performance tracing
      unpack-trees: optimize walking same trees with cache-tree
      unpack-trees: reduce malloc in cache-tree walk
      unpack-trees: reuse (still valid) cache-tree from src_index
      unpack-trees: add missing cache invalidation
      cache-tree: verify valid cache-tree in the test suite
      Document update for nd/unpack-trees-with-cache-tree
      bisect.c: make show_list() build again
      t/helper: keep test-tool command list sorted
      t/helper: merge test-dump-untracked-cache into test-tool
      t/helper: merge test-pkt-line into test-tool
      t/helper: merge test-parse-options into test-tool
      t/helper: merge test-dump-fsmonitor into test-tool
      Makefile: add a hint about TEST_BUILTINS_OBJS
      config.txt: follow camelCase naming
      config.txt: move fetch part out to a separate file
      config.txt: move format part out to a separate file
      config.txt: move gitcvs part out to a separate file
      config.txt: move gui part out to a separate file
      config.txt: move pull part out to a separate file
      config.txt: move push part out to a separate file
      config.txt: move receive part out to a separate file
      config.txt: move sendemail part out to a separate file
      config.txt: move sequence.editor out of "core" part
      config.txt: move submodule part out to a separate file
      archive.c: remove implicit dependency the_repository
      status: show progress bar if refreshing the index takes too long
      add: do not accept pathspec magic 'attr'
      completion: support "git fetch --multiple"
      read-cache.c: remove 'const' from index_has_changes()
      diff.c: reduce implicit dependency on the_index
      combine-diff.c: remove implicit dependency on the_index
      blame.c: rename "repo" argument to "r"
      diff.c: remove the_index dependency in textconv() functions
      grep.c: remove implicit dependency on the_index
      diff.c: remove implicit dependency on the_index
      read-cache.c: remove implicit dependency on the_index
      diff-lib.c: remove implicit dependency on the_index
      ll-merge.c: remove implicit dependency on the_index
      merge-blobs.c: remove implicit dependency on the_index
      merge.c: remove implicit dependency on the_index
      patch-ids.c: remove implicit dependency on the_index
      sha1-file.c: remove implicit dependency on the_index
      rerere.c: remove implicit dependency on the_index
      userdiff.c: remove implicit dependency on the_index
      line-range.c: remove implicit dependency on the_index
      submodule.c: remove implicit dependency on the_index
      tree-diff.c: remove implicit dependency on the_index
      ws.c: remove implicit dependency on the_index
      revision.c: remove implicit dependency on the_index
      revision.c: reduce implicit dependency the_repository
      read-cache.c: optimize reading index format v4
      config.txt: correct the note about uploadpack.packObjectsHook
      help -a: improve and make --verbose default
      refs.c: indent with tabs, not spaces
      Add a place for (not) sharing stuff between worktrees
      submodule.c: remove some of the_repository references
      completion: fix __gitcomp_builtin no longer consider extra options
      t1300: extract and use test_cmp_config()
      worktree: add per-worktree config files
      refs: new ref types to make per-worktree refs visible to all worktrees
      revision.c: correct a parameter name
      revision.c: better error reporting on ref from different worktrees
      fsck: check HEAD and reflog from other worktrees
      reflog expire: cover reflog from all worktrees
      Update makefile in preparation for Documentation/config/*.txt
      config.txt: move advice.* to a separate file
      config.txt: move core.* to a separate file
      config.txt: move add.* to a separate file
      config.txt: move alias.* to a separate file
      config.txt: move am.* to a separate file
      config.txt: move apply.* to a separate file
      config.txt: move blame.* to a separate file
      config.txt: move branch.* to a separate file
      config.txt: move browser.* to a separate file
      config.txt: move checkout.* to a separate file
      config.txt: move clean.* to a separate file
      config.txt: move color.* to a separate file
      config.txt: move column.* to a separate file
      config.txt: move commit.* to a separate file
      config.txt: move credential.* to a separate file
      config.txt: move completion.* to a separate file
      config.txt: move diff-config.txt to config/
      config.txt: move difftool.* to a separate file
      config.txt: move fastimport.* to a separate file
      config.txt: move fetch-config.txt to config/
      config.txt: move filter.* to a separate file
      config.txt: move format-config.txt to config/
      config.txt: move fmt-merge-msg-config.txt to config/
      config.txt: move fsck.* to a separate file
      config.txt: move gc.* to a separate file
      config.txt: move gitcvs-config.txt to config/
      config.txt: move gitweb.* to a separate file
      config.txt: move grep.* to a separate file
      config.txt: move gpg.* to a separate file
      config.txt: move gui-config.txt to config/
      config.txt: move guitool.* to a separate file
      config.txt: move help.* to a separate file
      config.txt: move ssh.* to a separate file
      config.txt: move http.* to a separate file
      config.txt: move i18n.* to a separate file
      git-imap-send.txt: move imap.* to a separate file
      config.txt: move index.* to a separate file
      config.txt: move init.* to a separate file
      config.txt: move instaweb.* to a separate file
      config.txt: move interactive.* to a separate file
      config.txt: move log.* to a separate file
      config.txt: move mailinfo.* to a separate file
      config.txt: move mailmap.* to a separate file
      config.txt: move man.* to a separate file
      config.txt: move merge-config.txt to config/
      config.txt: move mergetool.* to a separate file
      config.txt: move notes.* to a separate file
      config.txt: move pack.* to a separate file
      config.txt: move pager.* to a separate file
      config.txt: move pretty.* to a separate file
      config.txt: move protocol.* to a separate file
      config.txt: move pull-config.txt to config/
      config.txt: move push-config.txt to config/
      config.txt: move rebase-config.txt to config/
      config.txt: move receive-config.txt to config/
      config.txt: move remote.* to a separate file
      config.txt: move remotes.* to a separate file
      config.txt: move repack.* to a separate file
      config.txt: move rerere.* to a separate file
      config.txt: move reset.* to a separate file
      config.txt: move sendemail-config.txt to config/
      config.txt: move sequencer.* to a separate file
      config.txt: move showBranch.* to a separate file
      config.txt: move splitIndex.* to a separate file
      config.txt: move status.* to a separate file
      config.txt: move stash.* to a separate file
      config.txt: move submodule.* to a separate file
      config.txt: move tag.* to a separate file
      config.txt: move transfer.* to a separate file
      config.txt: move uploadarchive.* to a separate file
      config.txt: move uploadpack.* to a separate file
      config.txt: move url.* to a separate file
      config.txt: move user.* to a separate file
      config.txt: move versionsort.* to a separate file
      config.txt: move web.* to a separate file
      config.txt: move worktree.* to a separate file
      config.txt: remove config/dummy.txt
      thread-utils: macros to unconditionally compile pthreads API
      wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode
      git-worktree.txt: correct linkgit command name
      sequencer.c: remove a stray semicolon
      tree-walk.c: fix overoptimistic inclusion in :(exclude) matching
      run-command.h: include thread-utils.h instead of pthread.h
      send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c
      index-pack: remove #ifdef NO_PTHREADS
      name-hash.c: remove #ifdef NO_PTHREADS
      attr.c: remove #ifdef NO_PTHREADS
      grep: remove #ifdef NO_PTHREADS
      grep: clean up num_threads handling
      preload-index.c: remove #ifdef NO_PTHREADS
      pack-objects: remove #ifdef NO_PTHREADS
      read-cache.c: remove #ifdef NO_PTHREADS
      read-cache.c: reduce branching based on HAVE_THREADS
      read-cache.c: initialize copy_len to shut up gcc 8
      Clean up pthread_create() error handling
      completion: use __gitcomp_builtin for format-patch
      build: fix broken command-list.h generation with core.autocrlf
      format-patch: respect --stat in cover letter's diffstat
      doc: move extensions.worktreeConfig to the right place
      clone: fix colliding file detection on APFS
      files-backend.c: fix build error on Solaris
      transport-helper.c: do not translate a string twice

Nickolai Belakovski (2):
      worktree: update documentation for lock_reason and lock_reason_valid
      worktree: rename is_worktree_locked to worktree_lock_reason

Noam Postavsky (1):
      log: fix coloring of certain octopus merge shapes

Olga Telezhnaya (3):
      ref-filter: free memory from used_atom
      ls-remote: release memory instead of UNLEAK
      ref-filter: free item->value and item->value->s

Peter Krefting (2):
      l10n: sv.po: Update Swedish translation (4185t0f0u)
      l10n: sv.po: Update Swedish translation (4187t0f0u)

Phillip Wood (11):
      diff: fix --color-moved-ws=allow-indentation-change
      diff --color-moved-ws: fix double free crash
      diff --color-moved-ws: fix out of bounds string access
      diff --color-moved-ws: fix a memory leak
      diff --color-moved-ws: fix another memory leak
      diff --color-moved: fix a memory leak
      am: don't die in read_author_script()
      am: improve author-script error reporting
      am: rename read_author_script()
      add read_author_script() to libgit
      sequencer: use read_author_script()

Pratik Karki (46):
      rebase: start implementing it as a builtin
      rebase: refactor common shell functions into their own file
      builtin/rebase: support running "git rebase <upstream>"
      builtin rebase: support --onto
      builtin rebase: support `git rebase --onto A...B`
      builtin rebase: handle the pre-rebase hook and --no-verify
      builtin rebase: support --quiet
      builtin rebase: support the `verbose` and `diffstat` options
      builtin rebase: require a clean worktree
      builtin rebase: try to fast forward when possible
      builtin rebase: support --force-rebase
      builtin rebase: start a new rebase only if none is in progress
      builtin rebase: only store fully-qualified refs in `options.head_name`
      builtin rebase: support `git rebase <upstream> <switch-to>`
      builtin rebase: support --continue
      builtin rebase: support --skip
      builtin rebase: support --abort
      builtin rebase: support --quit
      builtin rebase: support --edit-todo and --show-current-patch
      builtin rebase: actions require a rebase in progress
      builtin rebase: stop if `git am` is in progress
      builtin rebase: allow selecting the rebase "backend"
      builtin rebase: support --signoff
      builtin rebase: support --rerere-autoupdate
      builtin rebase: support --committer-date-is-author-date
      builtin rebase: support `ignore-whitespace` option
      builtin rebase: support `ignore-date` option
      builtin rebase: support `keep-empty` option
      builtin rebase: support `--autosquash`
      builtin rebase: support `--gpg-sign` option
      builtin rebase: support `-C` and `--whitespace=<type>`
      builtin rebase: support `--autostash` option
      builtin rebase: support `--exec`
      builtin rebase: support `--allow-empty-message` option
      builtin rebase: support --rebase-merges[=[no-]rebase-cousins]
      merge-base --fork-point: extract libified function
      builtin rebase: support `fork-point` option
      builtin rebase: add support for custom merge strategies
      builtin rebase: support --root
      builtin rebase: optionally auto-detect the upstream
      builtin rebase: optionally pass custom reflogs to reset_head()
      builtin rebase: fast-forward to onto if it is a proper descendant
      builtin rebase: show progress when connected to a terminal
      builtin rebase: use no-op editor when interactive is "implied"
      builtin rebase: error out on incompatible option/mode combinations
      rebase: default to using the builtin rebase

Rafael Ascensão (2):
      refs: show --exclude failure with --branches/tags/remotes=glob
      refs: fix some exclude patterns being ignored

Ralf Thielow (5):
      git-rebase.sh: fix typos in error messages
      l10n: update German translation
      builtin/rebase.c: remove superfluous space in messages
      l10n: update German translation
      l10n: de.po: fix two messages

Ramsay Jones (12):
      Makefile: add a hdr-check target
      json-writer.h: add missing include (hdr-check)
      ewah/ewok_rlw.h: add missing include (hdr-check)
      refs/ref-cache.h: add missing declarations (hdr-check)
      refs/packed-backend.h: add missing declaration (hdr-check)
      refs/refs-internal.h: add missing declarations (hdr-check)
      midx.h: add missing forward declarations (hdr-check)
      delta-islands.h: add missing forward declarations (hdr-check)
      headers: normalize the spelling of some header guards
      fetch-object.h: add missing declaration (hdr-check)
      ewok_rlw.h: add missing 'inline' to function definition
      commit-reach.h: add missing declarations (hdr-check)

Rasmus Villemoes (6):
      help: redirect to aliased commands for "git cmd --help"
      git.c: handle_alias: prepend alias info when first argument is -h
      git-help.txt: document "git help cmd" vs "git cmd --help" for aliases
      Documentation/git-send-email.txt: style fixes
      send-email: only consider lines containing @ or <> for automatic Cc'ing
      send-email: also pick up cc addresses from -by trailers

René Scharfe (12):
      mailinfo: support format=flowed
      fsck: add a performance test for skipList
      fsck: use strbuf_getline() to read skiplist file
      fsck: use oidset instead of oid_array for skipList
      sequencer: use return value of oidset_insert()
      grep: add -r/--[no-]recursive
      fetch-pack: factor out is_unmatched_ref()
      fetch-pack: load tip_oids eagerly iff needed
      khash: factor out kh_release_*
      oidset: use khash
      oidset: uninline oidset_init()
      commit-reach: fix cast in compare_commits_by_gen()

Roger Strain (1):
      subtree: performance improvement for finding unexpected parent commits

SZEDER Gábor (20):
      t1404: increase core.packedRefsTimeout to avoid occasional test failure
      Documentation/git.txt: clarify that GIT_TRACE=/path appends
      t3701-add-interactive: tighten the check of trace output
      t1700-split-index: drop unnecessary 'grep'
      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
      t1700-split-index: document why FSMONITOR is disabled in this test script
      split-index: add tests to demonstrate the racy split index problem
      t1700-split-index: date back files to avoid racy situations
      split-index: count the number of deleted entries
      split-index: don't compare cached data of entries already marked for split index
      split-index: smudge and add racily clean cache entries to split index
      split-index: BUG() when cache entry refers to non-existing shared entry
      object_id.cocci: match only expressions of type 'struct object_id'
      test-lib: introduce the '-V' short option for '--verbose-log'
      travis-ci: install packages in 'ci/install-dependencies.sh'
      coccicheck: introduce 'pending' semantic patches
      ref-filter: don't look for objects when outside of a repository
      tests: send "bug in the test script" errors to the script's stderr
      test-lib-functions: make 'test_cmp_rev' more informative on failure
      t/lib-git-daemon: fix signal checking

Sam McKelvie (1):
      rev-parse: --show-superproject-working-tree should work during a merge

Saulius Gurklys (1):
      doc: fix small typo in git show-branch

Sebastian Staudt (1):
      travis-ci: no longer use containers

Shulhan (1):
      builtin/remote: quote remote name on error to display empty name

Stefan Beller (25):
      git-submodule.sh: align error reporting for update mode to use path
      git-submodule.sh: rename unused variables
      builtin/submodule--helper: factor out submodule updating
      builtin/submodule--helper: store update_clone information in a struct
      builtin/submodule--helper: factor out method to update a single submodule
      submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
      submodule--helper: introduce new update-module-mode helper
      test_decode_color: understand FAINT and ITALIC
      t3206: add color test for range-diff --dual-color
      diff.c: simplify caller of emit_line_0
      diff.c: reorder arguments for emit_line_ws_markup
      diff.c: add set_sign to emit_line_0
      diff: use emit_line_0 once per line
      diff.c: omit check for line prefix in emit_line_0
      diff.c: rewrite emit_line_0 more understandably
      diff.c: add --output-indicator-{new, old, context}
      range-diff: make use of different output indicators
      range-diff: indent special lines as context
      refs.c: migrate internal ref iteration to pass thru repository argument
      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
      string-list: remove unused function print_string_list
      strbuf.h: format according to coding guidelines
      diff.c: pass sign_index to emit_line_ws_markup
      submodule helper: convert relative URL to absolute URL if needed
      builtin/submodule--helper: remove debugging leftover tracing

Stephen P. Smith (10):
      wt-status.c: move has_unmerged earlier in the file
      wt-status: rename commitable to committable
      t7501: add test of "commit --dry-run --short"
      wt-status.c: set the committable flag in the collect phase
      roll wt_status_state into wt_status and populate in the collect phase
      t2000: rename and combine checkout clash tests
      t7509: cleanup description and filename
      t7502: rename commit test script to comply with naming convention
      t7500: rename commit tests script to comply with naming convention
      t7501: rename commit test to comply with naming convention

Steve Hoelzer (1):
      poll: use GetTickCount64() to avoid wrap-around issues

Steven Fernandez (1):
      git-completion.bash: add completion for stash list

Strain, Roger L (4):
      subtree: refactor split of a commit into standalone method
      subtree: make --ignore-joins pay attention to adds
      subtree: use commits before rejoins for splits
      subtree: improve decision on merges kept in split

Sven Strickroth (1):
      msvc: directly use MS version (_stricmp) of strcasecmp

Tao Qingyun (3):
      refs: docstring typo
      builtin/branch.c: remove useless branch_get
      branch: trivial style fix

Taylor Blau (4):
      transport.c: extract 'fill_alternate_refs_command'
      transport.c: introduce core.alternateRefsCommand
      transport.c: introduce core.alternateRefsPrefixes
      Documentation/config.txt: fix typo in core.alternateRefsCommand

Thomas Gummerer (17):
      rerere: unify error messages when read_cache fails
      rerere: lowercase error messages
      rerere: wrap paths in output in sq
      rerere: mark strings for translation
      rerere: add documentation for conflict normalization
      rerere: fix crash with files rerere can't handle
      rerere: only return whether a path has conflicts or not
      rerere: factor out handle_conflict function
      rerere: return strbuf from handle path
      rerere: teach rerere to handle nested conflicts
      rerere: recalculate conflict ID when unresolved conflict is committed
      rerere: mention caveat about unmatched conflict markers
      rerere: add note about files with existing conflict markers
      .gitattributes: add conflict-marker-size for relevant files
      linear-assignment: fix potential out of bounds memory access
      t5551: move setup code inside test_expect blocks
      t5551: compare sorted cookies files

Tim Schumacher (4):
      Documentation/Makefile: make manpage-base-url.xsl generation quieter
      alias: add support for aliases of an alias
      alias: show the call history when an alias is looping
      t0014: introduce an alias testing suite

Todd Zullinger (1):
      Documentation: build technical/multi-pack-index

Torsten Bögershausen (5):
      Make git_check_attr() a void function
      path.c: char is not (always) signed
      Upcast size_t variables to uintmax_t when printing
      remote-curl.c: xcurl_off_t is not portable (on 32 bit platfoms)
      t5601-99: Enable colliding file detection for MINGW

Trần Ngọc Quân (2):
      l10n: vi(4185t): Updated Vietnamese translation for v2.20.0
      l10n: vi(4187t): Updated Vietnamese translation for v2.20.0 rd3

Uwe Kleine-König (1):
      howto/using-merge-subtree: mention --allow-unrelated-histories

brian m. carlson (26):
      t: add test functions to translate hash-related values
      t0000: use hash translation table
      t0000: update tests for SHA-256
      t0002: abstract away SHA-1 specific constants
      t0064: make hash size independent
      t1006: make hash size independent
      t1400: switch hard-coded object ID to variable
      t1405: make hash size independent
      t1406: make hash-size independent
      t1407: make hash size independent
      editorconfig: provide editor settings for Git developers
      editorconfig: indicate settings should be kept in sync
      pack-bitmap-write: use GIT_MAX_RAWSZ for allocation
      builtin/repack: replace hard-coded constants
      builtin/mktree: remove hard-coded constant
      builtin/fetch-pack: remove constants with parse_oid_hex
      pack-revindex: express constants in terms of the_hash_algo
      packfile: express constants in terms of the_hash_algo
      refs/packed-backend: express constants using the_hash_algo
      upload-pack: express constants in terms of the_hash_algo
      transport: use parse_oid_hex instead of a constant
      tag: express constant in terms of the_hash_algo
      apply: replace hard-coded constants
      apply: rename new_sha1_prefix and old_sha1_prefix
      submodule: make zero-oid comparison hash function agnostic
      rerere: convert to use the_hash_algo

Ævar Arnfjörð Bjarmason (35):
      fetch: change "branch" to "reference" in --force -h output
      push tests: make use of unused $1 in test description
      push tests: use spaces in interpolated string
      fetch tests: add a test for clobbering tag behavior
      push doc: remove confusing mention of remote merger
      push doc: move mention of "tag <tag>" later in the prose
      push doc: correct lies about how push refspecs work
      fetch: document local ref updates with/without --force
      fetch: stop clobbering existing tags without --force
      fsck tests: setup of bogus commit object
      fsck tests: add a test for no skipList input
      fsck: document and test sorted skipList input
      fsck: document and test commented & empty line skipList input
      fsck: document that skipList input must be unabbreviated
      fsck: add a performance test
      fsck: support comments & empty lines in skipList
      commit-graph write: add progress output
      commit-graph verify: add progress output
      config doc: add missing list separator for checkout.optimizeNewBranch
      push doc: add spacing between two words
      fetch doc: correct grammar in --force docs
      gc: fix regression in 7b0f229222 impacting --quiet
      gc doc: mention the commit-graph in the intro
      pack-objects test: modernize style
      pack-objects tests: don't leave test .git corrupt at end
      index-pack tests: don't leave test repo dirty at end
      i18n: make GETTEXT_POISON a runtime option
      range-diff doc: add a section about output stability
      range-diff: fix regression in passing along diff options
      range-diff: make diff option behavior (e.g. --stat) consistent
      push: change needlessly ambiguous example in error
      rebase doc: document rebase.useBuiltin
      tests: add a special setup where rebase.useBuiltin is off
      read-cache: make the split index obey umask settings
      advice: don't pointlessly suggest --convert-graft-file

Đoàn Trần Công Danh (1):
      git-compat-util: prefer poll.h to sys/poll.h


^ permalink raw reply	[relevance 2%]

* Re: [PATCH] fetch: ensure submodule objects fetched
  2018-12-06 21:26 21% ` [PATCH] fetch: ensure submodule objects fetched Stefan Beller
@ 2018-12-09  1:57  4%   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-09  1:57 UTC (permalink / raw)
  To: Stefan Beller; +Cc: jonathantanmy, git

Stefan Beller <sbeller@google.com> writes:

> Currently when git-fetch is asked to recurse into submodules, it dispatches
> a plain "git-fetch -C <submodule-dir>" (with some submodule related options
> such as prefix and recusing strategy, but) without any information of the
> remote or the tip that should be fetched.
>
> But this default fetch is not sufficient, as a newly fetched commit in
> the superproject could point to a commit in the submodule that is not
> in the default refspec. This is common in workflows like Gerrit's.
> When fetching a Gerrit change under review (from refs/changes/??), the
> commits in that change likely point to submodule commits that have not
> been merged to a branch yet.
>
> Fetch a submodule object by id if the object that the superproject
> points to, cannot be found. For now this object is fetched from the
> 'origin' remote as we defer getting the default remote to a later patch.
>
> A list of new submodule commits are already generated in certain
> conditions (by check_for_new_submodule_commits()); this new feature
> invokes that function in more situations.
>
> The submodule checks were done only when a ref in the superproject
> changed, these checks were extended to also be performed when fetching
> into FETCH_HEAD for completeness, and add a test for that too.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>
> Thanks Jonathan for the review!
> So it looks like only the last patch needs some improvements,
> which is why I'd only resend the last patch here.
> Also note the test with interious superproject commits.

Sorry, can't parse the last sentence.

Anyway, will replace the last step with this.  Thanks.


^ permalink raw reply	[relevance 4%]

* Re: [PATCH 1/4] submodule update: add regression test with old style setups
  2018-12-07 23:54 25% ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
@ 2018-12-09  0:11  4%   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-09  0:11 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> As f178c13fda (Revert "Merge branch 'sb/submodule-core-worktree'",
> 2018-09-07) was produced shortly before a release, nobody asked for
> a regression test to be included. Add a regression test that makes sure
> that the invocation of `git submodule update` on old setups doesn't
> produce errors as pointed out in f178c13fda.
>
> The place to add such a regression test may look odd in t7412, but
> that is the best place as there we setup old style submodule setups
> explicitly.

Very good first step.  Thanks.

>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  t/t7412-submodule-absorbgitdirs.sh | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
> index ce74c12da2..1cfa150768 100755
> --- a/t/t7412-submodule-absorbgitdirs.sh
> +++ b/t/t7412-submodule-absorbgitdirs.sh
> @@ -75,7 +75,12 @@ test_expect_success 're-setup nested submodule' '
>  	GIT_WORK_TREE=../../../nested git -C sub1/.git/modules/nested config \
>  		core.worktree "../../../nested" &&
>  	# make sure this re-setup is correct
> -	git status --ignore-submodules=none
> +	git status --ignore-submodules=none &&
> +
> +	# also make sure this old setup does not regress
> +	git submodule update --init --recursive >out 2>err &&
> +	test_must_be_empty out &&
> +	test_must_be_empty err
>  '
>  
>  test_expect_success 'absorb the git dir in a nested submodule' '

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 4/4] submodule deinit: unset core.worktree
  2018-12-07 23:54 24% ` [PATCH 4/4] submodule deinit: unset core.worktree Stefan Beller
@ 2018-12-08  7:03  7%   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-08  7:03 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> This re-introduces 984cd77ddb (submodule deinit: unset core.worktree,
> 2018-06-18), which was reverted as part of f178c13fda (Revert "Merge
> branch 'sb/submodule-core-worktree'", 2018-09-07)
>
> The whole series was reverted as the offending commit e98317508c
> (submodule: ensure core.worktree is set after update, 2018-06-18)
> was relied on by other commits such as 984cd77ddb.
>
> Keep the offending commit reverted, but its functionality came back via
> 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17), such
> that we can reintroduce 984cd77ddb now.

None of the above three explains the most important thing directly,
so readers fail to grasp what the main theme of the three-patch
series is, without looking at the commits that were reverted
already.

Is the theme of the overall series to make sure core.worktree is set
to point at the working tree when submodule's working tree is
instantiated, and unset it when it is not?

2/4 was also explained (in the original) that it wants to unset and
did so when "move_head" gets called.  This one does the unset when a
submodule is deinited.  Are these the only two cases a submodule
loses its working tree?  If so, the log message for this step should
declare victory by ending with something like

	... as we covered the only other case in which a submodule
	loses its working tree in the earlier step (i.e. switching
	branches of top-level project to move to a commit that did
	not have the submodule), this makes the code always maintain
	core.worktree correctly unset when there is no working tree
	for a submodule.

Thanks.  I think I agree with what the series wants to do (if I read
what it wants to do correctly, that is).

> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  builtin/submodule--helper.c | 2 ++
>  t/lib-submodule-update.sh   | 2 +-
>  t/t7400-submodule-basic.sh  | 5 +++++
>  3 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index 31ac30cf2f..672b74db89 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -1131,6 +1131,8 @@ static void deinit_submodule(const char *path, const char *prefix,
>  		if (!(flags & OPT_QUIET))
>  			printf(format, displaypath);
>  
> +		submodule_unset_core_worktree(sub);
> +
>  		strbuf_release(&sb_rm);
>  	}
>  
> diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
> index 51d4555549..5b56b23166 100755
> --- a/t/lib-submodule-update.sh
> +++ b/t/lib-submodule-update.sh
> @@ -235,7 +235,7 @@ reset_work_tree_to_interested () {
>  	then
>  		mkdir -p submodule_update/.git/modules/sub1/modules &&
>  		cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2
> -		GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree
> +		# core.worktree is unset for sub2 as it is not checked out
>  	fi &&
>  	# indicate we are interested in the submodule:
>  	git -C submodule_update config submodule.sub1.url "bogus" &&
> diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
> index 76a7cb0af7..aba2d4d6ee 100755
> --- a/t/t7400-submodule-basic.sh
> +++ b/t/t7400-submodule-basic.sh
> @@ -984,6 +984,11 @@ test_expect_success 'submodule deinit should remove the whole submodule section
>  	rmdir init
>  '
>  
> +test_expect_success 'submodule deinit should unset core.worktree' '
> +	test_path_is_file .git/modules/example/config &&
> +	test_must_fail git config -f .git/modules/example/config core.worktree
> +'
> +
>  test_expect_success 'submodule deinit from subdirectory' '
>  	git submodule update --init &&
>  	git config submodule.example.foo bar &&

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree
  2018-12-07 23:54 18% ` [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree Stefan Beller
@ 2018-12-08  6:55  4%   ` Junio C Hamano
  2018-12-12 22:46  4%     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-12-08  6:55 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> Shortly after f178c13fda (Revert "Merge branch
> 'sb/submodule-core-worktree'", 2018-09-07), we had another series
> that implemented partially the same, ensuring that core.worktree was
> set in a checked out submodule, namely 74d4731da1 (submodule--helper:
> replace connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13)
>
> As the series 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c',
> 2018-09-17) has different goals than the reverted series 7e25437d35
> (Merge branch 'sb/submodule-core-worktree', 2018-07-18), I'd wanted to
> replay the series on top of it to reach the goal of having `core.worktree`
> correctly set when the submodules worktree is present, and unset when the
> worktree is not present.
>
> The replay resulted in a strange merge conflict highlighting that
> the BUG message was not changed in 74d4731da1 (submodule--helper:
> replace connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13).
>
> Fix the error message.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---

Unlike the step 2/4 I commented on, this does explain what this
wants to do and why, at least when looked from sideways.  Is the
above saying the same as the following two-liner?

	An ealier mistake while rebasing to produce 74d4731da1
	failed to update this BUG message.  Fix this.



>  builtin/submodule--helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index d38113a31a..31ac30cf2f 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -2045,7 +2045,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
>  	struct repository subrepo;
>  
>  	if (argc != 2)
> -		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
> +		BUG("submodule--helper ensure-core-worktree <path>");
>  
>  	path = argv[1];

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 2/4] submodule: unset core.worktree if no working tree is present
  2018-12-07 23:54 20% ` [PATCH 2/4] submodule: unset core.worktree if no working tree is present Stefan Beller
@ 2018-12-08  6:44  7%   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-12-08  6:44 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> This reintroduces 4fa4f90ccd (submodule: unset core.worktree if no working
> tree is present, 2018-06-12), which was reverted as part of f178c13fda
> (Revert "Merge branch 'sb/submodule-core-worktree'", 2018-09-07).
>
> 4fa4f90ccd was reverted as its followup commit was faulty, but without
> the accompanying change of the followup, we'd have an incomplete workflow
> of setting `core.worktree` again, when it is needed such as checking out
> a revision that contains a submodule.
>
> So re-introduce that commit as-is, focusing on fixing up the followup

I was hoping to hear (given what 0/4 claimed) a clearer explanation
of what this change wants to achieve, but that is lacking.

No need to grumble about an earlier work was that turned out to be
inappropriate for the codebase back then.  Repeatedly saying "this
is needed" without giving further explaining why it is so, or
anything like that, would help readers.

Just pretend that the ealier commits and their reversion never
happened, and further pretend that we are doing the best thing that
should happen to our codebase.  How would we explain this change,
what the problem it tries to solve and what the solution looks like
in the larger picture?

	When removing a working tree of a submodule (e.g. we may be
	switching back to an earlier commit in the superproject that
	did not have the submodule in question yet), we failed to
	unset core.worktree of the submodule's repository.  That
	caused this and that issues, exhibited by a few new tests
	this commit adds.

	Make sure that core.worktree gets unset so that a leftover
	setting won't cause these issues.

or something like that?  I am just guessing by looking at the old
commit's text, as the above two paragraphs and one sentence does not
say much.

> diff --git a/submodule.c b/submodule.c
> index 6415cc5580..d393e947e6 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1561,6 +1561,18 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
>  	return ret;
>  }
>  
> +void submodule_unset_core_worktree(const struct submodule *sub)
> +{
> +	char *config_path = xstrfmt("%s/modules/%s/config",
> +				    get_git_common_dir(), sub->name);
> +
> +	if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
> +		warning(_("Could not unset core.worktree setting in submodule '%s'"),
> +			  sub->path);
> +
> +	free(config_path);
> +}
> +
>  static const char *get_super_prefix_or_empty(void)
>  {
>  	const char *s = get_super_prefix();
> @@ -1726,6 +1738,8 @@ int submodule_move_head(const char *path,
>  
>  			if (is_empty_dir(path))
>  				rmdir_or_warn(path);
> +
> +			submodule_unset_core_worktree(sub);
>  		}
>  	}
>  out:
> diff --git a/submodule.h b/submodule.h
> index a680214c01..9e18e9b807 100644
> --- a/submodule.h
> +++ b/submodule.h
> @@ -131,6 +131,8 @@ int submodule_move_head(const char *path,
>  			const char *new_head,
>  			unsigned flags);
>  
> +void submodule_unset_core_worktree(const struct submodule *sub);
> +
>  /*
>   * Prepare the "env_array" parameter of a "struct child_process" for executing
>   * a submodule by clearing any repo-specific environment variables, but
> diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
> index 016391723c..51d4555549 100755
> --- a/t/lib-submodule-update.sh
> +++ b/t/lib-submodule-update.sh
> @@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() {
>  			git branch -t remove_sub1 origin/remove_sub1 &&
>  			$command remove_sub1 &&
>  			test_superproject_content origin/remove_sub1 &&
> -			! test -e sub1
> +			! test -e sub1 &&
> +			test_must_fail git config -f .git/modules/sub1/config core.worktree
>  		)
>  	'
>  	# ... absorbing a .git directory along the way.

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 0/4]
  2018-12-07 23:54  8% [PATCH 0/4] Stefan Beller
                   ` (3 preceding siblings ...)
  2018-12-07 23:54 24% ` [PATCH 4/4] submodule deinit: unset core.worktree Stefan Beller
@ 2018-12-08  5:57  2% ` Junio C Hamano
  2018-12-12 22:35  4%   ` Stefan Beller
  2018-12-14 23:59  9%   ` [PATCH 0/4] submodules: unset core.worktree when no working tree present Stefan Beller
  4 siblings, 2 replies; 200+ results
From: Junio C Hamano @ 2018-12-08  5:57 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> A couple days before the 2.19 release we had a bug report about
> broken submodules[1] and reverted[2] the commits leading up to them.
>
> The behavior of said bug fixed itself by taking a different approach[3],
> specifically by a weaker enforcement of having `core.worktree` set in a
> submodule [4].
>
> The revert [2] was overly broad as we neared the release, such that we wanted
> to rather keep the known buggy behavior of always having `core.worktree` set,
> rather than figuring out how to fix the new bug of having 'git submodule update'
> not working in old style repository setups.
>
> This series re-introduces those reverted patches, with no changes in code,
> but with drastically changed commit messages, as those focus on why it is safe
> to re-introduce them instead of explaining the desire for the change.

The above was a bit too cryptic for me to grok, so let me try
rephrasing to see if I got them all correctly.

 - three-patch series leading to 984cd77ddb were meant to fix some
   bug, but the series itself was buggy and caused problems; we got
   rid of them

 - the problem 984cd77ddb wanted to fix was fixed differently
   without reintroducing the problem three-patch series introduced.
   That fix is already with us since 4d6d6ef1fc.

 - now these three changes that were problematic in the past is
   resent without any update (other than that it has one preparatory
   patch to add tests).

Is that what is going on?  Obviously I am not getting "the other"
benefit we wanted to gain out of these three patches (because the
above description fails to explain what that is), other than to fix
the issue that was fixed by 4d6d6ef1fc.

Sorry for being puzzled...

> [1] https://public-inbox.org/git/2659750.rG6xLiZASK@twilight
> [2] f178c13fda (Revert "Merge branch 'sb/submodule-core-worktree'", 2018-09-07)
> [3] 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17)
> [4] 74d4731da1 (submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13)
>
> Stefan Beller (4):
>   submodule update: add regression test with old style setups
>   submodule: unset core.worktree if no working tree is present
>   submodule--helper: fix BUG message in ensure_core_worktree
>   submodule deinit: unset core.worktree
>
>  builtin/submodule--helper.c        |  4 +++-
>  submodule.c                        | 14 ++++++++++++++
>  submodule.h                        |  2 ++
>  t/lib-submodule-update.sh          |  5 +++--
>  t/t7400-submodule-basic.sh         |  5 +++++
>  t/t7412-submodule-absorbgitdirs.sh |  7 ++++++-
>  6 files changed, 33 insertions(+), 4 deletions(-)

^ permalink raw reply	[relevance 2%]

* Re: [wishlist] git submodule update --reset-hard
  2018-12-08  2:15  4%           ` Yaroslav Halchenko
@ 2018-12-08  4:21 29%             ` Yaroslav Halchenko
  2018-12-10 18:58  6%               ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Yaroslav Halchenko @ 2018-12-08  4:21 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 1215 bytes --]


On Fri, 07 Dec 2018, Yaroslav Halchenko wrote:


> On Fri, 07 Dec 2018, Stefan Beller wrote:
> > > the initial "git submodule update --reset-hard" is pretty much a
> > > crude workaround for some of those cases, so I would just go earlier in
> > > the history, and redo some things, whenever I could just drop or revert
> > > some selected set of commits.

> > That makes sense.
> > Do you want to give the implementation a try for the --reset-hard switch?

> ok, will do, thanks for the blessing ;-)

The patch is attached (please advise if should be done
differently) and also submitted as PR
https://github.com/git/git/pull/563

I guess it would need more tests.  Took me some time to figure out
why I was getting

	fatal: bad value for update parameter

after all my changes to the git-submodule.sh script after looking at an
example commit 42b491786260eb17d97ea9fb1c4b70075bca9523 which introduced
--merge to the update ;-)

-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

[-- Attachment #2: 0001-submodule-Add-reset-hard-option-for-git-submodule-up.patch --]
[-- Type: text/x-diff, Size: 8916 bytes --]

From 170296dc661b4bc3d942917ce27288df52ff650d Mon Sep 17 00:00:00 2001
From: Yaroslav Halchenko <debian@onerussian.com>
Date: Fri, 7 Dec 2018 21:28:29 -0500
Subject: [PATCH] submodule: Add --reset-hard option for git submodule update

This patch adds a --reset-hard option for the update command to hard
reset submodule(s) to the gitlink for the corresponding submodule in
the superproject.  This feature is desired e.g. to be able to discard
recent changes in the entire hierarchy of the submodules after running

   git reset --hard PREVIOUS_STATE

in the superproject which leaves submodules in their original state,
and

   git reset --hard --recurse-submodules PREVIOUS_STATE

would result in the submodules being checked into detached HEADs.

As in the original  git reset --hard  no checks or any kind of
safe-guards against jumping into some state which was never on the
current branch is done.

must_die_on_failure is not set to  yes to mimic behavior of a update
--checkout strategy, which would leave user with a non-clean state
immediately apparent via  git status  so an informed decision/actions
could be done manually.

Signed-off-by: Yaroslav Halchenko <debian@onerussian.com>
---
 Documentation/git-submodule.txt | 12 +++++++++++-
 Documentation/gitmodules.txt    |  4 ++--
 builtin/submodule--helper.c     |  3 ++-
 git-submodule.sh                | 10 +++++++++-
 submodule.c                     |  4 ++++
 submodule.h                     |  1 +
 t/t7406-submodule-update.sh     | 17 ++++++++++++++++-
 7 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index ba3c4df550..f90a42d265 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -124,7 +124,7 @@ If you really want to remove a submodule from the repository and commit
 that use linkgit:git-rm[1] instead. See linkgit:gitsubmodules[7] for removal
 options.
 
-update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--] [<path>...]::
+update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge|--reset-hard] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--] [<path>...]::
 +
 --
 Update the registered submodules to match what the superproject
@@ -358,6 +358,16 @@ the submodule itself.
 	If the key `submodule.$name.update` is set to `rebase`, this option is
 	implicit.
 
+--reset-hard::
+	This option is only valid for the update command.
+	Hard reset current state to the commit recorded in the	superproject.
+    If this option is given, the submodule's HEAD will not get detached
+    if it was not detached before. Note that, like with a regular
+    git reset --hard  no safe-guards are in place to prevent jumping
+    to a commit which was never part of the current branch.
+	If the key `submodule.$name.update` is set to `reset-hard`, this
+	option is implicit.
+
 --init::
 	This option is only valid for the update command.
 	Initialize all submodules for which "git submodule init" has not been
diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
index 312b6f9259..e085dbc01f 100644
--- a/Documentation/gitmodules.txt
+++ b/Documentation/gitmodules.txt
@@ -43,8 +43,8 @@ submodule.<name>.update::
 	command in the superproject. This is only used by `git
 	submodule init` to initialize the configuration variable of
 	the same name. Allowed values here are 'checkout', 'rebase',
-	'merge' or 'none'. See description of 'update' command in
-	linkgit:git-submodule[1] for their meaning. Note that the
+	'merge', 'reset-hard' or 'none'. See description of 'update' command
+	in linkgit:git-submodule[1] for their meaning. Note that the
 	'!command' form is intentionally ignored here for security
 	reasons.
 
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index d38113a31a..31d95c3cd6 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1481,6 +1481,7 @@ static void determine_submodule_update_strategy(struct repository *r,
 	if (just_cloned &&
 	    (out->type == SM_UPDATE_MERGE ||
 	     out->type == SM_UPDATE_REBASE ||
+	     out->type == SM_UPDATE_RESET_HARD ||
 	     out->type == SM_UPDATE_NONE))
 		out->type = SM_UPDATE_CHECKOUT;
 
@@ -1851,7 +1852,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
 			      "submodule boundaries")),
 		OPT_STRING(0, "update", &update,
 			   N_("string"),
-			   N_("rebase, merge, checkout or none")),
+			   N_("rebase, merge, checkout, reset-hard or none")),
 		OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"),
 			   N_("reference repository")),
 		OPT_BOOL(0, "dissociate", &suc.dissociate,
diff --git a/git-submodule.sh b/git-submodule.sh
index 5e608f8bad..b5d6fad983 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -9,7 +9,7 @@ USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <re
    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] init [--] [<path>...]
    or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
-   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
+   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase|--reset-hard] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
    or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
@@ -483,6 +483,9 @@ cmd_update()
 		-m|--merge)
 			update="merge"
 			;;
+		--reset-hard)
+			update="reset-hard"
+			;;
 		--recursive)
 			recursive=1
 			;;
@@ -621,6 +624,11 @@ cmd_update()
 				say_msg="$(eval_gettext "Submodule path '\$displaypath': merged in '\$sha1'")"
 				must_die_on_failure=yes
 				;;
+			reset-hard)
+				command="git reset --hard"
+				die_msg="$(eval_gettext "Unable to reset --hard to '\$sha1' in submodule path '\$displaypath'")"
+				say_msg="$(eval_gettext "Submodule path '\$displaypath': was reset --hard to '\$sha1'")"
+				;;
 			!*)
 				command="${update_module#!}"
 				die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$displaypath'")"
diff --git a/submodule.c b/submodule.c
index 6415cc5580..4580cf0944 100644
--- a/submodule.c
+++ b/submodule.c
@@ -373,6 +373,8 @@ enum submodule_update_type parse_submodule_update_type(const char *value)
 		return SM_UPDATE_REBASE;
 	else if (!strcmp(value, "merge"))
 		return SM_UPDATE_MERGE;
+	else if (!strcmp(value, "reset-hard"))
+		return SM_UPDATE_RESET_HARD;
 	else if (*value == '!')
 		return SM_UPDATE_COMMAND;
 	else
@@ -406,6 +408,8 @@ const char *submodule_strategy_to_string(const struct submodule_update_strategy
 		return "checkout";
 	case SM_UPDATE_MERGE:
 		return "merge";
+	case SM_UPDATE_RESET_HARD:
+		return "reset-hard";
 	case SM_UPDATE_REBASE:
 		return "rebase";
 	case SM_UPDATE_NONE:
diff --git a/submodule.h b/submodule.h
index a680214c01..f23ac4630e 100644
--- a/submodule.h
+++ b/submodule.h
@@ -29,6 +29,7 @@ enum submodule_update_type {
 	SM_UPDATE_CHECKOUT,
 	SM_UPDATE_REBASE,
 	SM_UPDATE_MERGE,
+	SM_UPDATE_RESET_HARD,
 	SM_UPDATE_NONE,
 	SM_UPDATE_COMMAND
 };
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index e87164aa8f..2e08e0047c 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -6,7 +6,8 @@
 test_description='Test updating submodules
 
 This test verifies that "git submodule update" detaches the HEAD of the
-submodule and "git submodule update --rebase/--merge" does not detach the HEAD.
+submodule and "git submodule update --rebase/--merge/--reset-hard" does
+not detach the HEAD.
 '
 
 . ./test-lib.sh
@@ -305,6 +306,20 @@ test_expect_success 'submodule update --merge staying on master' '
 	)
 '
 
+test_expect_success 'submodule update --reset-hard staying on master' '
+	(cd super/submodule &&
+	  git reset --hard HEAD~1
+	) &&
+	(cd super &&
+	 (cd submodule &&
+	  compare_head
+	 ) &&
+	 git submodule update --reset-hard submodule &&
+	 cd submodule &&
+	 compare_head
+	)
+'
+
 test_expect_success 'submodule update - rebase in .git/config' '
 	(cd super &&
 	 git config submodule.submodule.update rebase
-- 
2.20.0.rc2.8.g0a3bec4a1c.dirty


^ permalink raw reply related	[relevance 29%]

* Re: [wishlist] git submodule update --reset-hard
  2018-12-07 21:55  7%         ` Stefan Beller
@ 2018-12-08  2:15  4%           ` Yaroslav Halchenko
  2018-12-08  4:21 29%             ` Yaroslav Halchenko
  0 siblings, 1 reply; 200+ results
From: Yaroslav Halchenko @ 2018-12-08  2:15 UTC (permalink / raw)
  To: git


On Fri, 07 Dec 2018, Stefan Beller wrote:
> > the initial "git submodule update --reset-hard" is pretty much a
> > crude workaround for some of those cases, so I would just go earlier in
> > the history, and redo some things, whenever I could just drop or revert
> > some selected set of commits.

> That makes sense.
> Do you want to give the implementation a try for the --reset-hard switch?

ok, will do, thanks for the blessing ;-)

-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 4%]

* [PATCH 4/4] submodule deinit: unset core.worktree
  2018-12-07 23:54  8% [PATCH 0/4] Stefan Beller
                   ` (2 preceding siblings ...)
  2018-12-07 23:54 18% ` [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree Stefan Beller
@ 2018-12-07 23:54 24% ` Stefan Beller
  2018-12-08  7:03  7%   ` Junio C Hamano
  2018-12-08  5:57  2% ` [PATCH 0/4] Junio C Hamano
  4 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-07 23:54 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

This re-introduces 984cd77ddb (submodule deinit: unset core.worktree,
2018-06-18), which was reverted as part of f178c13fda (Revert "Merge
branch 'sb/submodule-core-worktree'", 2018-09-07)

The whole series was reverted as the offending commit e98317508c
(submodule: ensure core.worktree is set after update, 2018-06-18)
was relied on by other commits such as 984cd77ddb.

Keep the offending commit reverted, but its functionality came back via
4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17), such
that we can reintroduce 984cd77ddb now.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 2 ++
 t/lib-submodule-update.sh   | 2 +-
 t/t7400-submodule-basic.sh  | 5 +++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 31ac30cf2f..672b74db89 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1131,6 +1131,8 @@ static void deinit_submodule(const char *path, const char *prefix,
 		if (!(flags & OPT_QUIET))
 			printf(format, displaypath);
 
+		submodule_unset_core_worktree(sub);
+
 		strbuf_release(&sb_rm);
 	}
 
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 51d4555549..5b56b23166 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -235,7 +235,7 @@ reset_work_tree_to_interested () {
 	then
 		mkdir -p submodule_update/.git/modules/sub1/modules &&
 		cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2
-		GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree
+		# core.worktree is unset for sub2 as it is not checked out
 	fi &&
 	# indicate we are interested in the submodule:
 	git -C submodule_update config submodule.sub1.url "bogus" &&
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 76a7cb0af7..aba2d4d6ee 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -984,6 +984,11 @@ test_expect_success 'submodule deinit should remove the whole submodule section
 	rmdir init
 '
 
+test_expect_success 'submodule deinit should unset core.worktree' '
+	test_path_is_file .git/modules/example/config &&
+	test_must_fail git config -f .git/modules/example/config core.worktree
+'
+
 test_expect_success 'submodule deinit from subdirectory' '
 	git submodule update --init &&
 	git config submodule.example.foo bar &&
-- 
2.20.0.rc2.403.gdbc3b29805-goog


^ permalink raw reply related	[relevance 24%]

* [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree
  2018-12-07 23:54  8% [PATCH 0/4] Stefan Beller
  2018-12-07 23:54 25% ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
  2018-12-07 23:54 20% ` [PATCH 2/4] submodule: unset core.worktree if no working tree is present Stefan Beller
@ 2018-12-07 23:54 18% ` Stefan Beller
  2018-12-08  6:55  4%   ` Junio C Hamano
  2018-12-07 23:54 24% ` [PATCH 4/4] submodule deinit: unset core.worktree Stefan Beller
  2018-12-08  5:57  2% ` [PATCH 0/4] Junio C Hamano
  4 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-07 23:54 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

Shortly after f178c13fda (Revert "Merge branch
'sb/submodule-core-worktree'", 2018-09-07), we had another series
that implemented partially the same, ensuring that core.worktree was
set in a checked out submodule, namely 74d4731da1 (submodule--helper:
replace connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13)

As the series 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c',
2018-09-17) has different goals than the reverted series 7e25437d35
(Merge branch 'sb/submodule-core-worktree', 2018-07-18), I'd wanted to
replay the series on top of it to reach the goal of having `core.worktree`
correctly set when the submodules worktree is present, and unset when the
worktree is not present.

The replay resulted in a strange merge conflict highlighting that
the BUG message was not changed in 74d4731da1 (submodule--helper:
replace connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13).

Fix the error message.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index d38113a31a..31ac30cf2f 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2045,7 +2045,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
 	struct repository subrepo;
 
 	if (argc != 2)
-		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
+		BUG("submodule--helper ensure-core-worktree <path>");
 
 	path = argv[1];
 
-- 
2.20.0.rc2.403.gdbc3b29805-goog


^ permalink raw reply related	[relevance 18%]

* [PATCH 2/4] submodule: unset core.worktree if no working tree is present
  2018-12-07 23:54  8% [PATCH 0/4] Stefan Beller
  2018-12-07 23:54 25% ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
@ 2018-12-07 23:54 20% ` Stefan Beller
  2018-12-08  6:44  7%   ` Junio C Hamano
  2018-12-07 23:54 18% ` [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree Stefan Beller
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-07 23:54 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, Junio C Hamano

This reintroduces 4fa4f90ccd (submodule: unset core.worktree if no working
tree is present, 2018-06-12), which was reverted as part of f178c13fda
(Revert "Merge branch 'sb/submodule-core-worktree'", 2018-09-07).

4fa4f90ccd was reverted as its followup commit was faulty, but without
the accompanying change of the followup, we'd have an incomplete workflow
of setting `core.worktree` again, when it is needed such as checking out
a revision that contains a submodule.

So re-introduce that commit as-is, focusing on fixing up the followup

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c               | 14 ++++++++++++++
 submodule.h               |  2 ++
 t/lib-submodule-update.sh |  3 ++-
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/submodule.c b/submodule.c
index 6415cc5580..d393e947e6 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1561,6 +1561,18 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
 	return ret;
 }
 
+void submodule_unset_core_worktree(const struct submodule *sub)
+{
+	char *config_path = xstrfmt("%s/modules/%s/config",
+				    get_git_common_dir(), sub->name);
+
+	if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
+		warning(_("Could not unset core.worktree setting in submodule '%s'"),
+			  sub->path);
+
+	free(config_path);
+}
+
 static const char *get_super_prefix_or_empty(void)
 {
 	const char *s = get_super_prefix();
@@ -1726,6 +1738,8 @@ int submodule_move_head(const char *path,
 
 			if (is_empty_dir(path))
 				rmdir_or_warn(path);
+
+			submodule_unset_core_worktree(sub);
 		}
 	}
 out:
diff --git a/submodule.h b/submodule.h
index a680214c01..9e18e9b807 100644
--- a/submodule.h
+++ b/submodule.h
@@ -131,6 +131,8 @@ int submodule_move_head(const char *path,
 			const char *new_head,
 			unsigned flags);
 
+void submodule_unset_core_worktree(const struct submodule *sub);
+
 /*
  * Prepare the "env_array" parameter of a "struct child_process" for executing
  * a submodule by clearing any repo-specific environment variables, but
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 016391723c..51d4555549 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() {
 			git branch -t remove_sub1 origin/remove_sub1 &&
 			$command remove_sub1 &&
 			test_superproject_content origin/remove_sub1 &&
-			! test -e sub1
+			! test -e sub1 &&
+			test_must_fail git config -f .git/modules/sub1/config core.worktree
 		)
 	'
 	# ... absorbing a .git directory along the way.
-- 
2.20.0.rc2.403.gdbc3b29805-goog


^ permalink raw reply related	[relevance 20%]

* [PATCH 1/4] submodule update: add regression test with old style setups
  2018-12-07 23:54  8% [PATCH 0/4] Stefan Beller
@ 2018-12-07 23:54 25% ` Stefan Beller
  2018-12-09  0:11  4%   ` Junio C Hamano
  2018-12-07 23:54 20% ` [PATCH 2/4] submodule: unset core.worktree if no working tree is present Stefan Beller
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-07 23:54 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

As f178c13fda (Revert "Merge branch 'sb/submodule-core-worktree'",
2018-09-07) was produced shortly before a release, nobody asked for
a regression test to be included. Add a regression test that makes sure
that the invocation of `git submodule update` on old setups doesn't
produce errors as pointed out in f178c13fda.

The place to add such a regression test may look odd in t7412, but
that is the best place as there we setup old style submodule setups
explicitly.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 t/t7412-submodule-absorbgitdirs.sh | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
index ce74c12da2..1cfa150768 100755
--- a/t/t7412-submodule-absorbgitdirs.sh
+++ b/t/t7412-submodule-absorbgitdirs.sh
@@ -75,7 +75,12 @@ test_expect_success 're-setup nested submodule' '
 	GIT_WORK_TREE=../../../nested git -C sub1/.git/modules/nested config \
 		core.worktree "../../../nested" &&
 	# make sure this re-setup is correct
-	git status --ignore-submodules=none
+	git status --ignore-submodules=none &&
+
+	# also make sure this old setup does not regress
+	git submodule update --init --recursive >out 2>err &&
+	test_must_be_empty out &&
+	test_must_be_empty err
 '
 
 test_expect_success 'absorb the git dir in a nested submodule' '
-- 
2.20.0.rc2.403.gdbc3b29805-goog


^ permalink raw reply related	[relevance 25%]

* [PATCH 0/4]
@ 2018-12-07 23:54  8% Stefan Beller
  2018-12-07 23:54 25% ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
                   ` (4 more replies)
  0 siblings, 5 replies; 200+ results
From: Stefan Beller @ 2018-12-07 23:54 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

A couple days before the 2.19 release we had a bug report about
broken submodules[1] and reverted[2] the commits leading up to them.

The behavior of said bug fixed itself by taking a different approach[3],
specifically by a weaker enforcement of having `core.worktree` set in a
submodule [4].

The revert [2] was overly broad as we neared the release, such that we wanted
to rather keep the known buggy behavior of always having `core.worktree` set,
rather than figuring out how to fix the new bug of having 'git submodule update'
not working in old style repository setups.

This series re-introduces those reverted patches, with no changes in code,
but with drastically changed commit messages, as those focus on why it is safe
to re-introduce them instead of explaining the desire for the change.

[1] https://public-inbox.org/git/2659750.rG6xLiZASK@twilight
[2] f178c13fda (Revert "Merge branch 'sb/submodule-core-worktree'", 2018-09-07)
[3] 4d6d6ef1fc (Merge branch 'sb/submodule-update-in-c', 2018-09-17)
[4] 74d4731da1 (submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13)

Stefan Beller (4):
  submodule update: add regression test with old style setups
  submodule: unset core.worktree if no working tree is present
  submodule--helper: fix BUG message in ensure_core_worktree
  submodule deinit: unset core.worktree

 builtin/submodule--helper.c        |  4 +++-
 submodule.c                        | 14 ++++++++++++++
 submodule.h                        |  2 ++
 t/lib-submodule-update.sh          |  5 +++--
 t/t7400-submodule-basic.sh         |  5 +++++
 t/t7412-submodule-absorbgitdirs.sh |  7 ++++++-
 6 files changed, 33 insertions(+), 4 deletions(-)

-- 
2.20.0.rc2.403.gdbc3b29805-goog


^ permalink raw reply	[relevance 8%]

* Re: [wishlist] git submodule update --reset-hard
  2018-12-07  1:22  7%       ` Yaroslav Halchenko
@ 2018-12-07 21:55  7%         ` Stefan Beller
  2018-12-08  2:15  4%           ` Yaroslav Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-07 21:55 UTC (permalink / raw)
  To: Yaroslav Halchenko; +Cc: git

On Thu, Dec 6, 2018 at 5:23 PM Yaroslav Halchenko <yoh@onerussian.com> wrote:

> > There was a proposal to "re-attach HEAD" in the submodule, i.e.
> > if the branch branch points at the same commit, we don't need
> > a detached HEAD, but could go with the branch instead.
>
> if I got the idea right, if we are talking about any branch, it
> would also non-deterministic since who knows what left over branch(es)
> point to that commit.  Not sure if I would have used that ;)

I would think we'd rather want to have it deterministic, i.e. something like
1) record branch name of the submodule
2) update submodules HEAD to to superprojects gitlink
3) if recorded branch (1) matches the sha1 of detached HEAD,
  have HEAD point to the branch instead.

You notice a small inefficiency here as we write HEAD twice, so it
could be reworded as:
1) compare superprojects gitlink with the submodules branch
2a) if equal, set submodules HEAD to branch
2b) if unequal set HEAD to gitlink value, resulting in detached HEAD

Note that this idea of reattaching reflects the idea (a) below.


> > a) "stay on submodule branch (i.e. HEAD still points at $branch), and
> > reset --hard" such that the submodule has a clean index and at that $branch
> > or
> > b) "stay on submodule branch (i.e. HEAD still points at $branch), but $branch is
> >    set to the gitlink from the superproject, and then a reset --hard
> >    will have the worktree set to it as well.


> NB "gitlink" -- just now discovered the thing for me.  Thought it would be
> called a  subproject  echoing what git diff/log -p shows for submodule commits.

The terminology is messy:
The internal representation in Gits object model is a "gitlink" entry in a tree
object. Once we have a .gitmodules entry, we call it submodule.

The term 'subproject' is a historic artifact and will likely not be changed
in the diff output (or format-patch), because these diffs can be applied using
git-am for example. That makes the diff output effectively a transport
protocol, and changing protocols is hard if you have no versioning in them.

More in https://git-scm.com/docs/gitsubmodules (a rather recent new write
of a man page, going into concepts).

> > > right -- I meant the local changes and indeed reset --recurse-submodules
> > > indeed seems to recurse nicely.  Then the undesired effect remaining only
> > > the detached HEAD
>
> > For that we may want to revive discussions in
> > https://public-inbox.org/git/20170501180058.8063-5-sbeller@google.com/
>
> well, isn't that one requires a branch to be specified in .gitmodules?

Ah good point.

> >   git reset --hard --recursive=hard,keep-branch PREVIOUSPOINT
>
> 'keep-branch' (given aforementioned keeping the specified in .gitmodules
> branch) might be confusing.  Also what if a submodule already in a
> detached HEAD?  IMHO --recursive=hard, and just saying that it would do
> "reset --hard", is imho sufficient.  (that is why I like pure
> --reset hard   since it doesn't care and neither does anything to the
> branch)

For that we might want to first do the

  git submodule update --reset-hard

which runs reset --hard inside the submodule, no matter which
branch the submodule is on (if any) and resets to the given
superproject sha1.

See git-submodule.sh in git.git[1] in cmd_update.
We'd need to add a command line flag (`--reset-hard`
would be the obvious choice?) which would set the `update`
variable, which then is evaluated to what needs to be done in
the submodule, which in that case would be the hard reset.

https://github.com/git/git/blob/master/git-submodule.sh#L606

Once that is done we'd want to add a test case, presumably
in t/t7406-submodule-update.sh

> > > I would have asked for
>
> > >    git revert --recursive <commit>...
> > >    git rebase --recursive [-i] ...
>
> > > which I also frequently desire (could elaborate on the use cases etc).
>
> > These would be nice to have. It would be nice if you'd elaborate on the
> > use cases for future reference in the mailing list archive. :-)
>
> ok, will try to do so ;-) In summary: they are just a logical extension
> of git support for submodules for anyone actively working with
> submodules to keep entire tree in sync.  Then quite often the need for
> reverting a specific commit (which also has changes reflected in
> submodules) arises.  The same with rebase, especially to trim away some
> no longer desired changes reflected in submodules.
>
> the initial "git submodule update --reset-hard" is pretty much a
> crude workaround for some of those cases, so I would just go earlier in
> the history, and redo some things, whenever I could just drop or revert
> some selected set of commits.

That makes sense.
Do you want to give the implementation a try for the --reset-hard switch?

> ah... so it is only   submodule  command which has --recursive, and the
> rest have --recurse-submodules   when talking about recursing into
> submodules?

I don't think we were that cautious in development as it was done by
different people at different times. There is also just `--submodule` for
the diff family, for reference:
https://public-inbox.org/git/20180905225828.17782-1-sbeller@google.com/

^ permalink raw reply	[relevance 7%]

* Re: [wishlist] git submodule update --reset-hard
  2018-12-06 21:55  7%     ` Stefan Beller
@ 2018-12-07  1:22  7%       ` Yaroslav Halchenko
  2018-12-07 21:55  7%         ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Yaroslav Halchenko @ 2018-12-07  1:22 UTC (permalink / raw)
  To: git

Hi Stefan,

Thanks for the dialogue!  Replies are embedded below.

On Thu, 06 Dec 2018, Stefan Beller wrote:
> ...
> > > What if the branch differs from the sha1 recorded in the superproject?

> > git reset --hard  itself is an operation which should be done with some
> > level of competence in doing "the right thing" by calling it.  You
> > can hop branches even in current (without any submodules in question)
> > repository with it and cause as much chaos as you desire.

> Right.

> git reset --hard would the branch (as well as the working tree) to the
> given sha1, which is confusing as submodules get involved.

> The Right Thing as of now is the sha1 as found in the
> superprojects gitlink. But as that can be different from any branch
> in the submodule, we'd rather detach the HEAD to make it
> deterministic.

yeap, makes total sense to be the thing do that by default ;-)

> There was a proposal to "re-attach HEAD" in the submodule, i.e.
> if the branch branch points at the same commit, we don't need
> a detached HEAD, but could go with the branch instead.

if I got the idea right, if we are talking about any branch, it
would also non-deterministic since who knows what left over branch(es)
point to that commit.  Not sure if I would have used that ;)

> > If desired though, a number of prevention mechanisms could be in place (but
> > would require option(s) to overcome) to allow submodule to be reset --hard'ed
> > only when some conditions met (e.g. only to the commit which is among parent
> > commits path of the current branch).  This way wild hops would be prevented,
> > although you might still end up in some feature branch.  But since "reset
> > --hard" itself doesn't have any safe-guards, I do not really think they should
> > be implemented here either.

> So are you looking for
> a) "stay on submodule branch (i.e. HEAD still points at $branch), and
> reset --hard" such that the submodule has a clean index and at that $branch 
> or
> b) "stay on submodule branch (i.e. HEAD still points at $branch), but $branch is
>    set to the gitlink from the superproject, and then a reset --hard
>    will have the worktree set to it as well.

yes!

NB "gitlink" -- just now discovered the thing for me.  Thought it would be
called a  subproject  echoing what git diff/log -p shows for submodule commits.

> (a) is what the referenced submodule.repoLike option implements.

sounds like it indeed, thanks for spelling out

> I'd understand the desire for (b) as well, as it is a "real" hard reset on
> the superproject level, without detaching branches.

yeap

> > >   git reset --hard --recurse-submodules HEAD

> > it does indeed some trick(s) but not all seems to be the ones I desire:

> > 1. Seems to migrate submodule's .git directories into the top level
> > .git/modules

> Ah yes, that happens too. This will help once you want to git-rm
> a submodule and checkout states before and after.

yeap ;-) 

> > > undesirable in the sense of still having local changes (that is what
> > > the above reset with `--recurse` would fix) or changed the branch
> > > state? (i.e. is detached but was on a branch before?)

> > right -- I meant the local changes and indeed reset --recurse-submodules
> > indeed seems to recurse nicely.  Then the undesired effect remaining only
> > the detached HEAD

> For that we may want to revive discussions in
> https://public-inbox.org/git/20170501180058.8063-5-sbeller@google.com/

well, isn't that one requires a branch to be specified in .gitmodules?

> > > >   git submodule update --recursive

> > > > I would end up in the detached HEADs within submodules.

> > > > What I want is to retain current branch they are at (or may be possible
> > > > "were in"? reflog records might have that information)

> > > So something like

> > >   git submodule foreach --recursive git reset --hard

> > > ?

> > not quite  -- this would just kill all local changes within each submodule, not
> > to reset it to the desired state, which wouldn't be specified in such
> > invocation, and is only known to the repo containing it

> With this answer it sounds like you'd want (b) from above.

yeap

> > > You may be interested in
> > > https://public-inbox.org/git/20180927221603.148025-1-sbeller@google.com/
> > > which introduces a switch `submodule.repoLike [ = true]`, which
> > > when set would not detach HEAD in submodules.

> > Thanks! looks interesting -- was there more discussion/activity beyond those 5
> > posts in the thread?

> Unfortunately there was not.

pity

> > This feature might indeed come handy but if I got it right, it is somewhat
> > complimentary to just having submodule update --reset-hard .  E.g.  submodules
> > might be in different branches (if I am not tracking based on branch names), so
> > I would not want a recursive checkout with -b|-B.  But we would indeed benefit
> > from such functionality, since this difficulty of managing branches of
> > submodules I think would be elevated with it! (e.g. in one use case we probably
> > will end up with a few thousands of submodules, and at least 3 branches in each
> > which would need to be in sync, and typically you wouldn't want different
> > branches to be checked out in different submodules)

> > > Can you say more about the first question above:
> > > Would you typically have situations where the
> > > submodule branch is out of sync with the superproject
> > > and how do you deal with that?

> > typically I do not have anything out of sync.  My primary use-case is to
> > "cancel" recent changes in the entire tree of repositories.  I guess for
> > my use case, instead of needing two commands

> >    git reset --hard PREVIOUSPOINT
> >    git submodule update --reset--hard --recursive

> > I wish there was just one

> >    git reset --hard --recursive PREVIOUSPOINT

> Maybe this could learn options like

>   git reset --hard --recursive=hard,keep-branch PREVIOUSPOINT

'keep-branch' (given aforementioned keeping the specified in .gitmodules
branch) might be confusing.  Also what if a submodule already in a
detached HEAD?  IMHO --recursive=hard, and just saying that it would do
"reset --hard", is imho sufficient.  (that is why I like pure
--reset hard   since it doesn't care and neither does anything to the
branch)

> which then could be put into options like

>   git config reset.recurseSubmodules  hard,keep-branch &&
>   # maybe not needed, depending on the exact meaning
>   # of reset.recurseSubmodules:
>   git config submodule.recurse

> and then

>   git reset --hard PREVIOUS

> would do what you'd desire.

you mean

   git reset --hard --recurse-submodules PREVIOUS

in principle overall I would love to have it, besides not sure what
other than 'hard' could be there, and what 'keep-branch' would exactly
do ;-)

> > but I felt that   submodule update   might be a better starting point
> > since it already  provides different modes for update.  If I was even greedier,
> > I would have asked for

> >    git revert --recursive <commit>...
> >    git rebase --recursive [-i] ...

> > which I also frequently desire (could elaborate on the use cases etc).

> These would be nice to have. It would be nice if you'd elaborate on the
> use cases for future reference in the mailing list archive. :-)

ok, will try to do so ;-) In summary: they are just a logical extension
of git support for submodules for anyone actively working with
submodules to keep entire tree in sync.  Then quite often the need for
reverting a specific commit (which also has changes reflected in
submodules) arises.  The same with rebase, especially to trim away some
no longer desired changes reflected in submodules.  

the initial "git submodule update --reset-hard" is pretty much a
crude workaround for some of those cases, so I would just go earlier in
the history, and redo some things, whenever I could just drop or revert
some selected set of commits.

> > NB or --recurse-submodules to avoid confusion with recursive merge
> > strategy?

> ... and sometimes recursing in the file system, c.f. `ls-tree -r`.

ah... so it is only   submodule  command which has --recursive, and the
rest have --recurse-submodules   when talking about recursing into
submodules?

-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 7%]

* Re: [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (8 preceding siblings ...)
  2018-12-05  3:10  7% ` [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Junio C Hamano
@ 2018-12-07  0:25  6% ` Josh Steadmon
  9 siblings, 0 replies; 200+ results
From: Josh Steadmon @ 2018-12-07  0:25 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, jonathantanmy

On 2018.11.28 16:27, Stefan Beller wrote:
> This is a resend of sb/submodule-recursive-fetch-gets-the-tip,
> with all feedback addressed. As it took some time, I'll send it
> without range-diff, but would ask for full review.
> 
> I plan on resending after the next release as this got delayed quite a bit,
> which is why I also rebased it to master.
> 
> Thanks,
> Stefan

I am not very familiar with most of the submodule code, but for what
it's worth, this entire series looks good to me. I'll note that most of
the commits caused some style complaints, but I'll leave it up to your
judgement as to whether they're valid or not.

Reviewed-by: Josh Steadmon <steadmon@google.com>

^ permalink raw reply	[relevance 6%]

* Re: git, monorepos, and access control
  @ 2018-12-06 22:15  5%     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-06 22:15 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Jeff King, John.Coiner, git

On Thu, Dec 6, 2018 at 12:09 PM Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
>
> Hi,
>
> On Wed, 5 Dec 2018, Jeff King wrote:
>
> > The model that fits more naturally with how Git is implemented would be
> > to use submodules. There you leak the hash of the commit from the
> > private submodule, but that's probably obscure enough (and if you're
> > really worried, you can add a random nonce to the commit messages in the
> > submodule to make their hashes unguessable).
>
> I hear myself frequently saying: "Friends don't let friends use
> submodules". It's almost like: "Some people think their problem is solved
> by using submodules. Only now they have two problems."

Blaming tools for their lack of evolution/development is not necessarily the
right approach. I recall having patches rejected on this very mailing list
that fixed obvious but minor good things like whitespaces and coding style,
because it *might* produce merge conflicts. Would that situation warrant me
to blame the lacks in the merge algorithm, or could you imagine a better
way out? (No need to answer, it's purely to demonstrate that blaming
tooling is not always the right approach; only sometimes it may be)

> There are big reasons, after all, why some companies go for monorepos: it
> is not for lack of trying to go with submodules, it is the problems that
> were incurred by trying to treat entire repositories the same as single
> files (or even trees): they are just too different.

We could change that in more places.

One example you might think of is the output of git-status that displays
changed files. And in case of submodules it would just show
"submodule changes", which we already differentiate into "dirty tree" and
"different sha1 at HEAD".
Instead we could have the output of all changed files recursively in the
superprojects git-status output.

Another example is the diff machinery, which already knows some
basics such as embedding submodule logs or actual diffs.

> In a previous life, I also tried to go for submodules, was burned, and had
> to restart the whole thing. We ended up with something that might work in
> this instance, too, although our use case was not need-to-know type of
> encapsulation. What we went for was straight up modularization.

So this is a "Fix the data instead of the tool", which seems to be a local
optimization (i.e. you only have to do it once, such that it is cheaper to
do than fixing the tool for that workgroup)
... and because everyone does that the tool never gets fixed.

> What I mean is that we split the project up into over 100 individual
> projects that are now all maintained in individual repositories, and they
> are connected completely outside of Git, via a dependency management
> system (in this case, Maven, although that is probably too Java-centric
> for AMD's needs).

Once you have the dependency management system in place, you
will encounter the rare case of still wanting to change things across
repository boundaries at the same time. Submodules offer that, which
is why Android wants to migrate off of the repo tool, and there it seems
natural to go for submodules.

> I just wanted to throw that out here: if you can split up your project
> into individual projects, it might make sense not to maintain them as
> submodules but instead as individual repositories whose artifacts are
> uploaded into a central, versioned artifact store (Maven, NuGet, etc). And
> those artifacts would then be retrieved by the projects that need them.

This is cool and industry standard. But once you happen to run in a bug
that involves 2 new artifacts (but each of the new artifacts work fine
on their own), then you'd wish for something like "git-bisect but across
repositories". Submodules (in theory) allow for fine grained bisection
across these repository boundaries, I would think.

> I figure that that scheme might work for you better than submodules: I
> could imagine that you need to make the build artifacts available even to
> people who are not permitted to look at the corresponding source code,
> anyway.

This is a sensible suggestion, as they probably don't want to ramp up
development on submodules. :-)

^ permalink raw reply	[relevance 5%]

* Re: [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip
  2018-12-05  3:10  7% ` [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Junio C Hamano
@ 2018-12-06 21:59  4%   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-12-06 21:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jonathan Tan

On Tue, Dec 4, 2018 at 7:10 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > This is a resend of sb/submodule-recursive-fetch-gets-the-tip,
> > with all feedback addressed. As it took some time, I'll send it
> > without range-diff, but would ask for full review.
>
> Is that a "resend" or reroll/update (or whatever word that does not
> imply "just sending the same thing again")?

As you noticed, it is an actual update. I started to use resend
as DScho seems very unhappy about the word reroll claiming we'd
be the only Software community that uses the term reroll for
an iteration of a change.

I see how resend could sound like retransmission without change.


>                         child_process_init(cp);
>      -                  cp->dir = strbuf_detach(&submodule_path, NULL);
>     -                   prepare_submodule_repo_env(&cp->env_array);
>      +                  cp->dir = xstrdup(repo->worktree);
>     +                   prepare_submodule_repo_env(&cp->env_array);
>
> Hmph, I offhand do not see there would be any difference if you
> assigned to cp->dir before or after preparing the repo env, but is
> there a reason these two must be done in this updated order that I
> am missing?  Very similar changes appear multiple times in this
> range-diff.

Jonathan Tan asked for it to be "diff friendly". This -of course- is
range-diff unfriendly.

> [...]

you seem to be OK with a lot of the changes, I did not find an
actionable suggestion.

Thanks for still queuing topics during -rc time,
Stefan

^ permalink raw reply	[relevance 4%]

* Re: [wishlist] git submodule update --reset-hard
  2018-12-06 21:24  6%   ` Yaroslav Halchenko
@ 2018-12-06 21:55  7%     ` Stefan Beller
  2018-12-07  1:22  7%       ` Yaroslav Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-06 21:55 UTC (permalink / raw)
  To: Yaroslav Halchenko; +Cc: git

On Thu, Dec 6, 2018 at 1:25 PM Yaroslav Halchenko <yoh@onerussian.com> wrote:
>
>
> On Thu, 06 Dec 2018, Stefan Beller wrote:
>
> > On Thu, Dec 6, 2018 at 10:02 AM Yaroslav Halchenko <yoh@onerussian.com> wrote:
>
> > > Dear Git Gurus,
>
> > > I wondered what would be your take on my wishlist request to add
> > > --reset-hard option, which would be very similar to regular "update" which
> > > checks out necessary commit, but I want it to remain in the branch.
>
> > What if the branch differs from the sha1 recorded in the superproject?
>
> git reset --hard  itself is an operation which should be done with some
> level of competence in doing "the right thing" by calling it.  You
> can hop branches even in current (without any submodules in question)
> repository with it and cause as much chaos as you desire.

Right.

git reset --hard would the branch (as well as the working tree) to the
given sha1, which is confusing as submodules get involved.

The Right Thing as of now is the sha1 as found in the
superprojects gitlink. But as that can be different from any branch
in the submodule, we'd rather detach the HEAD to make it
deterministic.

There was a proposal to "re-attach HEAD" in the submodule, i.e.
if the branch branch points at the same commit, we don't need
a detached HEAD, but could go with the branch instead.

> If desired though, a number of prevention mechanisms could be in place (but
> would require option(s) to overcome) to allow submodule to be reset --hard'ed
> only when some conditions met (e.g. only to the commit which is among parent
> commits path of the current branch).  This way wild hops would be prevented,
> although you might still end up in some feature branch.  But since "reset
> --hard" itself doesn't have any safe-guards, I do not really think they should
> be implemented here either.

So are you looking for
a) "stay on submodule branch (i.e. HEAD still points at $branch), and
reset --hard"
    such that the submodule has a clean index and at that $branch or
b) "stay on submodule branch (i.e. HEAD still points at $branch), but $branch is
   set to the gitlink from the superproject, and then a reset --hard
will have the worktree
   set to it as well.

(a) is what the referenced submodule.repoLike option implements.

I'd understand the desire for (b) as well, as it is a "real" hard reset on
the superproject level, without detaching branches.

> >   git reset --hard --recurse-submodules HEAD

> it does indeed some trick(s) but not all seems to be the ones I desire:
>
> 1. Seems to migrate submodule's .git directories into the top level
> .git/modules

Ah yes, that happens too. This will help once you want to git-rm
a submodule and checkout states before and after.

> > undesirable in the sense of still having local changes (that is what
> > the above reset with `--recurse` would fix) or changed the branch
> > state? (i.e. is detached but was on a branch before?)
>
> right -- I meant the local changes and indeed reset --recurse-submodules
> indeed seems to recurse nicely.  Then the undesired effect remaining only
> the detached HEAD

For that we may want to revive discussions in
https://public-inbox.org/git/20170501180058.8063-5-sbeller@google.com/


> > >   git submodule update --recursive
>
> > > I would end up in the detached HEADs within submodules.
>
> > > What I want is to retain current branch they are at (or may be possible
> > > "were in"? reflog records might have that information)
>
> > So something like
>
> >   git submodule foreach --recursive git reset --hard
>
> > ?
>
> not quite  -- this would just kill all local changes within each submodule, not
> to reset it to the desired state, which wouldn't be specified in such
> invocation, and is only known to the repo containing it

With this answer it sounds like you'd want (b) from above.

> > You may be interested in
> > https://public-inbox.org/git/20180927221603.148025-1-sbeller@google.com/
> > which introduces a switch `submodule.repoLike [ = true]`, which
> > when set would not detach HEAD in submodules.
>
> Thanks! looks interesting -- was there more discussion/activity beyond those 5
> posts in the thread?

Unfortunately there was not.

> This feature might indeed come handy but if I got it right, it is somewhat
> complimentary to just having submodule update --reset-hard .  E.g.  submodules
> might be in different branches (if I am not tracking based on branch names), so
> I would not want a recursive checkout with -b|-B.  But we would indeed benefit
> from such functionality, since this difficulty of managing branches of
> submodules I think would be elevated with it! (e.g. in one use case we probably
> will end up with a few thousands of submodules, and at least 3 branches in each
> which would need to be in sync, and typically you wouldn't want different
> branches to be checked out in different submodules)
>
> > Can you say more about the first question above:
> > Would you typically have situations where the
> > submodule branch is out of sync with the superproject
> > and how do you deal with that?
>
> typically I do not have anything out of sync.  My primary use-case is to
> "cancel" recent changes in the entire tree of repositories.  I guess for
> my use case, instead of needing two commands
>
>    git reset --hard PREVIOUSPOINT
>    git submodule update --reset--hard --recursive
>
> I wish there was just one
>
>    git reset --hard --recursive PREVIOUSPOINT

Maybe this could learn options like

  git reset --hard --recursive=hard,keep-branch PREVIOUSPOINT

which then could be put into options like

  git config reset.recurseSubmodules  hard,keep-branch &&
  # maybe not needed, depending on the exact meaning
  # of reset.recurseSubmodules:
  git config submodule.recurse

and then

  git reset --hard PREVIOUS

would do what you'd desire.

> but I felt that   submodule update   might be a better starting point
> since it already  provides different modes for update.  If I was even greedier,
> I would have asked for
>
>    git revert --recursive <commit>...
>    git rebase --recursive [-i] ...
>
> which I also frequently desire (could elaborate on the use cases etc).

These would be nice to have. It would be nice if you'd elaborate on the
use cases for future reference in the mailing list archive. :-)

>
> NB or --recurse-submodules to avoid confusion with recursive merge
> strategy?

... and sometimes recursing in the file system, c.f. `ls-tree -r`.

^ permalink raw reply	[relevance 7%]

* [PATCH] fetch: ensure submodule objects fetched
  @ 2018-12-06 21:26 21% ` Stefan Beller
  2018-12-09  1:57  4%   ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-06 21:26 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, sbeller

Currently when git-fetch is asked to recurse into submodules, it dispatches
a plain "git-fetch -C <submodule-dir>" (with some submodule related options
such as prefix and recusing strategy, but) without any information of the
remote or the tip that should be fetched.

But this default fetch is not sufficient, as a newly fetched commit in
the superproject could point to a commit in the submodule that is not
in the default refspec. This is common in workflows like Gerrit's.
When fetching a Gerrit change under review (from refs/changes/??), the
commits in that change likely point to submodule commits that have not
been merged to a branch yet.

Fetch a submodule object by id if the object that the superproject
points to, cannot be found. For now this object is fetched from the
'origin' remote as we defer getting the default remote to a later patch.

A list of new submodule commits are already generated in certain
conditions (by check_for_new_submodule_commits()); this new feature
invokes that function in more situations.

The submodule checks were done only when a ref in the superproject
changed, these checks were extended to also be performed when fetching
into FETCH_HEAD for completeness, and add a test for that too.

Signed-off-by: Stefan Beller <sbeller@google.com>
---

Thanks Jonathan for the review!
So it looks like only the last patch needs some improvements,
which is why I'd only resend the last patch here.
Also note the test with interious superproject commits.

All suggestions sounded sensible, addressing them all,
here is a range-diff to the currently queued version:

Range-diff:
1:  04eb06607b ! 1:  ac6558cbc9 fetch: try fetching submodules if needed objects were not fetched
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    fetch: try fetching submodules if needed objects were not fetched
    +    fetch: ensure submodule objects fetched
     
         Currently when git-fetch is asked to recurse into submodules, it dispatches
         a plain "git-fetch -C <submodule-dir>" (with some submodule related options
    @@ -14,22 +14,19 @@
         commits in that change likely point to submodule commits that have not
         been merged to a branch yet.
     
    -    Try fetching a submodule by object id if the object id that the
    -    superproject points to, cannot be found.
    +    Fetch a submodule object by id if the object that the superproject
    +    points to, cannot be found. For now this object is fetched from the
    +    'origin' remote as we defer getting the default remote to a later patch.
     
    -    builtin/fetch used to only inspect submodules when they were fetched
    -    "on-demand", as in either on/off case it was clear whether the submodule
    -    needs to be fetched. However to know whether we need to try fetching the
    -    object ids, we need to identify the object names, which is done in this
    -    function check_for_new_submodule_commits(), so we'll also run that code
    -    in case the submodule recursion is set to "on".
    +    A list of new submodule commits are already generated in certain
    +    conditions (by check_for_new_submodule_commits()); this new feature
    +    invokes that function in more situations.
     
         The submodule checks were done only when a ref in the superproject
         changed, these checks were extended to also be performed when fetching
         into FETCH_HEAD for completeness, and add a test for that too.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/builtin/fetch.c b/builtin/fetch.c
      --- a/builtin/fetch.c
    @@ -82,7 +79,7 @@
      
      	struct string_list changed_submodule_names;
     +
    -+	/* The submodules to fetch in */
    ++	/* Pending fetches by OIDs */
     +	struct fetch_task **oid_fetch_tasks;
     +	int oid_fetch_tasks_nr, oid_fetch_tasks_alloc;
      };
    @@ -97,13 +94,16 @@
      	return spf->default_option;
      }
      
    ++/*
    ++ * Fetch in progress (if callback data) or
    ++ * pending (if in oid_fetch_tasks in struct submodule_parallel_fetch)
    ++ */
     +struct fetch_task {
     +	struct repository *repo;
     +	const struct submodule *sub;
     +	unsigned free_sub : 1; /* Do we need to free the submodule? */
     +
    -+	/* fetch specific oids if set, otherwise fetch default refspec */
    -+	struct oid_array *commits;
    ++	struct oid_array *commits; /* Ensure these commits are fetched */
     +};
     +
     +/**
    @@ -176,7 +176,6 @@
      
      	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
     -		struct strbuf submodule_prefix = STRBUF_INIT;
    -+		int recurse_config;
      		const struct cache_entry *ce = spf->r->index->cache[spf->count];
      		const char *default_argv;
     -		const struct submodule *submodule;
    @@ -199,11 +198,9 @@
     +		task = fetch_task_create(spf->r, ce->name);
     +		if (!task)
     +			continue;
    -+
    -+		recurse_config = get_fetch_recurse_config(task->sub, spf);
      
     -		switch (get_fetch_recurse_config(submodule, spf))
    -+		switch (recurse_config)
    ++		switch (get_fetch_recurse_config(task->sub, spf))
      		{
      		default:
      		case RECURSE_SUBMODULES_DEFAULT:
    @@ -314,7 +311,7 @@
      	return 0;
      }
      
    -+static int commit_exists_in_sub(const struct object_id *oid, void *data)
    ++static int commit_missing_in_sub(const struct object_id *oid, void *data)
     +{
     +	struct repository *subrepo = data;
     +
    @@ -340,7 +337,7 @@
     +
     +	/* Is this the second time we process this submodule? */
     +	if (task->commits)
    -+		return 0;
    ++		goto out;
     +
     +	it = string_list_lookup(&spf->changed_submodule_names, task->sub->name);
     +	if (!it)
    @@ -349,7 +346,7 @@
     +
     +	commits = it->util;
     +	oid_array_filter(commits,
    -+			 commit_exists_in_sub,
    ++			 commit_missing_in_sub,
     +			 task->repo);
     +
     +	/* Are there commits we want, but do not exist? */
    @@ -408,7 +405,7 @@
     +	)
     +'
     +
    -+test_expect_success 'fetch new submodule commits on-demand in FETCH_HEAD' '
    ++test_expect_success 'fetch new submodule commit on-demand in FETCH_HEAD' '
     +	# depends on the previous test for setup
     +
     +	C=$(git -C submodule commit-tree -m "another change outside refs/heads" HEAD^{tree}) &&
    @@ -462,5 +459,36 @@
     +		git checkout --recurse-submodules FETCH_HEAD
     +	)
     +'
    ++
    ++test_expect_success 'fetch new submodule commit intermittently referenced by superproject' '
    ++	# depends on the previous test for setup
    ++
    ++	D=$(git -C sub1 commit-tree -m "change 10 outside refs/heads" HEAD^{tree}) &&
    ++	E=$(git -C sub1 commit-tree -m "change 11 outside refs/heads" HEAD^{tree}) &&
    ++	F=$(git -C sub1 commit-tree -m "change 12 outside refs/heads" HEAD^{tree}) &&
    ++
    ++	git -C sub1 update-ref refs/changes/10 $D &&
    ++	git update-index --cacheinfo 160000 $D sub1 &&
    ++	git commit -m "updated submodules outside of refs/heads" &&
    ++
    ++	git -C sub1 update-ref refs/changes/11 $E &&
    ++	git update-index --cacheinfo 160000 $E sub1 &&
    ++	git commit -m "updated submodules outside of refs/heads" &&
    ++
    ++	git -C sub1 update-ref refs/changes/12 $F &&
    ++	git update-index --cacheinfo 160000 $F sub1 &&
    ++	git commit -m "updated submodules outside of refs/heads" &&
    ++
    ++	G=$(git rev-parse HEAD) &&
    ++	git update-ref refs/changes/13 $G &&
    ++	(
    ++		cd downstream &&
    ++		git fetch --recurse-submodules origin refs/changes/13 &&
    ++
    ++		git -C sub1 cat-file -t $D &&
    ++		git -C sub1 cat-file -t $E &&
    ++		git -C sub1 cat-file -t $F
    ++	)
    ++'
     +
      test_done

 builtin/fetch.c             |  11 +-
 submodule.c                 | 206 +++++++++++++++++++++++++++++++-----
 t/t5526-fetch-submodules.sh | 117 ++++++++++++++++++++
 3 files changed, 296 insertions(+), 38 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index e0140327aa..91f9b7d9c8 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -763,9 +763,6 @@ static int update_local_ref(struct ref *ref,
 			what = _("[new ref]");
 		}
 
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
-			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref(msg, ref, 0);
 		format_display(display, r ? '!' : '*', what,
 			       r ? _("unable to update local ref") : NULL,
@@ -779,9 +776,6 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "..");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
-			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("fast-forward", ref, 1);
 		format_display(display, r ? '!' : ' ', quickref.buf,
 			       r ? _("unable to update local ref") : NULL,
@@ -794,9 +788,6 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "...");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
-			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("forced-update", ref, 1);
 		format_display(display, r ? '!' : '+', quickref.buf,
 			       r ? _("unable to update local ref") : _("forced update"),
@@ -892,6 +883,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 				ref->force = rm->peer_ref->force;
 			}
 
+			if (recurse_submodules != RECURSE_SUBMODULES_OFF)
+				check_for_new_submodule_commits(&rm->old_oid);
 
 			if (!strcmp(rm->name, "HEAD")) {
 				kind = "";
diff --git a/submodule.c b/submodule.c
index d1b6646f42..b88343d977 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1231,8 +1231,14 @@ struct submodule_parallel_fetch {
 	int result;
 
 	struct string_list changed_submodule_names;
+
+	/* Pending fetches by OIDs */
+	struct fetch_task **oid_fetch_tasks;
+	int oid_fetch_tasks_nr, oid_fetch_tasks_alloc;
 };
-#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \
+		  STRING_LIST_INIT_DUP, \
+		  NULL, 0, 0}
 
 static int get_fetch_recurse_config(const struct submodule *submodule,
 				    struct submodule_parallel_fetch *spf)
@@ -1259,6 +1265,76 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+/*
+ * Fetch in progress (if callback data) or
+ * pending (if in oid_fetch_tasks in struct submodule_parallel_fetch)
+ */
+struct fetch_task {
+	struct repository *repo;
+	const struct submodule *sub;
+	unsigned free_sub : 1; /* Do we need to free the submodule? */
+
+	struct oid_array *commits; /* Ensure these commits are fetched */
+};
+
+/**
+ * When a submodule is not defined in .gitmodules, we cannot access it
+ * via the regular submodule-config. Create a fake submodule, which we can
+ * work on.
+ */
+static const struct submodule *get_non_gitmodules_submodule(const char *path)
+{
+	struct submodule *ret = NULL;
+	const char *name = default_name_or_path(path);
+
+	if (!name)
+		return NULL;
+
+	ret = xmalloc(sizeof(*ret));
+	memset(ret, 0, sizeof(*ret));
+	ret->path = name;
+	ret->name = name;
+
+	return (const struct submodule *) ret;
+}
+
+static struct fetch_task *fetch_task_create(struct repository *r,
+					    const char *path)
+{
+	struct fetch_task *task = xmalloc(sizeof(*task));
+	memset(task, 0, sizeof(*task));
+
+	task->sub = submodule_from_path(r, &null_oid, path);
+	if (!task->sub) {
+		/*
+		 * No entry in .gitmodules? Technically not a submodule,
+		 * but historically we supported repositories that happen to be
+		 * in-place where a gitlink is. Keep supporting them.
+		 */
+		task->sub = get_non_gitmodules_submodule(path);
+		if (!task->sub) {
+			free(task);
+			return NULL;
+		}
+
+		task->free_sub = 1;
+	}
+
+	return task;
+}
+
+static void fetch_task_release(struct fetch_task *p)
+{
+	if (p->free_sub)
+		free((void*)p->sub);
+	p->free_sub = 0;
+	p->sub = NULL;
+
+	if (p->repo)
+		repo_clear(p->repo);
+	FREE_AND_NULL(p->repo);
+}
+
 static struct repository *get_submodule_repo_for(struct repository *r,
 						 const struct submodule *sub)
 {
@@ -1286,39 +1362,29 @@ static struct repository *get_submodule_repo_for(struct repository *r,
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
-	int ret = 0;
 	struct submodule_parallel_fetch *spf = data;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
-		struct strbuf submodule_prefix = STRBUF_INIT;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *default_argv;
-		const struct submodule *submodule;
-		struct repository *repo;
-		struct submodule default_submodule = SUBMODULE_INIT;
+		struct fetch_task *task;
 
 		if (!S_ISGITLINK(ce->ce_mode))
 			continue;
 
-		submodule = submodule_from_path(spf->r, &null_oid, ce->name);
-		if (!submodule) {
-			const char *name = default_name_or_path(ce->name);
-			if (name) {
-				default_submodule.path = name;
-				default_submodule.name = name;
-				submodule = &default_submodule;
-			}
-		}
+		task = fetch_task_create(spf->r, ce->name);
+		if (!task)
+			continue;
 
-		switch (get_fetch_recurse_config(submodule, spf))
+		switch (get_fetch_recurse_config(task->sub, spf))
 		{
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule ||
+			if (!task->sub ||
 			    !string_list_lookup(
 					&spf->changed_submodule_names,
-					submodule->name))
+					task->sub->name))
 				continue;
 			default_argv = "on-demand";
 			break;
@@ -1329,11 +1395,11 @@ static int get_next_submodule(struct child_process *cp,
 			continue;
 		}
 
-		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
-		repo = get_submodule_repo_for(spf->r, submodule);
-		if (repo) {
+		task->repo = get_submodule_repo_for(spf->r, task->sub);
+		if (task->repo) {
+			struct strbuf submodule_prefix = STRBUF_INIT;
 			child_process_init(cp);
-			cp->dir = xstrdup(repo->gitdir);
+			cp->dir = task->repo->gitdir;
 			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
 			cp->git_cmd = 1;
 			if (!spf->quiet)
@@ -1343,12 +1409,22 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_pushv(&cp->args, spf->args.argv);
 			argv_array_push(&cp->args, default_argv);
 			argv_array_push(&cp->args, "--submodule-prefix");
+
+			strbuf_addf(&submodule_prefix, "%s%s/",
+						       spf->prefix,
+						       task->sub->path);
 			argv_array_push(&cp->args, submodule_prefix.buf);
 
-			repo_clear(repo);
-			free(repo);
-			ret = 1;
+			spf->count++;
+			*task_cb = task;
+
+			strbuf_release(&submodule_prefix);
+			return 1;
 		} else {
+
+			fetch_task_release(task);
+			free(task);
+
 			/*
 			 * An empty directory is normal,
 			 * the submodule is not initialized
@@ -1361,12 +1437,38 @@ static int get_next_submodule(struct child_process *cp,
 					    ce->name);
 			}
 		}
+	}
+
+	if (spf->oid_fetch_tasks_nr) {
+		struct fetch_task *task =
+			spf->oid_fetch_tasks[spf->oid_fetch_tasks_nr - 1];
+		struct strbuf submodule_prefix = STRBUF_INIT;
+		spf->oid_fetch_tasks_nr--;
+
+		strbuf_addf(&submodule_prefix, "%s%s/",
+			    spf->prefix, task->sub->path);
+
+		child_process_init(cp);
+		prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+		cp->git_cmd = 1;
+		cp->dir = task->repo->gitdir;
+
+		argv_array_init(&cp->args);
+		argv_array_pushv(&cp->args, spf->args.argv);
+		argv_array_push(&cp->args, "on-demand");
+		argv_array_push(&cp->args, "--submodule-prefix");
+		argv_array_push(&cp->args, submodule_prefix.buf);
+
+		/* NEEDSWORK: have get_default_remote from submodule--helper */
+		argv_array_push(&cp->args, "origin");
+		oid_array_for_each_unique(task->commits,
+					  append_oid_to_argv, &cp->args);
+
+		*task_cb = task;
 		strbuf_release(&submodule_prefix);
-		if (ret) {
-			spf->count++;
-			return 1;
-		}
+		return 1;
 	}
+
 	return 0;
 }
 
@@ -1374,20 +1476,66 @@ static int fetch_start_failure(struct strbuf *err,
 			       void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct fetch_task *task = task_cb;
 
 	spf->result = 1;
 
+	fetch_task_release(task);
 	return 0;
 }
 
+static int commit_missing_in_sub(const struct object_id *oid, void *data)
+{
+	struct repository *subrepo = data;
+
+	enum object_type type = oid_object_info(subrepo, oid, NULL);
+
+	return type != OBJ_COMMIT;
+}
+
 static int fetch_finish(int retvalue, struct strbuf *err,
 			void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct fetch_task *task = task_cb;
+
+	struct string_list_item *it;
+	struct oid_array *commits;
 
 	if (retvalue)
 		spf->result = 1;
 
+	if (!task || !task->sub)
+		BUG("callback cookie bogus");
+
+	/* Is this the second time we process this submodule? */
+	if (task->commits)
+		goto out;
+
+	it = string_list_lookup(&spf->changed_submodule_names, task->sub->name);
+	if (!it)
+		/* Could be an unchanged submodule, not contained in the list */
+		goto out;
+
+	commits = it->util;
+	oid_array_filter(commits,
+			 commit_missing_in_sub,
+			 task->repo);
+
+	/* Are there commits we want, but do not exist? */
+	if (commits->nr) {
+		task->commits = commits;
+		ALLOC_GROW(spf->oid_fetch_tasks,
+			   spf->oid_fetch_tasks_nr + 1,
+			   spf->oid_fetch_tasks_alloc);
+		spf->oid_fetch_tasks[spf->oid_fetch_tasks_nr] = task;
+		spf->oid_fetch_tasks_nr++;
+		return 0;
+	}
+
+out:
+	fetch_task_release(task);
+
 	return 0;
 }
 
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 6c2f9b2ba2..9f8c744eb5 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -600,4 +600,121 @@ test_expect_success "fetch new commits when submodule got renamed" '
 	test_cmp expect actual
 '
 
+test_expect_success "fetch new submodule commits on-demand outside standard refspec" '
+	# add a second submodule and ensure it is around in downstream first
+	git clone submodule sub1 &&
+	git submodule add ./sub1 &&
+	git commit -m "adding a second submodule" &&
+	git -C downstream pull &&
+	git -C downstream submodule update --init --recursive &&
+
+	git checkout --detach &&
+
+	C=$(git -C submodule commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/1 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	test_tick &&
+
+	D=$(git -C sub1 commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
+	git -C sub1 update-ref refs/changes/2 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+
+	git commit -m "updated submodules outside of refs/heads" &&
+	E=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/3 $E &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/3:refs/heads/my_branch &&
+		git -C submodule cat-file -t $C &&
+		git -C sub1 cat-file -t $D &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
+test_expect_success 'fetch new submodule commit on-demand in FETCH_HEAD' '
+	# depends on the previous test for setup
+
+	C=$(git -C submodule commit-tree -m "another change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/4 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	test_tick &&
+
+	D=$(git -C sub1 commit-tree -m "another change outside refs/heads" HEAD^{tree}) &&
+	git -C sub1 update-ref refs/changes/5 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+
+	git commit -m "updated submodules outside of refs/heads" &&
+	E=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/6 $E &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/6 &&
+		git -C submodule cat-file -t $C &&
+		git -C sub1 cat-file -t $D &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
+test_expect_success 'fetch new submodule commits on-demand without .gitmodules entry' '
+	# depends on the previous test for setup
+
+	git config -f .gitmodules --remove-section submodule.sub1 &&
+	git add .gitmodules &&
+	git commit -m "delete gitmodules file" &&
+	git checkout -B master &&
+	git -C downstream fetch &&
+	git -C downstream checkout origin/master &&
+
+	C=$(git -C submodule commit-tree -m "yet another change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/7 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	test_tick &&
+
+	D=$(git -C sub1 commit-tree -m "yet another change outside refs/heads" HEAD^{tree}) &&
+	git -C sub1 update-ref refs/changes/8 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+
+	git commit -m "updated submodules outside of refs/heads" &&
+	E=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/9 $E &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/9 &&
+		git -C submodule cat-file -t $C &&
+		git -C sub1 cat-file -t $D &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
+test_expect_success 'fetch new submodule commit intermittently referenced by superproject' '
+	# depends on the previous test for setup
+
+	D=$(git -C sub1 commit-tree -m "change 10 outside refs/heads" HEAD^{tree}) &&
+	E=$(git -C sub1 commit-tree -m "change 11 outside refs/heads" HEAD^{tree}) &&
+	F=$(git -C sub1 commit-tree -m "change 12 outside refs/heads" HEAD^{tree}) &&
+
+	git -C sub1 update-ref refs/changes/10 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+	git commit -m "updated submodules outside of refs/heads" &&
+
+	git -C sub1 update-ref refs/changes/11 $E &&
+	git update-index --cacheinfo 160000 $E sub1 &&
+	git commit -m "updated submodules outside of refs/heads" &&
+
+	git -C sub1 update-ref refs/changes/12 $F &&
+	git update-index --cacheinfo 160000 $F sub1 &&
+	git commit -m "updated submodules outside of refs/heads" &&
+
+	G=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/13 $G &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/13 &&
+
+		git -C sub1 cat-file -t $D &&
+		git -C sub1 cat-file -t $E &&
+		git -C sub1 cat-file -t $F
+	)
+'
+
 test_done
-- 
2.20.0.rc2.230.gc28305e538


^ permalink raw reply related	[relevance 21%]

* Re: [wishlist] git submodule update --reset-hard
  2018-12-06 18:29  7% ` Stefan Beller
@ 2018-12-06 21:24  6%   ` Yaroslav Halchenko
  2018-12-06 21:55  7%     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Yaroslav Halchenko @ 2018-12-06 21:24 UTC (permalink / raw)
  To: git


On Thu, 06 Dec 2018, Stefan Beller wrote:

> On Thu, Dec 6, 2018 at 10:02 AM Yaroslav Halchenko <yoh@onerussian.com> wrote:

> > Dear Git Gurus,

> > I wondered what would be your take on my wishlist request to add
> > --reset-hard option, which would be very similar to regular "update" which
> > checks out necessary commit, but I want it to remain in the branch.

> What if the branch differs from the sha1 recorded in the superproject?

git reset --hard  itself is an operation which should be done with some
level of competence in doing "the right thing" by calling it.  You
can hop branches even in current (without any submodules in question)
repository with it and cause as much chaos as you desire.

If desired though, a number of prevention mechanisms could be in place (but
would require option(s) to overcome) to allow submodule to be reset --hard'ed
only when some conditions met (e.g. only to the commit which is among parent
commits path of the current branch).  This way wild hops would be prevented,
although you might still end up in some feature branch.  But since "reset
--hard" itself doesn't have any safe-guards, I do not really think they should
be implemented here either.

> > Rationale: In DataLad we heavily rely on submodules, and we have established
> > easy ways to do some manipulations across full hierarchies of them. E.g. a
> > single command could introduce a good number of commits across deep hierarchy
> > of submodules, e.g. while committing changes within deep submodule, while also
> > doing all necessary commits in the repositories leading to that submodule so
> > the entire tree of them stays in a "clean" state. The difficulty comes when
> > there is a need to just "forget" some changes.  The obvious way is to e.g.

> >    git reset --hard PREVIOUS_STATE

>   git reset --hard --recurse-submodules HEAD

> would do the trick

it does indeed some trick(s) but not all seems to be the ones I desire:

1. Seems to migrate submodule's .git directories into the top level
.git/modules

	$>  git reset --hard --recurse-submodules HEAD^^^
	Migrating git directory of 'famface' from        
	'/tmp/gobbini/famface/.git' to
	'/tmp/gobbini/.git/modules/famface'
	Migrating git directory of 'famface/data' from
	'/tmp/gobbini/famface/data/.git' to
	'/tmp/gobbini/.git/modules/famface/modules/data'
	Migrating git directory of 'famface/data/scripts/mridefacer' from
	'/tmp/gobbini/famface/data/scripts/mridefacer/.git' to
	'/tmp/gobbini/.git/modules/famface/modules/data/modules/scripts/mridefacer'
	HEAD is now at 9b4296d [DATALAD] aggregated meta data

we might eventually adopt this default already for years model (git annex seems
to be ok, in that it then replaces .git symlink file with the actual
symlink .git -> ../../.git/modules/...  So things seems to keep working
for annex)

2. It still does the detached HEAD for me

	$> git submodule status --recursive              
	 2569ab436501a832d35afbbe9cc20ffeb6077eb1 famface (2569ab4)
	 f1e8c9b8b025c311424283b9711efc6bc906ba2b famface/data (BIDS-v1.0.1)
	 49b0fe42696724c2a8492f999736056e51b77358 famface/data/scripts/mridefacer (49b0fe4)


> > in the top level repository.  But that leaves all the submodules now in
> > the undesired state.  If I do

> undesirable in the sense of still having local changes (that is what
> the above reset with `--recurse` would fix) or changed the branch
> state? (i.e. is detached but was on a branch before?)

right -- I meant the local changes and indeed reset --recurse-submodules
indeed seems to recurse nicely.  Then the undesired effect remaining only
the detached HEAD

> >   git submodule update --recursive

> > I would end up in the detached HEADs within submodules.

> > What I want is to retain current branch they are at (or may be possible
> > "were in"? reflog records might have that information)

> So something like

>   git submodule foreach --recursive git reset --hard

> ?

not quite  -- this would just kill all local changes within each submodule, not
to reset it to the desired state, which wouldn't be specified in such
invocation, and is only known to the repo containing it

> You may be interested in
> https://public-inbox.org/git/20180927221603.148025-1-sbeller@google.com/
> which introduces a switch `submodule.repoLike [ = true]`, which
> when set would not detach HEAD in submodules.

Thanks! looks interesting -- was there more discussion/activity beyond those 5
posts in the thread?
https://public-inbox.org/git/87h8i9ift4.fsf@evledraar.gmail.com/#r 

This feature might indeed come handy but if I got it right, it is somewhat
complimentary to just having submodule update --reset-hard .  E.g.  submodules
might be in different branches (if I am not tracking based on branch names), so
I would not want a recursive checkout with -b|-B.  But we would indeed benefit
from such functionality, since this difficulty of managing branches of
submodules I think would be elevated with it! (e.g. in one use case we probably
will end up with a few thousands of submodules, and at least 3 branches in each
which would need to be in sync, and typically you wouldn't want different
branches to be checked out in different submodules)

> Can you say more about the first question above:
> Would you typically have situations where the
> submodule branch is out of sync with the superproject
> and how do you deal with that?

typically I do not have anything out of sync.  My primary use-case is to
"cancel" recent changes in the entire tree of repositories.  I guess for
my use case, instead of needing two commands

   git reset --hard PREVIOUSPOINT
   git submodule update --reset--hard --recursive

I wish there was just one

   git reset --hard --recursive PREVIOUSPOINT

but I felt that   submodule update   might be a better starting point
since it already  provides different modes for update.  If I was even greedier,
I would have asked for 

   git revert --recursive <commit>...
   git rebase --recursive [-i] ...

which I also frequently desire (could elaborate on the use cases etc).

NB or --recurse-submodules to avoid confusion with recursive merge
strategy?


But for a complete answer -- if submodule branch is ahead of the superproject's
record, I just commit new state for it in superproject.  Or if I see that all
what I have done was actually a throw away -- "reset --hard" to that needed
state, again manually in submodule.  With  submodule update --reset-hard
--recursive  or  git reset --hard --recursive   I would be just ready
regardless of the depth and complexity of the hierarchy ;-)

> Adding another mode to `git submodule update` sounds
> reasonable to me, too.

cool, thanks!

-- 
Yaroslav O. Halchenko
Center for Open Neuroscience     http://centerforopenneuroscience.org
Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
Phone: +1 (603) 646-9834                       Fax: +1 (603) 646-1419
WWW:   http://www.linkedin.com/in/yarik        

^ permalink raw reply	[relevance 6%]

* Re: [wishlist] git submodule update --reset-hard
  @ 2018-12-06 18:29  7% ` Stefan Beller
  2018-12-06 21:24  6%   ` Yaroslav Halchenko
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-12-06 18:29 UTC (permalink / raw)
  To: Yaroslav Halchenko; +Cc: git

On Thu, Dec 6, 2018 at 10:02 AM Yaroslav Halchenko <yoh@onerussian.com> wrote:
>
> Dear Git Gurus,
>
> I wondered what would be your take on my wishlist request to add
> --reset-hard option, which would be very similar to regular "update" which
> checks out necessary commit, but I want it to remain in the branch.

What if the branch differs from the sha1 recorded in the superproject?

> Rationale: In DataLad we heavily rely on submodules, and we have established
> easy ways to do some manipulations across full hierarchies of them. E.g. a
> single command could introduce a good number of commits across deep hierarchy
> of submodules, e.g. while committing changes within deep submodule, while also
> doing all necessary commits in the repositories leading to that submodule so
> the entire tree of them stays in a "clean" state. The difficulty comes when
> there is a need to just "forget" some changes.  The obvious way is to e.g.
>
>    git reset --hard PREVIOUS_STATE

  git reset --hard --recurse-submodules HEAD

would do the trick

> in the top level repository.  But that leaves all the submodules now in
> the undesired state.  If I do

undesirable in the sense of still having local changes (that is what
the above reset with `--recurse` would fix) or changed the branch
state? (i.e. is detached but was on a branch before?)

>   git submodule update --recursive
>
> I would end up in the detached HEADs within submodules.
>
> What I want is to retain current branch they are at (or may be possible
> "were in"? reflog records might have that information)

So something like

  git submodule foreach --recursive git reset --hard

?

You may be interested in
https://public-inbox.org/git/20180927221603.148025-1-sbeller@google.com/
which introduces a switch `submodule.repoLike [ = true]`, which
when set would not detach HEAD in submodules.

Can you say more about the first question above:
Would you typically have situations where the
submodule branch is out of sync with the superproject
and how do you deal with that?

Adding another mode to `git submodule update` sounds
reasonable to me, too.

Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (7 preceding siblings ...)
  2018-11-29  0:27 22% ` [PATCH 9/9] fetch: try fetching submodules if needed objects were not fetched Stefan Beller
@ 2018-12-05  3:10  7% ` Junio C Hamano
  2018-12-06 21:59  4%   ` Stefan Beller
  2018-12-07  0:25  6% ` Josh Steadmon
  9 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-12-05  3:10 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, jonathantanmy

Stefan Beller <sbeller@google.com> writes:

> This is a resend of sb/submodule-recursive-fetch-gets-the-tip,
> with all feedback addressed. As it took some time, I'll send it
> without range-diff, but would ask for full review.

Is that a "resend" or reroll/update (or whatever word that does not
imply "just sending the same thing again")?

FWIW, here is the range diff between 104f939f27..@{-1} and master..
after replacing the topic with this round.


 3:  304b2dab29 !  3:  08a297bd49 submodule.c: sort changed_submodule_names before searching it
    @@ -28,7 +28,7 @@
     @@
      	/* default value, "--submodule-prefix" and its value are added later */
      
    - 	calculate_changed_submodule_paths();
    + 	calculate_changed_submodule_paths(r);
     +	string_list_sort(&changed_submodule_names);
      	run_processes_parallel(max_parallel_jobs,
      			       get_next_submodule,

Just the call nearby in the context has become repository-aware; no
change in this series.

 4:  f7345dad6d !  4:  16dd6fe133 submodule.c: tighten scope of changed_submodule_names struct
...
    ++	calculate_changed_submodule_paths(r, &spf.changed_submodule_names);
     +	string_list_sort(&spf.changed_submodule_names);
      	run_processes_parallel(max_parallel_jobs,
      			       get_next_submodule,

I do recall having to do these adjustments while merging, so not
having to do so anymore with rebasing is a welcome change ;-)

 5:  5613d81d1e !  5:  bcd7337243 submodule: store OIDs in changed_submodule_names
...
Likewise.

 7:  e2419f7e30 !  7:  26f80ccfc1 submodule: migrate get_next_submodule to use repository structs
    @@ -4,7 +4,8 @@
     
         We used to recurse into submodules, even if they were broken having
         only an objects directory. The child process executed in the submodule
    -    would fail though if the submodule was broken.
    +    would fail though if the submodule was broken. This is tested via
    +    "fetching submodule into a broken repository" in t5526.
     
         This patch tightens the check upfront, such that we do not need
         to spawn a child process to find out if the submodule is broken.
    @@ -34,6 +35,7 @@
     +		strbuf_repo_worktree_path(&gitdir, r, "%s/.git", sub->path);
     +		if (repo_init(ret, gitdir.buf, NULL)) {
     +			strbuf_release(&gitdir);
    ++			free(ret);
     +			return NULL;

Leakfix?  Good.

     +		}
     +		strbuf_release(&gitdir);
    @@ -75,11 +77,10 @@
     +		if (repo) {
      			child_process_init(cp);
     -			cp->dir = strbuf_detach(&submodule_path, NULL);
    - 			prepare_submodule_repo_env(&cp->env_array);
     +			cp->dir = xstrdup(repo->worktree);
    + 			prepare_submodule_repo_env(&cp->env_array);

Hmph, I offhand do not see there would be any difference if you
assigned to cp->dir before or after preparing the repo env, but is
there a reason these two must be done in this updated order that I
am missing?  Very similar changes appear multiple times in this
range-diff.

      			cp->git_cmd = 1;
      			if (!spf->quiet)
    - 				strbuf_addf(err, "Fetching submodule %s%s\n",
     @@
      			argv_array_push(&cp->args, default_argv);
      			argv_array_push(&cp->args, "--submodule-prefix");
    @@ -94,8 +95,12 @@
     +			 * the submodule is not initialized
     +			 */
     +			if (S_ISGITLINK(ce->ce_mode) &&
    -+			    !is_empty_dir(ce->name))
    -+				die(_("Could not access submodule '%s'"), ce->name);
    ++			    !is_empty_dir(ce->name)) {
    ++				spf->result = 1;
    ++				strbuf_addf(err,
    ++					    _("Could not access submodule '%s'"),
    ++					    ce->name);
    ++			}

OK, not dying but returning to the caller to handle the error.

 9:  7454fe5cb6 !  9:  04eb06607b fetch: try fetching submodules if needed objects were not fetched
    @@ -17,11 +17,6 @@
         Try fetching a submodule by object id if the object id that the
         superproject points to, cannot be found.
     
    -    The try does not happen when the "git fetch" done at the
    -    superproject is not storing the fetched results in remote
    -    tracking branches (i.e. instead just recording them to
    -    FETCH_HEAD) in this step. A later patch will fix this.
    -
         builtin/fetch used to only inspect submodules when they were fetched
         "on-demand", as in either on/off case it was clear whether the submodule
         needs to be fetched. However to know whether we need to try fetching the
    @@ -29,6 +24,10 @@
         function check_for_new_submodule_commits(), so we'll also run that code
         in case the submodule recursion is set to "on".
     
    +    The submodule checks were done only when a ref in the superproject
    +    changed, these checks were extended to also be performed when fetching
    +    into FETCH_HEAD for completeness, and add a test for that too.
    +

OK.

         Signed-off-by: Stefan Beller <sbeller@google.com>
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    @@ -41,30 +40,39 @@
      
...

The range-diff output for this step is unreadble for me, but the
code around this area does not seem to appear in the comparison
between the result of applying these directly to master and the
result of merging the previous round to master, so perhaps this is
just an indication that later follow-up fix has been squashed into
this step or something, which I shouldn't have to worry about.

      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
    @@ -73,8 +81,10 @@
      	int result;
      
      	struct string_list changed_submodule_names;
    -+	struct get_next_submodule_task **fetch_specific_oids;
    -+	int fetch_specific_oids_nr, fetch_specific_oids_alloc;
    ++
    ++	/* The submodules to fetch in */
    ++	struct fetch_task **oid_fetch_tasks;
    ++	int oid_fetch_tasks_nr, oid_fetch_tasks_alloc;

OK.  The task struct has been renamed and the new name makes more
sense ("getting the next submodule" is less important than "what we
are going to do to that submodule").

...      
    -+struct get_next_submodule_task {
    ++struct fetch_task {
     +	struct repository *repo;
     +	const struct submodule *sub;
     +	unsigned free_sub : 1; /* Do we need to free the submodule? */
...
     +	return (const struct submodule *) ret;
     +}
     +
    -+static struct get_next_submodule_task *get_next_submodule_task_create(
    -+	struct repository *r, const char *path)
    ++static struct fetch_task *fetch_task_create(struct repository *r,
    ++					    const char *path)
     +{
    -+	struct get_next_submodule_task *task = xmalloc(sizeof(*task));
    ++	struct fetch_task *task = xmalloc(sizeof(*task));
     +	memset(task, 0, sizeof(*task));
     +
     +	task->sub = submodule_from_path(r, &null_oid, path);
     +	if (!task->sub) {
    -+		task->sub = get_default_submodule(path);
    ++		/*
    ++		 * No entry in .gitmodules? Technically not a submodule,
    ++		 * but historically we supported repositories that happen to be
    ++		 * in-place where a gitlink is. Keep supporting them.
    ++		 */
    ++		task->sub = get_non_gitmodules_submodule(path);
    ++		if (!task->sub) {
    ++			free(task);
    ++			return NULL;
    ++		}
    ++
     +		task->free_sub = 1;

OK.

    -+		if (!task->sub) {
    -+			free(task);
    +-		}
    ++		task = fetch_task_create(spf->r, ce->name);
    ++		if (!task)
     +			continue;
    - 		}

OK, so the code used to signal the need to work with the presense of
task->sub but now task's NULLness is used, so no need to free.

    @@ -231,24 +253,26 @@
     +			return 1;
      		} else {
     +
    -+			get_next_submodule_task_release(task);
    ++			fetch_task_release(task);
     +			free(task);
     +

OK.

    -+		/* NEEDSWORK: have get_default_remote from s--h */
    ++		/* NEEDSWORK: have get_default_remote from submodule--helper */

;-)


^ permalink raw reply	[relevance 7%]

* Re: [ANNOUNCE] Git v2.20.0-rc2
  2018-12-01 14:58  2% [ANNOUNCE] Git v2.20.0-rc2 Junio C Hamano
@ 2018-12-03 20:45  0% ` Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2018-12-03 20:45 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, git-for-windows, git-packagers

[-- Attachment #1: Type: text/plain, Size: 91897 bytes --]

Team,

Git for Windows v2.20.0-rc2 is available here:

https://github.com/git-for-windows/git/releases/tag/v2.20.0-rc2.windows.1

There is already one known issue: the size of the installer increased (see
https://github.com/git-for-windows/git/issues/1963). This is in the
process of being addressed.

Ciao,
Johannes

On Sat, 1 Dec 2018, Junio C Hamano wrote:

> A release candidate Git v2.20.0-rc2 is now available for testing
> at the usual places.  It is comprised of 934 non-merge commits
> since v2.19.0, contributed by 76 people, 25 of which are new faces.
> 
> The tarballs are found at:
> 
>     https://www.kernel.org/pub/software/scm/git/testing/
> 
> The following public repositories all have a copy of the
> 'v2.20.0-rc2' tag and the 'master' branch that the tag points at:
> 
>   url = https://kernel.googlesource.com/pub/scm/git/git
>   url = git://repo.or.cz/alt-git.git
>   url = https://github.com/gitster/git
> 
> New contributors whose contributions weren't in v2.19.0 are as follows.
> Welcome to the Git development community!
> 
>   Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan
>   Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis, David
>   Zych, Đoàn Trần Công Danh, Frederick Eaton, Greg Hurrell,
>   James Knight, Jann Horn, Joshua Watt, Loo Rong Jie, Lucas
>   De Marchi, Matthew DeVore, Mihir Mehta, Nickolai Belakovski,
>   Roger Strain, Sam McKelvie, Saulius Gurklys, Shulhan, Steven
>   Fernandez, Strain, Roger L, and Tim Schumacher.
> 
> Returning contributors who helped this release are as follows.
> Thanks for your continued support.
> 
>   Ævar Arnfjörð Bjarmason, Alban Gruin, Andreas Gruenbacher,
>   Andreas Heiduk, Antonio Ospite, Ben Peart, Brandon Williams,
>   brian m. carlson, Christian Couder, Christian Hesse, Denton Liu,
>   Derrick Stolee, Elijah Newren, Eric Sunshine, Jean-Noël Avila,
>   Jeff Hostetler, Jeff King, Johannes Schindelin, Johannes Sixt,
>   Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano,
>   Karsten Blees, Luke Diamand, Martin Ågren, Max Kirillov,
>   Michael Witten, Michał Górny, Nguyễn Thái Ngọc Duy, Noam
>   Postavsky, Olga Telezhnaya, Phillip Wood, Pratik Karki, Rafael
>   Ascensão, Ralf Thielow, Ramsay Jones, Rasmus Villemoes, René
>   Scharfe, Sebastian Staudt, Stefan Beller, Stephen P. Smith, Steve
>   Hoelzer, Sven Strickroth, SZEDER Gábor, Tao Qingyun, Taylor
>   Blau, Thomas Gummerer, Todd Zullinger, Torsten Bögershausen,
>   and Uwe Kleine-König.
> 
> ----------------------------------------------------------------
> 
> Git 2.20 Release Notes (draft)
> ==============================
> 
> Backward Compatibility Notes
> ----------------------------
> 
>  * "git branch -l <foo>" used to be a way to ask a reflog to be
>    created while creating a new branch, but that is no longer the
>    case.  It is a short-hand for "git branch --list <foo>" now.
> 
>  * "git push" into refs/tags/* hierarchy is rejected without getting
>    forced, but "git fetch" (misguidedly) used the "fast forwarding"
>    rule used for the refs/heads/* hierarchy; this has been corrected,
>    which means some fetches of tags that did not fail with older
>    version of Git will fail without "--force" with this version.
> 
>  * "git help -a" now gives verbose output (same as "git help -av").
>    Those who want the old output may say "git help --no-verbose -a"..
> 
>  * "git cpn --help", when "cpn" is an alias to, say, "cherry-pick -n",
>    reported only the alias expansion of "cpn" in earlier versions of
>    Git.  It now runs "git cherry-pick --help" to show the manual page
>    of the command, while sending the alias expansion to the standard
>    error stream.
> 
>  * "git send-email" learned to grab address-looking string on any
>    trailer whose name ends with "-by". This is a backward-incompatible
>    change.  Adding "--suppress-cc=misc-by" on the command line, or
>    setting sendemail.suppresscc configuration variable to "misc-by",
>    can be used to disable this behaviour.
> 
> 
> Updates since v2.19
> -------------------
> 
> UI, Workflows & Features
> 
>  * Running "git clone" against a project that contain two files with
>    pathnames that differ only in cases on a case insensitive
>    filesystem would result in one of the files lost because the
>    underlying filesystem is incapable of holding both at the same
>    time.  An attempt is made to detect such a case and warn.
> 
>  * "git checkout -b newbranch [HEAD]" should not have to do as much as
>    checking out a commit different from HEAD.  An attempt is made to
>    optimize this special case.
> 
>  * "git rev-list --stdin </dev/null" used to be an error; it now shows
>    no output without an error.  "git rev-list --stdin --default HEAD"
>    still falls back to the given default when nothing is given on the
>    standard input.
> 
>  * Lift code from GitHub to restrict delta computation so that an
>    object that exists in one fork is not made into a delta against
>    another object that does not appear in the same forked repository.
> 
>  * "git format-patch" learned new "--interdiff" and "--range-diff"
>    options to explain the difference between this version and the
>    previous attempt in the cover letter (or after the three-dashes as
>    a comment).
> 
>  * "git mailinfo" used in "git am" learned to make a best-effort
>    recovery of a patch corrupted by MUA that sends text/plain with
>    format=flawed option.
>    (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).
> 
>  * The rules used by "git push" and "git fetch" to determine if a ref
>    can or cannot be updated were inconsistent; specifically, fetching
>    to update existing tags were allowed even though tags are supposed
>    to be unmoving anchoring points.  "git fetch" was taught to forbid
>    updates to existing tags without the "--force" option.
> 
>  * "git multi-pack-index" learned to detect corruption in the .midx
>    file it uses, and this feature has been integrated into "git fsck".
> 
>  * Generation of (experimental) commit-graph files have so far been
>    fairly silent, even though it takes noticeable amount of time in a
>    meaningfully large repository.  The users will now see progress
>    output.
> 
>  * The minimum version of Windows supported by Windows port of Git is
>    now set to Vista.
> 
>  * The completion script (in contrib/) learned to complete a handful of
>    options "git stash list" command takes.
> 
>  * The completion script (in contrib/) learned that "git fetch
>    --multiple" only takes remote names as arguments and no refspecs.
> 
>  * "git status" learns to show progress bar when refreshing the index
>    takes a long time.
>    (merge ae9af12287 nd/status-refresh-progress later to maint).
> 
>  * "git help -a" and "git help -av" give different pieces of
>    information, and generally the "verbose" version is more friendly
>    to the new users.  "git help -a" by default now uses the more
>    verbose output (with "--no-verbose", you can go back to the
>    original).  Also "git help -av" now lists aliases and external
>    commands, which it did not used to.
> 
>  * Unlike "grep", "git grep" by default recurses to the whole tree.
>    The command learned "git grep --recursive" option, so that "git
>    grep --no-recursive" can serve as a synonym to setting the
>    max-depth to 0.
> 
>  * When pushing into a repository that borrows its objects from an
>    alternate object store, "git receive-pack" that responds to the
>    push request on the other side lists the tips of refs in the
>    alternate to reduce the amount of objects transferred.  This
>    sometimes is detrimental when the number of refs in the alternate
>    is absurdly large, in which case the bandwidth saved in potentially
>    fewer objects transferred is wasted in excessively large ref
>    advertisement.  The alternate refs that are advertised are now
>    configurable with a pair of configuration variables.
> 
>  * "git cmd --help" when "cmd" is aliased used to only say "cmd is
>    aliased to ...".  Now it shows that to the standard error stream
>    and runs "git $cmd --help" where $cmd is the first word of the
>    alias expansion.
> 
>  * The documentation of "git gc" has been updated to mention that it
>    is no longer limited to "pruning away crufts" but also updates
>    ancillary files like commit-graph as a part of repository
>    optimization.
> 
>  * "git p4 unshelve" improvements.
> 
>  * The logic to select the default user name and e-mail on Windows has
>    been improved.
>    (merge 501afcb8b0 js/mingw-default-ident later to maint).
> 
>  * The "rev-list --filter" feature learned to exclude all trees via
>    "tree:0" filter.
> 
>  * "git send-email" learned to grab address-looking string on any
>    trailer whose name ends with "-by"; --suppress-cc=misc-by on the
>    command line, or setting sendemail.suppresscc configuration
>    variable to "misc-by", can be used to disable this behaviour.
> 
>  * Developer builds now uses -Wunused-function compilation option.
> 
>  * One of our CI tests to run with "unusual/experimental/random"
>    settings now also uses commit-graph and midx.
> 
>  * "git mergetool" learned to take the "--[no-]gui" option, just like
>    "git difftool" does.
> 
>  * "git rebase -i" learned a new insn, 'break', that the user can
>    insert in the to-do list.  Upon hitting it, the command returns
>    control back to the user.
> 
>  * New "--pretty=format:" placeholders %GF and %GP that show the GPG
>    key fingerprints have been invented.
> 
>  * On platforms with recent cURL library, http.sslBackend configuration
>    variable can be used to choose a different SSL backend at runtime.
>    The Windows port uses this mechanism to switch between OpenSSL and
>    Secure Channel while talking over the HTTPS protocol.
> 
>  * "git send-email" learned to disable SMTP authentication via the
>    "--smtp-auth=none" option, even when the smtp username is given
>    (which turns the authentication on by default).
> 
>  * A fourth class of configuration files (in addition to the
>    traditional "system wide", "per user in the $HOME directory" and
>    "per repository in the $GIT_DIR/config") has been introduced so
>    that different worktrees that share the same repository (hence the
>    same $GIT_DIR/config file) can use different customization.
> 
>  * A pattern with '**' that does not have a slash on either side used
>    to be an invalid one, but the code now treats such double-asterisks
>    the same way as two normal asterisks that happen to be adjacent to
>    each other.
>    (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).
> 
>  * The "--no-patch" option, which can be used to get a high-level
>    overview without the actual line-by-line patch difference shown, of
>    the "range-diff" command was earlier broken, which has been
>    corrected.
> 
>  * The recently merged "rebase in C" has an escape hatch to use the
>    scripted version when necessary, but it hasn't been documented,
>    which has been corrected.
> 
> 
> Performance, Internal Implementation, Development Support etc.
> 
>  * When there are too many packfiles in a repository (which is not
>    recommended), looking up an object in these would require
>    consulting many pack .idx files; a new mechanism to have a single
>    file that consolidates all of these .idx files is introduced.
> 
>  * "git submodule update" is getting rewritten piece-by-piece into C.
> 
>  * The code for computing history reachability has been shuffled,
>    obtained a bunch of new tests to cover them, and then being
>    improved.
> 
>  * The unpack_trees() API used in checking out a branch and merging
>    walks one or more trees along with the index.  When the cache-tree
>    in the index tells us that we are walking a tree whose flattened
>    contents is known (i.e. matches a span in the index), as linearly
>    scanning a span in the index is much more efficient than having to
>    open tree objects recursively and listing their entries, the walk
>    can be optimized, which has been done.
> 
>  * When creating a thin pack, which allows objects to be made into a
>    delta against another object that is not in the resulting pack but
>    is known to be present on the receiving end, the code learned to
>    take advantage of the reachability bitmap; this allows the server
>    to send a delta against a base beyond the "boundary" commit.
> 
>  * spatch transformation to replace boolean uses of !hashcmp() to
>    newly introduced oideq() is added, and applied, to regain
>    performance lost due to support of multiple hash algorithms.
> 
>  * Fix a bug in which the same path could be registered under multiple
>    worktree entries if the path was missing (for instance, was removed
>    manually).  Also, as a convenience, expand the number of cases in
>    which --force is applicable.
> 
>  * Split Documentation/config.txt for easier maintenance.
>    (merge 6014363f0b nd/config-split later to maint).
> 
>  * Test helper binaries clean-up.
>    (merge c9a1f4161f nd/test-tool later to maint).
> 
>  * Various tests have been updated to make it easier to swap the
>    hash function used for object identification.
>    (merge ae0c89d41b bc/hash-independent-tests later to maint).
> 
>  * Update fsck.skipList implementation and documentation.
>    (merge 371a655074 ab/fsck-skiplist later to maint).
> 
>  * An alias that expands to another alias has so far been forbidden,
>    but now it is allowed to create such an alias.
> 
>  * Various test scripts have been updated for style and also correct
>    handling of exit status of various commands.
> 
>  * "gc --auto" ended up calling exit(-1) upon error, which has been
>    corrected to use exit(1).  Also the error reporting behaviour when
>    daemonized has been updated to exit with zero status when stopping
>    due to a previously discovered error (which implies there is no
>    point running gc to improve the situation); we used to exit with
>    failure in such a case.
> 
>  * Various codepaths in the core-ish part learned to work on an
>    arbitrary in-core index structure, not necessarily the default
>    instance "the_index".
>    (merge b3c7eef9b0 nd/the-index later to maint).
> 
>  * Code clean-up in the internal machinery used by "git status" and
>    "git commit --dry-run".
>    (merge 73ba5d78b4 ss/wt-status-committable later to maint).
> 
>  * Some environment variables that control the runtime options of Git
>    used during tests are getting renamed for consistency.
>    (merge 4231d1ba99 bp/rename-test-env-var later to maint).
> 
>  * A pair of new extensions to the index file have been introduced.
>    They allow the index file to be read in parallel for performance.
> 
>  * The oidset API was built on top of the oidmap API which in turn is
>    on the hashmap API.  Replace the implementation to build on top of
>    the khash API and gain performance.
> 
>  * Over some transports, fetching objects with an exact commit object
>    name can be done without first seeing the ref advertisements.  The
>    code has been optimized to exploit this.
> 
>  * In a partial clone that will lazily be hydrated from the
>    originating repository, we generally want to avoid "does this
>    object exist (locally)?" on objects that we deliberately omitted
>    when we created the clone.  The cache-tree codepath (which is used
>    to write a tree object out of the index) however insisted that the
>    object exists, even for paths that are outside of the partial
>    checkout area.  The code has been updated to avoid such a check.
> 
>  * To help developers, an EditorConfig file that attempts to follow
>    the project convention has been added.
>    (merge b548d698a0 bc/editorconfig later to maint).
> 
>  * The result of coverage test can be combined with "git blame" to
>    check the test coverage of code introduced recently with a new
>    'coverage-diff' tool (in contrib/).
>    (merge 783faedd65 ds/coverage-diff later to maint).
> 
>  * An experiment to fuzz test a few areas, hopefully we can gain more
>    coverage to various areas.
> 
>  * More codepaths are moving away from hardcoded hash sizes.
> 
>  * The way the Windows port figures out the current directory has been
>    improved.
> 
>  * The way DLLs are loaded on the Windows port has been improved.
> 
>  * Some tests have been reorganized and renamed; "ls t/" now gives a
>    better overview of what is tested for these scripts than before.
> 
>  * "git rebase" and "git rebase -i" have been reimplemented in C.
> 
>  * Windows port learned to use nano-second resolution file timestamps.
> 
>  * The overly large Documentation/config.txt file have been split into
>    million little pieces.  This potentially allows each individual piece
>    included into the manual page of the command it affects more easily.
> 
>  * Replace three string-list instances used as look-up tables in "git
>    fetch" with hashmaps.
> 
>  * Unify code to read the author-script used in "git am" and the
>    commands that use the sequencer machinery, e.g. "git rebase -i".
> 
>  * In preparation to the day when we can deprecate and remove the
>    "rebase -p", make sure we can skip and later remove tests for
>    it.
> 
>  * The history traversal used to implement the tag-following has been
>    optimized by introducing a new helper.
> 
>  * The helper function to refresh the cached stat information in the
>    in-core index has learned to perform the lstat() part of the
>    operation in parallel on multi-core platforms.
> 
>  * The code to traverse objects for reachability, used to decide what
>    objects are unreferenced and expendable, have been taught to also
>    consider per-worktree refs of other worktrees as starting points to
>    prevent data loss.
> 
>  * "git add" needs to internally run "diff-files" equivalent, and the
>    codepath learned the same optimization as "diff-files" has to run
>    lstat(2) in parallel to find which paths have been updated in the
>    working tree.
> 
>  * The procedure to install dependencies before testing at Travis CI
>    is getting revamped for both simplicity and flexibility, taking
>    advantage of the recent move to the vm-based environment.
> 
>  * The support for format-patch (and send-email) by the command-line
>    completion script (in contrib/) has been simplified a bit.
> 
>  * The revision walker machinery learned to take advantage of the
>    commit generation numbers stored in the commit-graph file.
> 
>  * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".
> 
>  * The way -lcurl library gets linked has been simplified by taking
>    advantage of the fact that we can just ask curl-config command how.
> 
>  * Various functions have been audited for "-Wunused-parameter" warnings
>    and bugs in them got fixed.
> 
>  * A sanity check for start-up sequence has been added in the config
>    API codepath.
> 
>  * The build procedure to link for fuzzing test has been made
>    customizable with a new Makefile variable.
> 
>  * The way "git rebase" parses and forwards the command line options
>    meant for underlying "git am" has been revamped, which fixed for
>    options with parameters that were not passed correctly.
> 
>  * Our testing framework uses a special i18n "poisoned localization"
>    feature to find messages that ought to stay constant but are
>    incorrectly marked to be translated.  This feature has been made
>    into a runtime option (it used to be a compile-time option).
> 
>  * "git push" used to check ambiguities between object-names and
>    refnames while processing the list of refs' old and new values,
>    which was unnecessary (as it knew that it is feeding raw object
>    names).  This has been optimized out.
> 
>  * The xcurl_off_t() helper function is used to cast size_t to
>    curl_off_t, but some compilers gave warnings against the code to
>    ensure the casting is done without wraparound, when size_t is
>    narrower than curl_off_t.  This warning has been squelched.
> 
>  * Code preparation to replace ulong vars with size_t vars where
>    appropriate continues.
> 
>  * The "test installed Git" mode of our test suite has been updated to
>    work better.
> 
>  * A coding convention around the Coccinelle semantic patches to have
>    two classes to ease code migration process has been proposed and
>    its support has been added to the Makefile.
> 
> 
> Fixes since v2.19
> -----------------
> 
>  * "git interpret-trailers" and its underlying machinery had a buggy
>    code that attempted to ignore patch text after commit log message,
>    which triggered in various codepaths that will always get the log
>    message alone and never get such an input.
>    (merge 66e83d9b41 jk/trailer-fixes later to maint).
> 
>  * Malformed or crafted data in packstream can make our code attempt
>    to read or write past the allocated buffer and abort, instead of
>    reporting an error, which has been fixed.
> 
>  * "git rebase -i" did not clear the state files correctly when a run
>    of "squash/fixup" is aborted and then the user manually amended the
>    commit instead, which has been corrected.
>    (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).
> 
>  * When fsmonitor is in use, after operation on submodules updates
>    .gitmodules, we lost track of the fact that we did so and relied on
>    stale fsmonitor data.
>    (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).
> 
>  * Fix for a long-standing bug that leaves the index file corrupt when
>    it shrinks during a partial commit.
>    (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).
> 
>  * Further fix for O_APPEND emulation on Windows
>    (merge eeaf7ddac7 js/mingw-o-append later to maint).
> 
>  * A corner case bugfix in "git rerere" code.
>    (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).
> 
>  * "git add ':(attr:foo)'" is not supported and is supposed to be
>    rejected while the command line arguments are parsed, but we fail
>    to reject such a command line upfront.
>    (merge 84d938b732 nd/attr-pathspec-fix later to maint).
> 
>  * Recent update broke the reachability algorithm when refs (e.g.
>    tags) that point at objects that are not commit were involved,
>    which has been fixed.
> 
>  * "git rebase" etc. in Git 2.19 fails to abort when given an empty
>    commit log message as result of editing, which has been corrected.
>    (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).
> 
>  * The code to backfill objects in lazily cloned repository did not
>    work correctly, which has been corrected.
>    (merge e68302011c jt/lazy-object-fetch-fix later to maint).
> 
>  * Update error messages given by "git remote" and make them consistent.
>    (merge 5025425dff ms/remote-error-message-update later to maint).
> 
>  * "git update-ref" learned to make both "--no-deref" and "--stdin"
>    work at the same time.
>    (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).
> 
>  * Recently added "range-diff" had a corner-case bug to cause it
>    segfault, which has been corrected.
>    (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).
> 
>  * The recently introduced commit-graph auxiliary data is incompatible
>    with mechanisms such as replace & grafts that "breaks" immutable
>    nature of the object reference relationship.  Disable optimizations
>    based on its use (and updating existing commit-graph) when these
>    incompatible features are in use in the repository.
>    (merge 829a321569 ds/commit-graph-with-grafts later to maint).
> 
>  * The mailmap file update.
>    (merge 255eb03edf jn/mailmap-update later to maint).
> 
>  * The code in "git status" sometimes hit an assertion failure.  This
>    was caused by a structure that was reused without cleaning the data
>    used for the first run, which has been corrected.
>    (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).
> 
>  * "git fetch $repo $object" in a partial clone did not correctly
>    fetch the asked-for object that is referenced by an object in
>    promisor packfile, which has been fixed.
> 
>  * A corner-case bugfix.
>    (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).
> 
>  * Various fixes to "diff --color-moved-ws".
> 
>  * A partial clone that is configured to lazily fetch missing objects
>    will on-demand issue a "git fetch" request to the originating
>    repository to fill not-yet-obtained objects.  The request has been
>    optimized for requesting a tree object (and not the leaf blob
>    objects contained in it) by telling the originating repository that
>    no blobs are needed.
>    (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).
> 
>  * The codepath to support the experimental split-index mode had
>    remaining "racily clean" issues fixed.
>    (merge 4c490f3d32 sg/split-index-racefix later to maint).
> 
>  * "git log --graph" showing an octopus merge sometimes miscounted the
>    number of display columns it is consuming to show the merge and its
>    parent commits, which has been corrected.
>    (merge 04005834ed np/log-graph-octopus-fix later to maint).
> 
>  * "git range-diff" did not work well when the compared ranges had
>    changes in submodules and the "--submodule=log" was used.
> 
>  * The implementation of run_command() API on the UNIX platforms had a
>    bug that caused a command not on $PATH to be found in the current
>    directory.
>    (merge f67b980771 jk/run-command-notdot later to maint).
> 
>  * A mutex used in "git pack-objects" were not correctly initialized
>    and this caused "git repack" to dump core on Windows.
>    (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).
> 
>  * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
>    Windows would strip initial parts from the paths because they
>    were not recognized as absolute, which has been corrected.
>    (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).
> 
>  * The receive.denyCurrentBranch=updateInstead codepath kicked in even
>    when the push should have been rejected due to other reasons, such
>    as it does not fast-forward or the update-hook rejects it, which
>    has been corrected.
>    (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).
> 
>  * The logic to determine the archive type "git archive" uses did not
>    correctly kick in for "git archive --remote", which has been
>    corrected.
> 
>  * "git repack" in a shallow clone did not correctly update the
>    shallow points in the repository, leading to a repository that
>    does not pass fsck.
>    (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).
> 
>  * Some codepaths failed to form a proper URL when .gitmodules record
>    the URL to a submodule repository as relative to the repository of
>    superproject, which has been corrected.
>    (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).
> 
>  * "git fetch" over protocol v2 into a shallow repository failed to
>    fetch full history behind a new tip of history that was diverged
>    before the cut-off point of the history that was previously fetched
>    shallowly.
> 
>  * The command line completion machinery (in contrib/) has been
>    updated to allow the completion script to tweak the list of options
>    that are reported by the parse-options machinery correctly.
>    (merge 276b49ff34 nd/completion-negation later to maint).
> 
>  * Operations on promisor objects make sense in the context of only a
>    small subset of the commands that internally use the revisions
>    machinery, but the "--exclude-promisor-objects" option were taken
>    and led to nonsense results by commands like "log", to which it
>    didn't make much sense.  This has been corrected.
>    (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).
> 
>  * The "container" mode of TravisCI is going away.  Our .travis.yml
>    file is getting prepared for the transition.
>    (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).
> 
>  * Our test scripts can now take the '-V' option as a synonym for the
>    '--verbose-log' option.
>    (merge a5f52c6dab sg/test-verbose-log later to maint).
> 
>  * A regression in Git 2.12 era made "git fsck" fall into an infinite
>    loop while processing truncated loose objects.
>    (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).
> 
>  * "git ls-remote $there foo" was broken by recent update for the
>    protocol v2 and stopped showing refs that match 'foo' that are not
>    refs/{heads,tags}/foo, which has been fixed.
>    (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).
> 
>  * Additional comment on a tricky piece of code to help developers.
>    (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).
> 
>  * A couple of tests used to leave the repository in a state that is
>    deliberately corrupt, which have been corrected.
>    (merge aa984dbe5e ab/pack-tests-cleanup later to maint).
> 
>  * The submodule support has been updated to read from the blob at
>    HEAD:.gitmodules when the .gitmodules file is missing from the
>    working tree.
>    (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).
> 
>  * "git fetch" was a bit loose in parsing responses from the other side
>    when talking over the protocol v2.
> 
>  * "git rev-parse --exclude=* --branches --branches"  (i.e. first
>    saying "add only things that do not match '*' out of all branches"
>    and then adding all branches, without any exclusion this time")
>    worked as expected, but "--exclude=* --all --all" did not work the
>    same way, which has been fixed.
>    (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).
> 
>  * "git send-email --transfer-encoding=..." in recent versions of Git
>    sometimes produced an empty "Content-Transfer-Encoding:" header,
>    which has been corrected.
>    (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).
> 
>  * The interface into "xdiff" library used to discover the offset and
>    size of a generated patch hunk by first formatting it into the
>    textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
>    out.  A new interface has been introduced to allow callers a more
>    direct access to them.
>    (merge 5eade0746e jk/xdiff-interface later to maint).
> 
>  * Pathspec matching against a tree object were buggy when negative
>    pathspec elements were involved, which has been fixed.
>    (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).
> 
>  * "git merge" and "git pull" that merges into an unborn branch used
>    to completely ignore "--verify-signatures", which has been
>    corrected.
>    (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).
> 
>  * "git rebase --autostash" did not correctly re-attach the HEAD at times.
> 
>  * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
>    quite work, which has been corrected.
>    (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).
> 
>  * When editing a patch in a "git add -i" session, a hunk could be
>    made to no-op.  The "git apply" program used to reject a patch with
>    such a no-op hunk to catch user mistakes, but it is now updated to
>    explicitly allow a no-op hunk in an edited patch.
>    (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).
> 
>  * The URL to an MSDN page in a comment has been updated.
>    (merge 2ef2ae2917 js/mingw-msdn-url later to maint).
> 
>  * "git ls-remote --sort=<thing>" can feed an object that is not yet
>    available into the comparison machinery and segfault, which has
>    been corrected to check such a request upfront and reject it.
> 
>  * When "git bundle" aborts due to an empty commit ranges
>    (i.e. resulting in an empty pack), it left a file descriptor to an
>    lockfile open, which resulted in leftover lockfile on Windows where
>    you cannot remove a file with an open file descriptor.  This has
>    been corrected.
>    (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).
> 
>  * "git format-patch --stat=<width>" can be used to specify the width
>    used by the diffstat (shown in the cover letter).
>    (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).
> 
>  * The way .git/index and .git/sharedindex* files were initially
>    created gave these files different perm bits until they were
>    adjusted for shared repository settings.  This was made consistent.
>    (merge c9d6c78870 cc/shared-index-permbits later to maint).
> 
>  * "git rebase --stat" to transplant a piece of history onto a totally
>    unrelated history were not working before and silently showed wrong
>    result.  With the recent reimplementation in C, it started to instead
>    die with an error message, as the original logic was not prepared
>    to cope with this case.  This has now been fixed.
> 
>  * The advice message to tell the user to migrate an existing graft
>    file to the replace system when a graft file was read was shown
>    even when "git replace --convert-graft-file" command, which is the
>    way the message suggests to use, was running, which made little
>    sense.
>    (merge 8821e90a09 ab/replace-graft-with-replace-advice later to maint).
> 
>  * "git diff --raw" lost ellipses to adjust the output columns for
>    some time now, but the documentation still showed them.
> 
>  * Code cleanup, docfix, build fix, etc.
>    (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
>    (merge b9b07efdb2 tg/conflict-marker-size later to maint).
>    (merge fa0aeea770 sg/doc-trace-appends later to maint).
>    (merge d64324cb60 tb/void-check-attr later to maint).
>    (merge c3b9bc94b9 en/double-semicolon-fix later to maint).
>    (merge 79336116f5 sg/t3701-tighten-trace later to maint).
>    (merge 801fa63a90 jk/dev-build-format-security later to maint).
>    (merge 0597dd62ba sb/string-list-remove-unused later to maint).
>    (merge db2d36fad8 bw/protocol-v2 later to maint).
>    (merge 456d7cd3a9 sg/split-index-test later to maint).
>    (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).
>    (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).
>    (merge 55f6bce2c9 fe/doc-updates later to maint).
>    (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).
>    (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).
>    (merge 4c399442f7 ma/commit-graph-docs later to maint).
>    (merge fc0503b04e ma/t1400-undebug-test later to maint).
>    (merge e56b53553a nd/packobjectshook-doc-fix later to maint).
>    (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).
>    (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).
>    (merge ad0b8f9575 mw/doc-typofixes later to maint).
>    (merge d9f079ad1a jc/how-to-document-api later to maint).
>    (merge b1492bf315 ma/t7005-bash-workaround later to maint).
>    (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).
>    (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).
>    (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).
>    (merge 61018fe9e0 du/cherry-is-plumbing later to maint).
>    (merge c7e5fe79b9 sb/strbuf-h-update later to maint).
>    (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).
>    (merge 2e3c894f4b tq/branch-style-fix later to maint).
>    (merge c5d844af9c sg/doc-show-branch-typofix later to maint).
>    (merge 081d91618b ah/doc-updates later to maint).
>    (merge b84c783882 jc/cocci-preincr later to maint).
>    (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).
>    (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).
>    (merge 3063477445 tb/char-may-be-unsigned later to maint).
>    (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
>    (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
>    (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).
>    (merge 3006f5ee16 ma/reset-doc-rendering-fix later to maint).
>    (merge 4c2eb06419 sg/daemon-test-signal-fix later to maint).
>    (merge d27525e519 ss/msvc-strcasecmp later to maint).
> 
> ----------------------------------------------------------------
> 
> Changes since v2.19.0 are as follows:
> 
> Aaron Lindsay (1):
>       send-email: avoid empty transfer encoding header
> 
> Alban Gruin (21):
>       sequencer: make three functions and an enum from sequencer.c public
>       rebase -i: rewrite append_todo_help() in C
>       editor: add a function to launch the sequence editor
>       rebase -i: rewrite the edit-todo functionality in C
>       sequencer: add a new function to silence a command, except if it fails
>       rebase -i: rewrite setup_reflog_action() in C
>       rebase -i: rewrite checkout_onto() in C
>       sequencer: refactor append_todo_help() to write its message to a buffer
>       sequencer: change the way skip_unnecessary_picks() returns its result
>       t3404: todo list with commented-out commands only aborts
>       rebase -i: rewrite complete_action() in C
>       rebase -i: remove unused modes and functions
>       rebase -i: implement the logic to initialize $revisions in C
>       rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C
>       rebase -i: rewrite write_basic_state() in C
>       rebase -i: rewrite init_basic_state() in C
>       rebase -i: implement the main part of interactive rebase as a builtin
>       rebase--interactive2: rewrite the submodes of interactive rebase in C
>       rebase -i: remove git-rebase--interactive.sh
>       rebase -i: move rebase--helper modes to rebase--interactive
>       p3400: replace calls to `git checkout -b' by `git checkout -B'
> 
> Alexander Pyhalov (1):
>       t7005-editor: quote filename to fix whitespace-issue
> 
> Andreas Gruenbacher (1):
>       rev-parse: clear --exclude list after 'git rev-parse --all'
> 
> Andreas Heiduk (6):
>       doc: clarify boundaries of 'git worktree list --porcelain'
>       doc: fix ASCII art tab spacing
>       doc: fix inappropriate monospace formatting
>       doc: fix descripion for 'git tag --format'
>       doc: fix indentation of listing blocks in gitweb.conf.txt
>       doc: fix formatting in git-update-ref
> 
> Anton Serbulov (1):
>       mingw: fix getcwd when the parent directory cannot be queried
> 
> Antonio Ospite (10):
>       submodule: add a print_config_from_gitmodules() helper
>       submodule: factor out a config_set_in_gitmodules_file_gently function
>       t7411: merge tests 5 and 6
>       t7411: be nicer to future tests and really clean things up
>       submodule--helper: add a new 'config' subcommand
>       submodule: use the 'submodule--helper config' command
>       t7506: clean up .gitmodules properly before setting up new scenario
>       submodule: add a helper to check if it is safe to write to .gitmodules
>       submodule: support reading .gitmodules when it's not in the working tree
>       t/helper: add test-submodule-nested-repo-config
> 
> Ben Peart (19):
>       checkout: optimize "git checkout -b <new_branch>"
>       git-mv: allow submodules and fsmonitor to work together
>       t/README: correct spelling of "uncommon"
>       preload-index: use git_env_bool() not getenv() for customization
>       fsmonitor: update GIT_TEST_FSMONITOR support
>       read-cache: update TEST_GIT_INDEX_VERSION support
>       preload-index: update GIT_FORCE_PRELOAD_TEST support
>       read-cache: clean up casting and byte decoding
>       eoie: add End of Index Entry (EOIE) extension
>       config: add new index.threads config setting
>       read-cache: load cache extensions on a worker thread
>       ieot: add Index Entry Offset Table (IEOT) extension
>       read-cache: load cache entries on worker threads
>       reset: don't compute unstaged changes after reset when --quiet
>       reset: add new reset.quiet config setting
>       reset: warn when refresh_index() takes more than 2 seconds
>       speed up refresh_index() by utilizing preload_index()
>       add: speed up cmd_add() by utilizing read_cache_preload()
>       refresh_index: remove unnecessary calls to preload_index()
> 
> Brandon Williams (1):
>       config: document value 2 for protocol.version
> 
> Brendan Forster (1):
>       http: add support for disabling SSL revocation checks in cURL
> 
> Carlo Marcelo Arenas Belón (8):
>       unpack-trees: avoid dead store for struct progress
>       multi-pack-index: avoid dead store for struct progress
>       read-cache: use of memory after it is freed
>       commit-slabs: move MAYBE_UNUSED out
>       khash: silence -Wunused-function for delta-islands
>       compat: make sure git_mmap is not expected to write
>       sequencer: cleanup for gcc warning in non developer mode
>       builtin/notes: remove unnecessary free
> 
> Christian Couder (3):
>       pack-objects: refactor code into compute_layer_order()
>       pack-objects: move tree_depth into 'struct packing_data'
>       pack-objects: move 'layer' into 'struct packing_data'
> 
> Christian Hesse (2):
>       subtree: add build targets 'man' and 'html'
>       subtree: make install targets depend on build targets
> 
> Daniels Umanovskis (3):
>       doc: move git-rev-parse from porcelain to plumbing
>       doc: move git-get-tar-commit-id to plumbing
>       doc: move git-cherry to plumbing
> 
> David Zych (1):
>       doc: clarify gitcredentials path component matching
> 
> Denton Liu (3):
>       mergetool: accept -g/--[no-]gui as arguments
>       completion: support `git mergetool --[no-]gui`
>       doc: document diff/merge.guitool config keys
> 
> Derrick Stolee (93):
>       multi-pack-index: add design document
>       multi-pack-index: add format details
>       multi-pack-index: add builtin
>       multi-pack-index: add 'write' verb
>       midx: write header information to lockfile
>       multi-pack-index: load into memory
>       t5319: expand test data
>       packfile: generalize pack directory list
>       multi-pack-index: read packfile list
>       multi-pack-index: write pack names in chunk
>       midx: read pack names into array
>       midx: sort and deduplicate objects from packfiles
>       midx: write object ids in a chunk
>       midx: write object id fanout chunk
>       midx: write object offsets
>       config: create core.multiPackIndex setting
>       midx: read objects from multi-pack-index
>       midx: use midx in abbreviation calculations
>       midx: use existing midx when writing new one
>       midx: use midx in approximate_object_count
>       midx: prevent duplicate packfile loads
>       packfile: skip loading index if in multi-pack-index
>       midx: clear midx on repack
>       commit-reach: move walk methods from commit.c
>       commit.h: remove method declarations
>       commit-reach: move ref_newer from remote.c
>       commit-reach: move commit_contains from ref-filter
>       upload-pack: make reachable() more generic
>       upload-pack: refactor ok_to_give_up()
>       upload-pack: generalize commit date cutoff
>       commit-reach: move can_all_from_reach_with_flags
>       test-reach: create new test tool for ref_newer
>       test-reach: test in_merge_bases
>       test-reach: test is_descendant_of
>       test-reach: test get_merge_bases_many
>       test-reach: test reduce_heads
>       test-reach: test can_all_from_reach_with_flags
>       test-reach: test commit_contains
>       commit-reach: replace ref_newer logic
>       commit-reach: make can_all_from_reach... linear
>       commit-reach: use can_all_from_reach
>       multi-pack-index: provide more helpful usage info
>       multi-pack-index: store local property
>       midx: mark bad packed objects
>       midx: stop reporting garbage
>       midx: fix bug that skips midx with alternates
>       packfile: add all_packs list
>       treewide: use get_all_packs
>       midx: test a few commands that use get_all_packs
>       pack-objects: consider packs in multi-pack-index
>       commit-graph: update design document
>       test-repository: properly init repo
>       commit-graph: not compatible with replace objects
>       commit-graph: not compatible with grafts
>       commit-graph: not compatible with uninitialized repo
>       commit-graph: close_commit_graph before shallow walk
>       commit-graph: define GIT_TEST_COMMIT_GRAPH
>       t3206-range-diff.sh: cover single-patch case
>       t5318: use test_oid for HASH_LEN
>       multi-pack-index: add 'verify' verb
>       multi-pack-index: verify bad header
>       multi-pack-index: verify corrupt chunk lookup table
>       multi-pack-index: verify packname order
>       multi-pack-index: verify missing pack
>       multi-pack-index: verify oid fanout order
>       multi-pack-index: verify oid lookup order
>       multi-pack-index: fix 32-bit vs 64-bit size check
>       multi-pack-index: verify object offsets
>       multi-pack-index: report progress during 'verify'
>       fsck: verify multi-pack-index
>       commit-reach: properly peel tags
>       commit-reach: fix memory and flag leaks
>       commit-reach: cleanups in can_all_from_reach...
>       commit-graph: clean up leaked memory during write
>       commit-graph: reduce initial oid allocation
>       midx: fix broken free() in close_midx()
>       contrib: add coverage-diff script
>       ci: add optional test variables
>       commit-reach: fix first-parent heuristic
>       midx: close multi-pack-index on repack
>       multi-pack-index: define GIT_TEST_MULTI_PACK_INDEX
>       packfile: close multi-pack-index in close_all_packs
>       prio-queue: add 'peek' operation
>       test-reach: add run_three_modes method
>       test-reach: add rev-list tests
>       revision.c: begin refactoring --topo-order logic
>       commit/revisions: bookkeeping before refactoring
>       revision.c: generation-based topo-order algorithm
>       t6012: make rev-list tests more interesting
>       commit-reach: implement get_reachable_subset
>       test-reach: test get_reachable_subset
>       remote: make add_missing_tags() linear
>       pack-objects: ignore ambiguous object warnings
> 
> Elijah Newren (14):
>       Remove superfluous trailing semicolons
>       t4200: demonstrate rerere segfault on specially crafted merge
>       rerere: avoid buffer overrun
>       update-ref: fix type of update_flags variable to match its usage
>       update-ref: allow --no-deref with --stdin
>       sequencer: fix --allow-empty-message behavior, make it smarter
>       merge-recursive: set paths correctly when three-way merging content
>       merge-recursive: avoid wrapper function when unnecessary and wasteful
>       merge-recursive: remove final remaining caller of merge_file_one()
>       merge-recursive: rename merge_file_1() and merge_content()
>       commit: fix erroneous BUG, 'multiple renames on the same target? how?'
>       merge-recursive: improve auto-merging messages with path collisions
>       merge-recursive: avoid showing conflicts with merge branch before HEAD
>       fsck: move fsck_head_link() to get_default_heads() to avoid some globals
> 
> Eric Sunshine (26):
>       format-patch: allow additional generated content in make_cover_letter()
>       format-patch: add --interdiff option to embed diff in cover letter
>       format-patch: teach --interdiff to respect -v/--reroll-count
>       interdiff: teach show_interdiff() to indent interdiff
>       log-tree: show_log: make commentary block delimiting reusable
>       format-patch: allow --interdiff to apply to a lone-patch
>       range-diff: respect diff_option.file rather than assuming 'stdout'
>       range-diff: publish default creation factor
>       range-diff: relieve callers of low-level configuration burden
>       format-patch: add --range-diff option to embed diff in cover letter
>       format-patch: extend --range-diff to accept revision range
>       format-patch: teach --range-diff to respect -v/--reroll-count
>       format-patch: add --creation-factor tweak for --range-diff
>       format-patch: allow --range-diff to apply to a lone-patch
>       worktree: don't die() in library function find_worktree()
>       worktree: move delete_git_dir() earlier in file for upcoming new callers
>       worktree: generalize delete_git_dir() to reduce code duplication
>       worktree: prepare for more checks of whether path can become worktree
>       worktree: disallow adding same path multiple times
>       worktree: teach 'add' to respect --force for registered but missing path
>       worktree: teach 'move' to override lock when --force given twice
>       worktree: teach 'remove' to override lock when --force given twice
>       worktree: delete .git/worktrees if empty after 'remove'
>       doc-diff: fix non-portable 'man' invocation
>       doc-diff: add --clean mode to remove temporary working gunk
>       doc/Makefile: drop doc-diff worktree and temporary files on "make clean"
> 
> Frederick Eaton (3):
>       git-archimport.1: specify what kind of Arch we're talking about
>       git-column.1: clarify initial description, provide examples
>       git-describe.1: clarify that "human readable" is also git-readable
> 
> Greg Hurrell (1):
>       doc: update diff-format.txt for removed ellipses in --raw
> 
> James Knight (1):
>       build: link with curl-defined linker flags
> 
> Jann Horn (2):
>       patch-delta: fix oob read
>       patch-delta: consistently report corruption
> 
> Jean-Noël Avila (1):
>       i18n: fix small typos
> 
> Jeff Hostetler (2):
>       t0051: test GIT_TRACE to a windows named pipe
>       mingw: fix mingw_open_append to work with named pipes
> 
> Jeff King (98):
>       branch: make "-l" a synonym for "--list"
>       Add delta-islands.{c,h}
>       pack-objects: add delta-islands support
>       repack: add delta-islands support
>       t5320: tests for delta islands
>       t/perf: factor boilerplate out of test_perf
>       t/perf: factor out percent calculations
>       t/perf: add infrastructure for measuring sizes
>       t/perf: add perf tests for fetches from a bitmapped server
>       pack-bitmap: save "have" bitmap from walk
>       pack-objects: reuse on-disk deltas for thin "have" objects
>       SubmittingPatches: mention doc-diff
>       rev-list: make empty --stdin not an error
>       trailer: use size_t for string offsets
>       trailer: use size_t for iterating trailer list
>       trailer: pass process_trailer_opts to trailer_info_get()
>       interpret-trailers: tighten check for "---" patch boundary
>       interpret-trailers: allow suppressing "---" divider
>       pretty, ref-filter: format %(trailers) with no_divider option
>       sequencer: ignore "---" divider when parsing trailers
>       append_signoff: use size_t for string offsets
>       coccinelle: use <...> for function exclusion
>       introduce hasheq() and oideq()
>       convert "oidcmp() == 0" to oideq()
>       convert "hashcmp() == 0" to hasheq()
>       convert "oidcmp() != 0" to "!oideq()"
>       convert "hashcmp() != 0" to "!hasheq()"
>       convert hashmap comparison functions to oideq()
>       read-cache: use oideq() in ce_compare functions
>       show_dirstat: simplify same-content check
>       doc-diff: always use oids inside worktree
>       test-delta: read input into a heap buffer
>       t5303: test some corrupt deltas
>       patch-delta: handle truncated copy parameters
>       t5303: use printf to generate delta bases
>       doc/git-branch: remove obsolete "-l" references
>       bitmap_has_sha1_in_uninteresting(): drop BUG check
>       t5310: test delta reuse with bitmaps
>       traverse_bitmap_commit_list(): don't free result
>       pack-bitmap: drop "loaded" flag
>       reopen_tempfile(): truncate opened file
>       doc-diff: force worktree add
>       config.mak.dev: add -Wformat-security
>       pack-objects: handle island check for "external" delta base
>       receive-pack: update comment with check_everything_connected
>       submodule--helper: use "--" to signal end of clone options
>       submodule-config: ban submodule urls that start with dash
>       submodule-config: ban submodule paths that start with a dash
>       fsck: detect submodule urls starting with dash
>       fsck: detect submodule paths starting with dash
>       more oideq/hasheq conversions
>       transport: drop refnames from for_each_alternate_ref
>       test-tool: show tool list on error
>       config.mak.dev: enable -Wunused-function
>       run-command: mark path lookup errors with ENOENT
>       t5410: use longer path for sample script
>       upload-pack: fix broken if/else chain in config callback
>       t1450: check large blob in trailing-garbage test
>       check_stream_sha1(): handle input underflow
>       cat-file: handle streaming failures consistently
>       ls-remote: do not send ref prefixes for patterns
>       ls-remote: pass heads/tags prefixes to transport
>       read_istream_pack_non_delta(): document input handling
>       xdiff: provide a separate emit callback for hunks
>       xdiff-interface: provide a separate consume callback for hunks
>       rev-list: handle flags for --indexed-objects
>       approxidate: handle pending number for "specials"
>       pathspec: handle non-terminated strings with :(attr)
>       diff: avoid generating unused hunk header lines
>       diff: discard hunk headers for patch-ids earlier
>       diff: use hunk callback for word-diff
>       combine-diff: use an xdiff hunk callback
>       diff: convert --check to use a hunk callback
>       range-diff: use a hunk callback
>       xdiff-interface: drop parse_hunk_header()
>       apply: mark include/exclude options as NONEG
>       am: handle --no-patch-format option
>       ls-files: mark exclude options as NONEG
>       pack-objects: mark index-version option as NONEG
>       cat-file: mark batch options with NONEG
>       status: mark --find-renames option with NONEG
>       format-patch: mark "--no-numbered" option with NONEG
>       show-branch: mark --reflog option as NONEG
>       tag: mark "--message" option with NONEG
>       cat-file: report an error on multiple --batch options
>       apply: return -1 from option callback instead of calling exit(1)
>       parse-options: drop OPT_DATE()
>       assert NOARG/NONEG behavior of parse-options callbacks
>       midx: double-check large object write loop
>       merge: extract verify_merge_signature() helper
>       merge: handle --verify-signatures for unborn branch
>       pull: handle --verify-signatures for unborn branch
>       approxidate: fix NULL dereference in date_time()
>       bundle: dup() output descriptor closer to point-of-use
>       pack-objects: fix tree_depth and layer invariants
>       pack-objects: zero-initialize tree_depth/layer arrays
>       pack-objects: fix off-by-one in delta-island tree-depth computation
>       t5562: fix perl path
> 
> Johannes Schindelin (64):
>       rebase -i --autosquash: demonstrate a problem skipping the last squash
>       rebase -i: be careful to wrap up fixup/squash chains
>       compat/poll: prepare for targeting Windows Vista
>       mingw: set _WIN32_WINNT explicitly for Git for Windows
>       mingw: bump the minimum Windows version to Vista
>       builtin rebase: prepare for builtin rebase -i
>       rebase -i: clarify what happens on a failed `exec`
>       rebase -i: introduce the 'break' command
>       getpwuid(mingw): initialize the structure only once
>       getpwuid(mingw): provide a better default for the user name
>       mingw: use domain information for default email
>       http: add support for selecting SSL backends at runtime
>       pack-objects: fix typo 'detla' -> 'delta'
>       pack-objects (mingw): demonstrate a segmentation fault with large deltas
>       pack-objects (mingw): initialize `packing_data` mutex in the correct spot
>       rebase (autostash): avoid duplicate call to state_dir_path()
>       rebase (autostash): store the full OID in <state-dir>/autostash
>       rebase (autostash): use an explicit OID to apply the stash
>       mingw: factor out code to set stat() data
>       rebase --autostash: demonstrate a problem with dirty submodules
>       rebase --autostash: fix issue with dirty submodules
>       mingw: load system libraries the recommended way
>       mingw: ensure `getcwd()` reports the correct case
>       repack: point out a bug handling stale shallow info
>       shallow: offer to prune only non-existing entries
>       repack -ad: prune the list of shallow commits
>       http: when using Secure Channel, ignore sslCAInfo by default
>       t7800: fix quoting
>       mingw: reencode environment variables on the fly (UTF-16 <-> UTF-8)
>       config: rename `dummy` parameter to `cb` in git_default_config()
>       config: allow for platform-specific core.* config settings
>       config: move Windows-specific config settings into compat/mingw.c
>       mingw: unset PERL5LIB by default
>       mingw: fix isatty() after dup2()
>       t3404: decouple some test cases from outcomes of previous test cases
>       t3418: decouple test cases from a previous `rebase -p` test case
>       tests: optionally skip `git rebase -p` tests
>       Windows: force-recompile git.res for differing architectures
>       built-in rebase: demonstrate regression with --autostash
>       built-in rebase --autostash: leave the current branch alone if possible
>       Update .mailmap
>       rebase -r: demonstrate bug with conflicting merges
>       rebase -r: do not write MERGE_HEAD unless needed
>       rebase -i: include MERGE_HEAD into files to clean up
>       built-in rebase --skip/--abort: clean up stale .git/<name> files
>       status: rebase and merge can be in progress at the same time
>       apply --recount: allow "no-op hunks"
>       rebase: consolidate clean-up code before leaving reset_head()
>       rebase: prepare reset_head() for more flags
>       built-in rebase: reinstate `checkout -q` behavior where appropriate
>       tests: fix GIT_TEST_INSTALLED's PATH to include t/helper/
>       tests: respect GIT_TEST_INSTALLED when initializing repositories
>       t/lib-gettext: test installed git-sh-i18n if GIT_TEST_INSTALLED is set
>       mingw: use `CreateHardLink()` directly
>       rebase: really just passthru the `git am` options
>       rebase: validate -C<n> and --whitespace=<mode> parameters early
>       config: report a bug if git_dir exists without commondir
>       tests: do not require Git to be built when testing an installed Git
>       tests: explicitly use `git.exe` on Windows
>       mingw: replace an obsolete link with the superseding one
>       legacy-rebase: backport -C<n> and --whitespace=<option> checks
>       rebase: warn about the correct tree's OID
>       rebase: fix GIT_REFLOG_ACTION regression
>       rebase --stat: fix when rebasing to an unrelated history
> 
> Johannes Sixt (3):
>       diff: don't attempt to strip prefix from absolute Windows paths
>       rebase -i: recognize short commands without arguments
>       t3404-rebase-interactive: test abbreviated commands
> 
> Jonathan Nieder (9):
>       gc: improve handling of errors reading gc.log
>       gc: exit with status 128 on failure
>       gc: do not return error for prior errors in daemonized mode
>       commit-reach: correct accidental #include of C file
>       mailmap: consistently normalize brian m. carlson's name
>       git doc: direct bug reporters to mailing list archive
>       eoie: default to not writing EOIE section
>       ieot: default to not writing IEOT section
>       index: make index.threads=true enable ieot and eoie
> 
> Jonathan Tan (15):
>       fetch-object: unify fetch_object[s] functions
>       fetch-object: set exact_oid when fetching
>       connected: document connectivity in partial clones
>       fetch: in partial clone, check presence of targets
>       fetch-pack: avoid object flags if no_dependents
>       fetch-pack: exclude blobs when lazy-fetching trees
>       transport: allow skipping of ref listing
>       transport: do not list refs if possible
>       transport: list refs before fetch if necessary
>       fetch: do not list refs if fetching only hashes
>       cache-tree: skip some blob checks in partial clone
>       upload-pack: make have_obj not global
>       upload-pack: make want_obj not global
>       upload-pack: clear flags before each v2 request
>       fetch-pack: be more precise in parsing v2 response
> 
> Josh Steadmon (4):
>       fuzz: add basic fuzz testing target.
>       fuzz: add fuzz testing for packfile indices.
>       archive: initialize archivers earlier
>       Makefile: use FUZZ_CXXFLAGS for linking fuzzers
> 
> Joshua Watt (1):
>       send-email: explicitly disable authentication
> 
> Junio C Hamano (36):
>       Revert "doc/Makefile: drop doc-diff worktree and temporary files on "make clean""
>       Initial batch post 2.19
>       Second batch post 2.19
>       Git 2.14.5
>       Git 2.15.3
>       Git 2.16.5
>       Git 2.17.2
>       Git 2.18.1
>       Git 2.19.1
>       t0000: do not get self-test disrupted by environment warnings
>       CodingGuidelines: document the API in *.h files
>       Declare that the next one will be named 2.20
>       Third batch for 2.20
>       rebase: fix typoes in error messages
>       Fourth batch for 2.20
>       Revert "subtree: make install targets depend on build targets"
>       Fifth batch for 2.20
>       receive: denyCurrentBranch=updateinstead should not blindly update
>       cocci: simplify "if (++u > 1)" to "if (u++)"
>       fsck: s/++i > 1/i++/
>       http: give curl version warnings consistently
>       Sixth batch for 2.20
>       Seventh batch for 2.20
>       fetch: replace string-list used as a look-up table with a hashmap
>       rebase: apply cocci patch
>       Eighth batch for 2.20
>       Ninth batch for 2.20
>       Makefile: ease dynamic-gettext-poison transition
>       Tenth batch for 2.20
>       Git 2.20-rc0
>       RelNotes: name the release properly
>       Prepare for 2.20-rc1
>       Git 2.19.2
>       Git 2.20-rc1
>       format-patch: do not let its diff-options affect --range-diff
>       Git 2.20-rc2
> 
> Karsten Blees (2):
>       mingw: replace MSVCRT's fstat() with a Win32-based implementation
>       mingw: implement nanosecond-precision file times
> 
> Loo Rong Jie (1):
>       win32: replace pthread_cond_*() with much simpler code
> 
> Lucas De Marchi (1):
>       range-diff: allow to diff files regardless of submodule config
> 
> Luke Diamand (3):
>       git-p4: do not fail in verbose mode for missing 'fileSize' key
>       git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved
>       git-p4: fully support unshelving changelists
> 
> Martin Ågren (11):
>       Doc: use `--type=bool` instead of `--bool`
>       git-config.txt: fix 'see: above' note
>       git-commit-graph.txt: fix bullet lists
>       git-commit-graph.txt: typeset more in monospace
>       git-commit-graph.txt: refer to "*commit*-graph file"
>       Doc: refer to the "commit-graph file" with dash
>       t1400: drop debug `echo` to actually execute `test`
>       builtin/commit-graph.c: UNLEAK variables
>       sequencer: break out of loop explicitly
>       git-reset.txt: render tables correctly under Asciidoctor
>       git-reset.txt: render literal examples as monospace
> 
> Matthew DeVore (19):
>       list-objects: store common func args in struct
>       list-objects: refactor to process_tree_contents
>       list-objects: always parse trees gently
>       t/README: reformat Do, Don't, Keep in mind lists
>       Documentation: add shell guidelines
>       tests: standardize pipe placement
>       t/*: fix ordering of expected/observed arguments
>       tests: don't swallow Git errors upstream of pipes
>       t9109: don't swallow Git errors upstream of pipes
>       tests: order arguments to git-rev-list properly
>       rev-list: handle missing tree objects properly
>       revision: mark non-user-given objects instead
>       list-objects-filter: use BUG rather than die
>       list-objects-filter-options: do not over-strbuf_init
>       list-objects-filter: implement filter tree:0
>       filter-trees: code clean-up of tests
>       list-objects: support for skipping tree traversal
>       Documentation/git-log.txt: do not show --exclude-promisor-objects
>       exclude-promisor-objects: declare when option is allowed
> 
> Max Kirillov (1):
>       http-backend test: make empty CONTENT_LENGTH test more realistic
> 
> Michael Witten (3):
>       docs: typo: s/go/to/
>       docs: graph: remove unnecessary `graph_update()' call
>       docs: typo: s/isimilar/similar/
> 
> Michał Górny (6):
>       gpg-interface.c: detect and reject multiple signatures on commits
>       gpg-interface.c: use flags to determine key/signer info presence
>       gpg-interface.c: support getting key fingerprint via %GF format
>       gpg-interface.c: obtain primary key fingerprint as well
>       t/t7510-signed-commit.sh: Add %GP to custom format checks
>       t/t7510-signed-commit.sh: add signing subkey to Eris Discordia key
> 
> Mihir Mehta (1):
>       doc: fix a typo and clarify a sentence
> 
> Nguyễn Thái Ngọc Duy (170):
>       clone: report duplicate entries on case-insensitive filesystems
>       trace.h: support nested performance tracing
>       unpack-trees: add performance tracing
>       unpack-trees: optimize walking same trees with cache-tree
>       unpack-trees: reduce malloc in cache-tree walk
>       unpack-trees: reuse (still valid) cache-tree from src_index
>       unpack-trees: add missing cache invalidation
>       cache-tree: verify valid cache-tree in the test suite
>       Document update for nd/unpack-trees-with-cache-tree
>       bisect.c: make show_list() build again
>       t/helper: keep test-tool command list sorted
>       t/helper: merge test-dump-untracked-cache into test-tool
>       t/helper: merge test-pkt-line into test-tool
>       t/helper: merge test-parse-options into test-tool
>       t/helper: merge test-dump-fsmonitor into test-tool
>       Makefile: add a hint about TEST_BUILTINS_OBJS
>       config.txt: follow camelCase naming
>       config.txt: move fetch part out to a separate file
>       config.txt: move format part out to a separate file
>       config.txt: move gitcvs part out to a separate file
>       config.txt: move gui part out to a separate file
>       config.txt: move pull part out to a separate file
>       config.txt: move push part out to a separate file
>       config.txt: move receive part out to a separate file
>       config.txt: move sendemail part out to a separate file
>       config.txt: move sequence.editor out of "core" part
>       config.txt: move submodule part out to a separate file
>       archive.c: remove implicit dependency the_repository
>       status: show progress bar if refreshing the index takes too long
>       add: do not accept pathspec magic 'attr'
>       completion: support "git fetch --multiple"
>       read-cache.c: remove 'const' from index_has_changes()
>       diff.c: reduce implicit dependency on the_index
>       combine-diff.c: remove implicit dependency on the_index
>       blame.c: rename "repo" argument to "r"
>       diff.c: remove the_index dependency in textconv() functions
>       grep.c: remove implicit dependency on the_index
>       diff.c: remove implicit dependency on the_index
>       read-cache.c: remove implicit dependency on the_index
>       diff-lib.c: remove implicit dependency on the_index
>       ll-merge.c: remove implicit dependency on the_index
>       merge-blobs.c: remove implicit dependency on the_index
>       merge.c: remove implicit dependency on the_index
>       patch-ids.c: remove implicit dependency on the_index
>       sha1-file.c: remove implicit dependency on the_index
>       rerere.c: remove implicit dependency on the_index
>       userdiff.c: remove implicit dependency on the_index
>       line-range.c: remove implicit dependency on the_index
>       submodule.c: remove implicit dependency on the_index
>       tree-diff.c: remove implicit dependency on the_index
>       ws.c: remove implicit dependency on the_index
>       revision.c: remove implicit dependency on the_index
>       revision.c: reduce implicit dependency the_repository
>       read-cache.c: optimize reading index format v4
>       config.txt: correct the note about uploadpack.packObjectsHook
>       help -a: improve and make --verbose default
>       refs.c: indent with tabs, not spaces
>       Add a place for (not) sharing stuff between worktrees
>       submodule.c: remove some of the_repository references
>       completion: fix __gitcomp_builtin no longer consider extra options
>       t1300: extract and use test_cmp_config()
>       worktree: add per-worktree config files
>       refs: new ref types to make per-worktree refs visible to all worktrees
>       revision.c: correct a parameter name
>       revision.c: better error reporting on ref from different worktrees
>       fsck: check HEAD and reflog from other worktrees
>       reflog expire: cover reflog from all worktrees
>       Update makefile in preparation for Documentation/config/*.txt
>       config.txt: move advice.* to a separate file
>       config.txt: move core.* to a separate file
>       config.txt: move add.* to a separate file
>       config.txt: move alias.* to a separate file
>       config.txt: move am.* to a separate file
>       config.txt: move apply.* to a separate file
>       config.txt: move blame.* to a separate file
>       config.txt: move branch.* to a separate file
>       config.txt: move browser.* to a separate file
>       config.txt: move checkout.* to a separate file
>       config.txt: move clean.* to a separate file
>       config.txt: move color.* to a separate file
>       config.txt: move column.* to a separate file
>       config.txt: move commit.* to a separate file
>       config.txt: move credential.* to a separate file
>       config.txt: move completion.* to a separate file
>       config.txt: move diff-config.txt to config/
>       config.txt: move difftool.* to a separate file
>       config.txt: move fastimport.* to a separate file
>       config.txt: move fetch-config.txt to config/
>       config.txt: move filter.* to a separate file
>       config.txt: move format-config.txt to config/
>       config.txt: move fmt-merge-msg-config.txt to config/
>       config.txt: move fsck.* to a separate file
>       config.txt: move gc.* to a separate file
>       config.txt: move gitcvs-config.txt to config/
>       config.txt: move gitweb.* to a separate file
>       config.txt: move grep.* to a separate file
>       config.txt: move gpg.* to a separate file
>       config.txt: move gui-config.txt to config/
>       config.txt: move guitool.* to a separate file
>       config.txt: move help.* to a separate file
>       config.txt: move ssh.* to a separate file
>       config.txt: move http.* to a separate file
>       config.txt: move i18n.* to a separate file
>       git-imap-send.txt: move imap.* to a separate file
>       config.txt: move index.* to a separate file
>       config.txt: move init.* to a separate file
>       config.txt: move instaweb.* to a separate file
>       config.txt: move interactive.* to a separate file
>       config.txt: move log.* to a separate file
>       config.txt: move mailinfo.* to a separate file
>       config.txt: move mailmap.* to a separate file
>       config.txt: move man.* to a separate file
>       config.txt: move merge-config.txt to config/
>       config.txt: move mergetool.* to a separate file
>       config.txt: move notes.* to a separate file
>       config.txt: move pack.* to a separate file
>       config.txt: move pager.* to a separate file
>       config.txt: move pretty.* to a separate file
>       config.txt: move protocol.* to a separate file
>       config.txt: move pull-config.txt to config/
>       config.txt: move push-config.txt to config/
>       config.txt: move rebase-config.txt to config/
>       config.txt: move receive-config.txt to config/
>       config.txt: move remote.* to a separate file
>       config.txt: move remotes.* to a separate file
>       config.txt: move repack.* to a separate file
>       config.txt: move rerere.* to a separate file
>       config.txt: move reset.* to a separate file
>       config.txt: move sendemail-config.txt to config/
>       config.txt: move sequencer.* to a separate file
>       config.txt: move showBranch.* to a separate file
>       config.txt: move splitIndex.* to a separate file
>       config.txt: move status.* to a separate file
>       config.txt: move stash.* to a separate file
>       config.txt: move submodule.* to a separate file
>       config.txt: move tag.* to a separate file
>       config.txt: move transfer.* to a separate file
>       config.txt: move uploadarchive.* to a separate file
>       config.txt: move uploadpack.* to a separate file
>       config.txt: move url.* to a separate file
>       config.txt: move user.* to a separate file
>       config.txt: move versionsort.* to a separate file
>       config.txt: move web.* to a separate file
>       config.txt: move worktree.* to a separate file
>       config.txt: remove config/dummy.txt
>       thread-utils: macros to unconditionally compile pthreads API
>       wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode
>       git-worktree.txt: correct linkgit command name
>       sequencer.c: remove a stray semicolon
>       tree-walk.c: fix overoptimistic inclusion in :(exclude) matching
>       run-command.h: include thread-utils.h instead of pthread.h
>       send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c
>       index-pack: remove #ifdef NO_PTHREADS
>       name-hash.c: remove #ifdef NO_PTHREADS
>       attr.c: remove #ifdef NO_PTHREADS
>       grep: remove #ifdef NO_PTHREADS
>       grep: clean up num_threads handling
>       preload-index.c: remove #ifdef NO_PTHREADS
>       pack-objects: remove #ifdef NO_PTHREADS
>       read-cache.c: remove #ifdef NO_PTHREADS
>       read-cache.c: reduce branching based on HAVE_THREADS
>       read-cache.c: initialize copy_len to shut up gcc 8
>       Clean up pthread_create() error handling
>       completion: use __gitcomp_builtin for format-patch
>       build: fix broken command-list.h generation with core.autocrlf
>       format-patch: respect --stat in cover letter's diffstat
>       doc: move extensions.worktreeConfig to the right place
>       clone: fix colliding file detection on APFS
>       files-backend.c: fix build error on Solaris
>       transport-helper.c: do not translate a string twice
> 
> Nickolai Belakovski (2):
>       worktree: update documentation for lock_reason and lock_reason_valid
>       worktree: rename is_worktree_locked to worktree_lock_reason
> 
> Noam Postavsky (1):
>       log: fix coloring of certain octopus merge shapes
> 
> Olga Telezhnaya (3):
>       ref-filter: free memory from used_atom
>       ls-remote: release memory instead of UNLEAK
>       ref-filter: free item->value and item->value->s
> 
> Phillip Wood (11):
>       diff: fix --color-moved-ws=allow-indentation-change
>       diff --color-moved-ws: fix double free crash
>       diff --color-moved-ws: fix out of bounds string access
>       diff --color-moved-ws: fix a memory leak
>       diff --color-moved-ws: fix another memory leak
>       diff --color-moved: fix a memory leak
>       am: don't die in read_author_script()
>       am: improve author-script error reporting
>       am: rename read_author_script()
>       add read_author_script() to libgit
>       sequencer: use read_author_script()
> 
> Pratik Karki (46):
>       rebase: start implementing it as a builtin
>       rebase: refactor common shell functions into their own file
>       builtin/rebase: support running "git rebase <upstream>"
>       builtin rebase: support --onto
>       builtin rebase: support `git rebase --onto A...B`
>       builtin rebase: handle the pre-rebase hook and --no-verify
>       builtin rebase: support --quiet
>       builtin rebase: support the `verbose` and `diffstat` options
>       builtin rebase: require a clean worktree
>       builtin rebase: try to fast forward when possible
>       builtin rebase: support --force-rebase
>       builtin rebase: start a new rebase only if none is in progress
>       builtin rebase: only store fully-qualified refs in `options.head_name`
>       builtin rebase: support `git rebase <upstream> <switch-to>`
>       builtin rebase: support --continue
>       builtin rebase: support --skip
>       builtin rebase: support --abort
>       builtin rebase: support --quit
>       builtin rebase: support --edit-todo and --show-current-patch
>       builtin rebase: actions require a rebase in progress
>       builtin rebase: stop if `git am` is in progress
>       builtin rebase: allow selecting the rebase "backend"
>       builtin rebase: support --signoff
>       builtin rebase: support --rerere-autoupdate
>       builtin rebase: support --committer-date-is-author-date
>       builtin rebase: support `ignore-whitespace` option
>       builtin rebase: support `ignore-date` option
>       builtin rebase: support `keep-empty` option
>       builtin rebase: support `--autosquash`
>       builtin rebase: support `--gpg-sign` option
>       builtin rebase: support `-C` and `--whitespace=<type>`
>       builtin rebase: support `--autostash` option
>       builtin rebase: support `--exec`
>       builtin rebase: support `--allow-empty-message` option
>       builtin rebase: support --rebase-merges[=[no-]rebase-cousins]
>       merge-base --fork-point: extract libified function
>       builtin rebase: support `fork-point` option
>       builtin rebase: add support for custom merge strategies
>       builtin rebase: support --root
>       builtin rebase: optionally auto-detect the upstream
>       builtin rebase: optionally pass custom reflogs to reset_head()
>       builtin rebase: fast-forward to onto if it is a proper descendant
>       builtin rebase: show progress when connected to a terminal
>       builtin rebase: use no-op editor when interactive is "implied"
>       builtin rebase: error out on incompatible option/mode combinations
>       rebase: default to using the builtin rebase
> 
> Rafael Ascensão (2):
>       refs: show --exclude failure with --branches/tags/remotes=glob
>       refs: fix some exclude patterns being ignored
> 
> Ralf Thielow (2):
>       git-rebase.sh: fix typos in error messages
>       builtin/rebase.c: remove superfluous space in messages
> 
> Ramsay Jones (12):
>       Makefile: add a hdr-check target
>       json-writer.h: add missing include (hdr-check)
>       ewah/ewok_rlw.h: add missing include (hdr-check)
>       refs/ref-cache.h: add missing declarations (hdr-check)
>       refs/packed-backend.h: add missing declaration (hdr-check)
>       refs/refs-internal.h: add missing declarations (hdr-check)
>       midx.h: add missing forward declarations (hdr-check)
>       delta-islands.h: add missing forward declarations (hdr-check)
>       headers: normalize the spelling of some header guards
>       fetch-object.h: add missing declaration (hdr-check)
>       ewok_rlw.h: add missing 'inline' to function definition
>       commit-reach.h: add missing declarations (hdr-check)
> 
> Rasmus Villemoes (6):
>       help: redirect to aliased commands for "git cmd --help"
>       git.c: handle_alias: prepend alias info when first argument is -h
>       git-help.txt: document "git help cmd" vs "git cmd --help" for aliases
>       Documentation/git-send-email.txt: style fixes
>       send-email: only consider lines containing @ or <> for automatic Cc'ing
>       send-email: also pick up cc addresses from -by trailers
> 
> René Scharfe (12):
>       mailinfo: support format=flowed
>       fsck: add a performance test for skipList
>       fsck: use strbuf_getline() to read skiplist file
>       fsck: use oidset instead of oid_array for skipList
>       sequencer: use return value of oidset_insert()
>       grep: add -r/--[no-]recursive
>       fetch-pack: factor out is_unmatched_ref()
>       fetch-pack: load tip_oids eagerly iff needed
>       khash: factor out kh_release_*
>       oidset: use khash
>       oidset: uninline oidset_init()
>       commit-reach: fix cast in compare_commits_by_gen()
> 
> Roger Strain (1):
>       subtree: performance improvement for finding unexpected parent commits
> 
> SZEDER Gábor (20):
>       t1404: increase core.packedRefsTimeout to avoid occasional test failure
>       Documentation/git.txt: clarify that GIT_TRACE=/path appends
>       t3701-add-interactive: tighten the check of trace output
>       t1700-split-index: drop unnecessary 'grep'
>       t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
>       t1700-split-index: document why FSMONITOR is disabled in this test script
>       split-index: add tests to demonstrate the racy split index problem
>       t1700-split-index: date back files to avoid racy situations
>       split-index: count the number of deleted entries
>       split-index: don't compare cached data of entries already marked for split index
>       split-index: smudge and add racily clean cache entries to split index
>       split-index: BUG() when cache entry refers to non-existing shared entry
>       object_id.cocci: match only expressions of type 'struct object_id'
>       test-lib: introduce the '-V' short option for '--verbose-log'
>       travis-ci: install packages in 'ci/install-dependencies.sh'
>       coccicheck: introduce 'pending' semantic patches
>       ref-filter: don't look for objects when outside of a repository
>       tests: send "bug in the test script" errors to the script's stderr
>       test-lib-functions: make 'test_cmp_rev' more informative on failure
>       t/lib-git-daemon: fix signal checking
> 
> Sam McKelvie (1):
>       rev-parse: --show-superproject-working-tree should work during a merge
> 
> Saulius Gurklys (1):
>       doc: fix small typo in git show-branch
> 
> Sebastian Staudt (1):
>       travis-ci: no longer use containers
> 
> Shulhan (1):
>       builtin/remote: quote remote name on error to display empty name
> 
> Stefan Beller (25):
>       git-submodule.sh: align error reporting for update mode to use path
>       git-submodule.sh: rename unused variables
>       builtin/submodule--helper: factor out submodule updating
>       builtin/submodule--helper: store update_clone information in a struct
>       builtin/submodule--helper: factor out method to update a single submodule
>       submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
>       submodule--helper: introduce new update-module-mode helper
>       test_decode_color: understand FAINT and ITALIC
>       t3206: add color test for range-diff --dual-color
>       diff.c: simplify caller of emit_line_0
>       diff.c: reorder arguments for emit_line_ws_markup
>       diff.c: add set_sign to emit_line_0
>       diff: use emit_line_0 once per line
>       diff.c: omit check for line prefix in emit_line_0
>       diff.c: rewrite emit_line_0 more understandably
>       diff.c: add --output-indicator-{new, old, context}
>       range-diff: make use of different output indicators
>       range-diff: indent special lines as context
>       refs.c: migrate internal ref iteration to pass thru repository argument
>       refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
>       string-list: remove unused function print_string_list
>       strbuf.h: format according to coding guidelines
>       diff.c: pass sign_index to emit_line_ws_markup
>       submodule helper: convert relative URL to absolute URL if needed
>       builtin/submodule--helper: remove debugging leftover tracing
> 
> Stephen P. Smith (10):
>       wt-status.c: move has_unmerged earlier in the file
>       wt-status: rename commitable to committable
>       t7501: add test of "commit --dry-run --short"
>       wt-status.c: set the committable flag in the collect phase
>       roll wt_status_state into wt_status and populate in the collect phase
>       t2000: rename and combine checkout clash tests
>       t7509: cleanup description and filename
>       t7502: rename commit test script to comply with naming convention
>       t7500: rename commit tests script to comply with naming convention
>       t7501: rename commit test to comply with naming convention
> 
> Steve Hoelzer (1):
>       poll: use GetTickCount64() to avoid wrap-around issues
> 
> Steven Fernandez (1):
>       git-completion.bash: add completion for stash list
> 
> Strain, Roger L (4):
>       subtree: refactor split of a commit into standalone method
>       subtree: make --ignore-joins pay attention to adds
>       subtree: use commits before rejoins for splits
>       subtree: improve decision on merges kept in split
> 
> Sven Strickroth (1):
>       msvc: directly use MS version (_stricmp) of strcasecmp
> 
> Tao Qingyun (3):
>       refs: docstring typo
>       builtin/branch.c: remove useless branch_get
>       branch: trivial style fix
> 
> Taylor Blau (4):
>       transport.c: extract 'fill_alternate_refs_command'
>       transport.c: introduce core.alternateRefsCommand
>       transport.c: introduce core.alternateRefsPrefixes
>       Documentation/config.txt: fix typo in core.alternateRefsCommand
> 
> Thomas Gummerer (17):
>       rerere: unify error messages when read_cache fails
>       rerere: lowercase error messages
>       rerere: wrap paths in output in sq
>       rerere: mark strings for translation
>       rerere: add documentation for conflict normalization
>       rerere: fix crash with files rerere can't handle
>       rerere: only return whether a path has conflicts or not
>       rerere: factor out handle_conflict function
>       rerere: return strbuf from handle path
>       rerere: teach rerere to handle nested conflicts
>       rerere: recalculate conflict ID when unresolved conflict is committed
>       rerere: mention caveat about unmatched conflict markers
>       rerere: add note about files with existing conflict markers
>       .gitattributes: add conflict-marker-size for relevant files
>       linear-assignment: fix potential out of bounds memory access
>       t5551: move setup code inside test_expect blocks
>       t5551: compare sorted cookies files
> 
> Tim Schumacher (4):
>       Documentation/Makefile: make manpage-base-url.xsl generation quieter
>       alias: add support for aliases of an alias
>       alias: show the call history when an alias is looping
>       t0014: introduce an alias testing suite
> 
> Todd Zullinger (1):
>       Documentation: build technical/multi-pack-index
> 
> Torsten Bögershausen (5):
>       Make git_check_attr() a void function
>       path.c: char is not (always) signed
>       Upcast size_t variables to uintmax_t when printing
>       remote-curl.c: xcurl_off_t is not portable (on 32 bit platfoms)
>       t5601-99: Enable colliding file detection for MINGW
> 
> Uwe Kleine-König (1):
>       howto/using-merge-subtree: mention --allow-unrelated-histories
> 
> brian m. carlson (26):
>       t: add test functions to translate hash-related values
>       t0000: use hash translation table
>       t0000: update tests for SHA-256
>       t0002: abstract away SHA-1 specific constants
>       t0064: make hash size independent
>       t1006: make hash size independent
>       t1400: switch hard-coded object ID to variable
>       t1405: make hash size independent
>       t1406: make hash-size independent
>       t1407: make hash size independent
>       editorconfig: provide editor settings for Git developers
>       editorconfig: indicate settings should be kept in sync
>       pack-bitmap-write: use GIT_MAX_RAWSZ for allocation
>       builtin/repack: replace hard-coded constants
>       builtin/mktree: remove hard-coded constant
>       builtin/fetch-pack: remove constants with parse_oid_hex
>       pack-revindex: express constants in terms of the_hash_algo
>       packfile: express constants in terms of the_hash_algo
>       refs/packed-backend: express constants using the_hash_algo
>       upload-pack: express constants in terms of the_hash_algo
>       transport: use parse_oid_hex instead of a constant
>       tag: express constant in terms of the_hash_algo
>       apply: replace hard-coded constants
>       apply: rename new_sha1_prefix and old_sha1_prefix
>       submodule: make zero-oid comparison hash function agnostic
>       rerere: convert to use the_hash_algo
> 
> Ævar Arnfjörð Bjarmason (35):
>       fetch: change "branch" to "reference" in --force -h output
>       push tests: make use of unused $1 in test description
>       push tests: use spaces in interpolated string
>       fetch tests: add a test for clobbering tag behavior
>       push doc: remove confusing mention of remote merger
>       push doc: move mention of "tag <tag>" later in the prose
>       push doc: correct lies about how push refspecs work
>       fetch: document local ref updates with/without --force
>       fetch: stop clobbering existing tags without --force
>       fsck tests: setup of bogus commit object
>       fsck tests: add a test for no skipList input
>       fsck: document and test sorted skipList input
>       fsck: document and test commented & empty line skipList input
>       fsck: document that skipList input must be unabbreviated
>       fsck: add a performance test
>       fsck: support comments & empty lines in skipList
>       commit-graph write: add progress output
>       commit-graph verify: add progress output
>       config doc: add missing list separator for checkout.optimizeNewBranch
>       push doc: add spacing between two words
>       fetch doc: correct grammar in --force docs
>       gc: fix regression in 7b0f229222 impacting --quiet
>       gc doc: mention the commit-graph in the intro
>       pack-objects test: modernize style
>       pack-objects tests: don't leave test .git corrupt at end
>       index-pack tests: don't leave test repo dirty at end
>       i18n: make GETTEXT_POISON a runtime option
>       range-diff doc: add a section about output stability
>       range-diff: fix regression in passing along diff options
>       range-diff: make diff option behavior (e.g. --stat) consistent
>       push: change needlessly ambiguous example in error
>       rebase doc: document rebase.useBuiltin
>       tests: add a special setup where rebase.useBuiltin is off
>       read-cache: make the split index obey umask settings
>       advice: don't pointlessly suggest --convert-graft-file
> 
> Đoàn Trần Công Danh (1):
>       git-compat-util: prefer poll.h to sys/poll.h
> 
> -- 
> You received this message because you are subscribed to the Google Groups "git-packagers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to git-packagers+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/git-packagers/xmqq36rhjnts.fsf%40gitster-ct.c.googlers.com.
> For more options, visit https://groups.google.com/d/optout.
> 

^ permalink raw reply	[relevance 0%]

* [ANNOUNCE] Git v2.20.0-rc2
@ 2018-12-01 14:58  2% Junio C Hamano
  2018-12-03 20:45  0% ` Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-12-01 14:58 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

A release candidate Git v2.20.0-rc2 is now available for testing
at the usual places.  It is comprised of 934 non-merge commits
since v2.19.0, contributed by 76 people, 25 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.20.0-rc2' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.19.0 are as follows.
Welcome to the Git development community!

  Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan
  Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis, David
  Zych, Đoàn Trần Công Danh, Frederick Eaton, Greg Hurrell,
  James Knight, Jann Horn, Joshua Watt, Loo Rong Jie, Lucas
  De Marchi, Matthew DeVore, Mihir Mehta, Nickolai Belakovski,
  Roger Strain, Sam McKelvie, Saulius Gurklys, Shulhan, Steven
  Fernandez, Strain, Roger L, and Tim Schumacher.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Alban Gruin, Andreas Gruenbacher,
  Andreas Heiduk, Antonio Ospite, Ben Peart, Brandon Williams,
  brian m. carlson, Christian Couder, Christian Hesse, Denton Liu,
  Derrick Stolee, Elijah Newren, Eric Sunshine, Jean-Noël Avila,
  Jeff Hostetler, Jeff King, Johannes Schindelin, Johannes Sixt,
  Jonathan Nieder, Jonathan Tan, Josh Steadmon, Junio C Hamano,
  Karsten Blees, Luke Diamand, Martin Ågren, Max Kirillov,
  Michael Witten, Michał Górny, Nguyễn Thái Ngọc Duy, Noam
  Postavsky, Olga Telezhnaya, Phillip Wood, Pratik Karki, Rafael
  Ascensão, Ralf Thielow, Ramsay Jones, Rasmus Villemoes, René
  Scharfe, Sebastian Staudt, Stefan Beller, Stephen P. Smith, Steve
  Hoelzer, Sven Strickroth, SZEDER Gábor, Tao Qingyun, Taylor
  Blau, Thomas Gummerer, Todd Zullinger, Torsten Bögershausen,
  and Uwe Kleine-König.

----------------------------------------------------------------

Git 2.20 Release Notes (draft)
==============================

Backward Compatibility Notes
----------------------------

 * "git branch -l <foo>" used to be a way to ask a reflog to be
   created while creating a new branch, but that is no longer the
   case.  It is a short-hand for "git branch --list <foo>" now.

 * "git push" into refs/tags/* hierarchy is rejected without getting
   forced, but "git fetch" (misguidedly) used the "fast forwarding"
   rule used for the refs/heads/* hierarchy; this has been corrected,
   which means some fetches of tags that did not fail with older
   version of Git will fail without "--force" with this version.

 * "git help -a" now gives verbose output (same as "git help -av").
   Those who want the old output may say "git help --no-verbose -a"..

 * "git cpn --help", when "cpn" is an alias to, say, "cherry-pick -n",
   reported only the alias expansion of "cpn" in earlier versions of
   Git.  It now runs "git cherry-pick --help" to show the manual page
   of the command, while sending the alias expansion to the standard
   error stream.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by". This is a backward-incompatible
   change.  Adding "--suppress-cc=misc-by" on the command line, or
   setting sendemail.suppresscc configuration variable to "misc-by",
   can be used to disable this behaviour.


Updates since v2.19
-------------------

UI, Workflows & Features

 * Running "git clone" against a project that contain two files with
   pathnames that differ only in cases on a case insensitive
   filesystem would result in one of the files lost because the
   underlying filesystem is incapable of holding both at the same
   time.  An attempt is made to detect such a case and warn.

 * "git checkout -b newbranch [HEAD]" should not have to do as much as
   checking out a commit different from HEAD.  An attempt is made to
   optimize this special case.

 * "git rev-list --stdin </dev/null" used to be an error; it now shows
   no output without an error.  "git rev-list --stdin --default HEAD"
   still falls back to the given default when nothing is given on the
   standard input.

 * Lift code from GitHub to restrict delta computation so that an
   object that exists in one fork is not made into a delta against
   another object that does not appear in the same forked repository.

 * "git format-patch" learned new "--interdiff" and "--range-diff"
   options to explain the difference between this version and the
   previous attempt in the cover letter (or after the three-dashes as
   a comment).

 * "git mailinfo" used in "git am" learned to make a best-effort
   recovery of a patch corrupted by MUA that sends text/plain with
   format=flawed option.
   (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).

 * The rules used by "git push" and "git fetch" to determine if a ref
   can or cannot be updated were inconsistent; specifically, fetching
   to update existing tags were allowed even though tags are supposed
   to be unmoving anchoring points.  "git fetch" was taught to forbid
   updates to existing tags without the "--force" option.

 * "git multi-pack-index" learned to detect corruption in the .midx
   file it uses, and this feature has been integrated into "git fsck".

 * Generation of (experimental) commit-graph files have so far been
   fairly silent, even though it takes noticeable amount of time in a
   meaningfully large repository.  The users will now see progress
   output.

 * The minimum version of Windows supported by Windows port of Git is
   now set to Vista.

 * The completion script (in contrib/) learned to complete a handful of
   options "git stash list" command takes.

 * The completion script (in contrib/) learned that "git fetch
   --multiple" only takes remote names as arguments and no refspecs.

 * "git status" learns to show progress bar when refreshing the index
   takes a long time.
   (merge ae9af12287 nd/status-refresh-progress later to maint).

 * "git help -a" and "git help -av" give different pieces of
   information, and generally the "verbose" version is more friendly
   to the new users.  "git help -a" by default now uses the more
   verbose output (with "--no-verbose", you can go back to the
   original).  Also "git help -av" now lists aliases and external
   commands, which it did not used to.

 * Unlike "grep", "git grep" by default recurses to the whole tree.
   The command learned "git grep --recursive" option, so that "git
   grep --no-recursive" can serve as a synonym to setting the
   max-depth to 0.

 * When pushing into a repository that borrows its objects from an
   alternate object store, "git receive-pack" that responds to the
   push request on the other side lists the tips of refs in the
   alternate to reduce the amount of objects transferred.  This
   sometimes is detrimental when the number of refs in the alternate
   is absurdly large, in which case the bandwidth saved in potentially
   fewer objects transferred is wasted in excessively large ref
   advertisement.  The alternate refs that are advertised are now
   configurable with a pair of configuration variables.

 * "git cmd --help" when "cmd" is aliased used to only say "cmd is
   aliased to ...".  Now it shows that to the standard error stream
   and runs "git $cmd --help" where $cmd is the first word of the
   alias expansion.

 * The documentation of "git gc" has been updated to mention that it
   is no longer limited to "pruning away crufts" but also updates
   ancillary files like commit-graph as a part of repository
   optimization.

 * "git p4 unshelve" improvements.

 * The logic to select the default user name and e-mail on Windows has
   been improved.
   (merge 501afcb8b0 js/mingw-default-ident later to maint).

 * The "rev-list --filter" feature learned to exclude all trees via
   "tree:0" filter.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by"; --suppress-cc=misc-by on the
   command line, or setting sendemail.suppresscc configuration
   variable to "misc-by", can be used to disable this behaviour.

 * Developer builds now uses -Wunused-function compilation option.

 * One of our CI tests to run with "unusual/experimental/random"
   settings now also uses commit-graph and midx.

 * "git mergetool" learned to take the "--[no-]gui" option, just like
   "git difftool" does.

 * "git rebase -i" learned a new insn, 'break', that the user can
   insert in the to-do list.  Upon hitting it, the command returns
   control back to the user.

 * New "--pretty=format:" placeholders %GF and %GP that show the GPG
   key fingerprints have been invented.

 * On platforms with recent cURL library, http.sslBackend configuration
   variable can be used to choose a different SSL backend at runtime.
   The Windows port uses this mechanism to switch between OpenSSL and
   Secure Channel while talking over the HTTPS protocol.

 * "git send-email" learned to disable SMTP authentication via the
   "--smtp-auth=none" option, even when the smtp username is given
   (which turns the authentication on by default).

 * A fourth class of configuration files (in addition to the
   traditional "system wide", "per user in the $HOME directory" and
   "per repository in the $GIT_DIR/config") has been introduced so
   that different worktrees that share the same repository (hence the
   same $GIT_DIR/config file) can use different customization.

 * A pattern with '**' that does not have a slash on either side used
   to be an invalid one, but the code now treats such double-asterisks
   the same way as two normal asterisks that happen to be adjacent to
   each other.
   (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).

 * The "--no-patch" option, which can be used to get a high-level
   overview without the actual line-by-line patch difference shown, of
   the "range-diff" command was earlier broken, which has been
   corrected.

 * The recently merged "rebase in C" has an escape hatch to use the
   scripted version when necessary, but it hasn't been documented,
   which has been corrected.


Performance, Internal Implementation, Development Support etc.

 * When there are too many packfiles in a repository (which is not
   recommended), looking up an object in these would require
   consulting many pack .idx files; a new mechanism to have a single
   file that consolidates all of these .idx files is introduced.

 * "git submodule update" is getting rewritten piece-by-piece into C.

 * The code for computing history reachability has been shuffled,
   obtained a bunch of new tests to cover them, and then being
   improved.

 * The unpack_trees() API used in checking out a branch and merging
   walks one or more trees along with the index.  When the cache-tree
   in the index tells us that we are walking a tree whose flattened
   contents is known (i.e. matches a span in the index), as linearly
   scanning a span in the index is much more efficient than having to
   open tree objects recursively and listing their entries, the walk
   can be optimized, which has been done.

 * When creating a thin pack, which allows objects to be made into a
   delta against another object that is not in the resulting pack but
   is known to be present on the receiving end, the code learned to
   take advantage of the reachability bitmap; this allows the server
   to send a delta against a base beyond the "boundary" commit.

 * spatch transformation to replace boolean uses of !hashcmp() to
   newly introduced oideq() is added, and applied, to regain
   performance lost due to support of multiple hash algorithms.

 * Fix a bug in which the same path could be registered under multiple
   worktree entries if the path was missing (for instance, was removed
   manually).  Also, as a convenience, expand the number of cases in
   which --force is applicable.

 * Split Documentation/config.txt for easier maintenance.
   (merge 6014363f0b nd/config-split later to maint).

 * Test helper binaries clean-up.
   (merge c9a1f4161f nd/test-tool later to maint).

 * Various tests have been updated to make it easier to swap the
   hash function used for object identification.
   (merge ae0c89d41b bc/hash-independent-tests later to maint).

 * Update fsck.skipList implementation and documentation.
   (merge 371a655074 ab/fsck-skiplist later to maint).

 * An alias that expands to another alias has so far been forbidden,
   but now it is allowed to create such an alias.

 * Various test scripts have been updated for style and also correct
   handling of exit status of various commands.

 * "gc --auto" ended up calling exit(-1) upon error, which has been
   corrected to use exit(1).  Also the error reporting behaviour when
   daemonized has been updated to exit with zero status when stopping
   due to a previously discovered error (which implies there is no
   point running gc to improve the situation); we used to exit with
   failure in such a case.

 * Various codepaths in the core-ish part learned to work on an
   arbitrary in-core index structure, not necessarily the default
   instance "the_index".
   (merge b3c7eef9b0 nd/the-index later to maint).

 * Code clean-up in the internal machinery used by "git status" and
   "git commit --dry-run".
   (merge 73ba5d78b4 ss/wt-status-committable later to maint).

 * Some environment variables that control the runtime options of Git
   used during tests are getting renamed for consistency.
   (merge 4231d1ba99 bp/rename-test-env-var later to maint).

 * A pair of new extensions to the index file have been introduced.
   They allow the index file to be read in parallel for performance.

 * The oidset API was built on top of the oidmap API which in turn is
   on the hashmap API.  Replace the implementation to build on top of
   the khash API and gain performance.

 * Over some transports, fetching objects with an exact commit object
   name can be done without first seeing the ref advertisements.  The
   code has been optimized to exploit this.

 * In a partial clone that will lazily be hydrated from the
   originating repository, we generally want to avoid "does this
   object exist (locally)?" on objects that we deliberately omitted
   when we created the clone.  The cache-tree codepath (which is used
   to write a tree object out of the index) however insisted that the
   object exists, even for paths that are outside of the partial
   checkout area.  The code has been updated to avoid such a check.

 * To help developers, an EditorConfig file that attempts to follow
   the project convention has been added.
   (merge b548d698a0 bc/editorconfig later to maint).

 * The result of coverage test can be combined with "git blame" to
   check the test coverage of code introduced recently with a new
   'coverage-diff' tool (in contrib/).
   (merge 783faedd65 ds/coverage-diff later to maint).

 * An experiment to fuzz test a few areas, hopefully we can gain more
   coverage to various areas.

 * More codepaths are moving away from hardcoded hash sizes.

 * The way the Windows port figures out the current directory has been
   improved.

 * The way DLLs are loaded on the Windows port has been improved.

 * Some tests have been reorganized and renamed; "ls t/" now gives a
   better overview of what is tested for these scripts than before.

 * "git rebase" and "git rebase -i" have been reimplemented in C.

 * Windows port learned to use nano-second resolution file timestamps.

 * The overly large Documentation/config.txt file have been split into
   million little pieces.  This potentially allows each individual piece
   included into the manual page of the command it affects more easily.

 * Replace three string-list instances used as look-up tables in "git
   fetch" with hashmaps.

 * Unify code to read the author-script used in "git am" and the
   commands that use the sequencer machinery, e.g. "git rebase -i".

 * In preparation to the day when we can deprecate and remove the
   "rebase -p", make sure we can skip and later remove tests for
   it.

 * The history traversal used to implement the tag-following has been
   optimized by introducing a new helper.

 * The helper function to refresh the cached stat information in the
   in-core index has learned to perform the lstat() part of the
   operation in parallel on multi-core platforms.

 * The code to traverse objects for reachability, used to decide what
   objects are unreferenced and expendable, have been taught to also
   consider per-worktree refs of other worktrees as starting points to
   prevent data loss.

 * "git add" needs to internally run "diff-files" equivalent, and the
   codepath learned the same optimization as "diff-files" has to run
   lstat(2) in parallel to find which paths have been updated in the
   working tree.

 * The procedure to install dependencies before testing at Travis CI
   is getting revamped for both simplicity and flexibility, taking
   advantage of the recent move to the vm-based environment.

 * The support for format-patch (and send-email) by the command-line
   completion script (in contrib/) has been simplified a bit.

 * The revision walker machinery learned to take advantage of the
   commit generation numbers stored in the commit-graph file.

 * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".

 * The way -lcurl library gets linked has been simplified by taking
   advantage of the fact that we can just ask curl-config command how.

 * Various functions have been audited for "-Wunused-parameter" warnings
   and bugs in them got fixed.

 * A sanity check for start-up sequence has been added in the config
   API codepath.

 * The build procedure to link for fuzzing test has been made
   customizable with a new Makefile variable.

 * The way "git rebase" parses and forwards the command line options
   meant for underlying "git am" has been revamped, which fixed for
   options with parameters that were not passed correctly.

 * Our testing framework uses a special i18n "poisoned localization"
   feature to find messages that ought to stay constant but are
   incorrectly marked to be translated.  This feature has been made
   into a runtime option (it used to be a compile-time option).

 * "git push" used to check ambiguities between object-names and
   refnames while processing the list of refs' old and new values,
   which was unnecessary (as it knew that it is feeding raw object
   names).  This has been optimized out.

 * The xcurl_off_t() helper function is used to cast size_t to
   curl_off_t, but some compilers gave warnings against the code to
   ensure the casting is done without wraparound, when size_t is
   narrower than curl_off_t.  This warning has been squelched.

 * Code preparation to replace ulong vars with size_t vars where
   appropriate continues.

 * The "test installed Git" mode of our test suite has been updated to
   work better.

 * A coding convention around the Coccinelle semantic patches to have
   two classes to ease code migration process has been proposed and
   its support has been added to the Makefile.


Fixes since v2.19
-----------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.
   (merge 66e83d9b41 jk/trailer-fixes later to maint).

 * Malformed or crafted data in packstream can make our code attempt
   to read or write past the allocated buffer and abort, instead of
   reporting an error, which has been fixed.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.
   (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.
   (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.
   (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).

 * Further fix for O_APPEND emulation on Windows
   (merge eeaf7ddac7 js/mingw-o-append later to maint).

 * A corner case bugfix in "git rerere" code.
   (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.
   (merge 84d938b732 nd/attr-pathspec-fix later to maint).

 * Recent update broke the reachability algorithm when refs (e.g.
   tags) that point at objects that are not commit were involved,
   which has been fixed.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.
   (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.
   (merge e68302011c jt/lazy-object-fetch-fix later to maint).

 * Update error messages given by "git remote" and make them consistent.
   (merge 5025425dff ms/remote-error-message-update later to maint).

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.
   (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.
   (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.
   (merge 829a321569 ds/commit-graph-with-grafts later to maint).

 * The mailmap file update.
   (merge 255eb03edf jn/mailmap-update later to maint).

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.
   (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).

 * "git fetch $repo $object" in a partial clone did not correctly
   fetch the asked-for object that is referenced by an object in
   promisor packfile, which has been fixed.

 * A corner-case bugfix.
   (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).

 * Various fixes to "diff --color-moved-ws".

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.
   (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.
   (merge 4c490f3d32 sg/split-index-racefix later to maint).

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.
   (merge 04005834ed np/log-graph-octopus-fix later to maint).

 * "git range-diff" did not work well when the compared ranges had
   changes in submodules and the "--submodule=log" was used.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.
   (merge f67b980771 jk/run-command-notdot later to maint).

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.
   (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.
   (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.
   (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).

 * The logic to determine the archive type "git archive" uses did not
   correctly kick in for "git archive --remote", which has been
   corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.
   (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).

 * Some codepaths failed to form a proper URL when .gitmodules record
   the URL to a submodule repository as relative to the repository of
   superproject, which has been corrected.
   (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).

 * "git fetch" over protocol v2 into a shallow repository failed to
   fetch full history behind a new tip of history that was diverged
   before the cut-off point of the history that was previously fetched
   shallowly.

 * The command line completion machinery (in contrib/) has been
   updated to allow the completion script to tweak the list of options
   that are reported by the parse-options machinery correctly.
   (merge 276b49ff34 nd/completion-negation later to maint).

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.
   (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.
   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.
   (merge a5f52c6dab sg/test-verbose-log later to maint).

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.
   (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).

 * "git ls-remote $there foo" was broken by recent update for the
   protocol v2 and stopped showing refs that match 'foo' that are not
   refs/{heads,tags}/foo, which has been fixed.
   (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).

 * Additional comment on a tricky piece of code to help developers.
   (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).

 * A couple of tests used to leave the repository in a state that is
   deliberately corrupt, which have been corrected.
   (merge aa984dbe5e ab/pack-tests-cleanup later to maint).

 * The submodule support has been updated to read from the blob at
   HEAD:.gitmodules when the .gitmodules file is missing from the
   working tree.
   (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).

 * "git fetch" was a bit loose in parsing responses from the other side
   when talking over the protocol v2.

 * "git rev-parse --exclude=* --branches --branches"  (i.e. first
   saying "add only things that do not match '*' out of all branches"
   and then adding all branches, without any exclusion this time")
   worked as expected, but "--exclude=* --all --all" did not work the
   same way, which has been fixed.
   (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).

 * "git send-email --transfer-encoding=..." in recent versions of Git
   sometimes produced an empty "Content-Transfer-Encoding:" header,
   which has been corrected.
   (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).

 * The interface into "xdiff" library used to discover the offset and
   size of a generated patch hunk by first formatting it into the
   textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
   out.  A new interface has been introduced to allow callers a more
   direct access to them.
   (merge 5eade0746e jk/xdiff-interface later to maint).

 * Pathspec matching against a tree object were buggy when negative
   pathspec elements were involved, which has been fixed.
   (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).

 * "git merge" and "git pull" that merges into an unborn branch used
   to completely ignore "--verify-signatures", which has been
   corrected.
   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).

 * "git rebase --autostash" did not correctly re-attach the HEAD at times.

 * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
   quite work, which has been corrected.
   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).

 * When editing a patch in a "git add -i" session, a hunk could be
   made to no-op.  The "git apply" program used to reject a patch with
   such a no-op hunk to catch user mistakes, but it is now updated to
   explicitly allow a no-op hunk in an edited patch.
   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).

 * The URL to an MSDN page in a comment has been updated.
   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).

 * "git ls-remote --sort=<thing>" can feed an object that is not yet
   available into the comparison machinery and segfault, which has
   been corrected to check such a request upfront and reject it.

 * When "git bundle" aborts due to an empty commit ranges
   (i.e. resulting in an empty pack), it left a file descriptor to an
   lockfile open, which resulted in leftover lockfile on Windows where
   you cannot remove a file with an open file descriptor.  This has
   been corrected.
   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).

 * "git format-patch --stat=<width>" can be used to specify the width
   used by the diffstat (shown in the cover letter).
   (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).

 * The way .git/index and .git/sharedindex* files were initially
   created gave these files different perm bits until they were
   adjusted for shared repository settings.  This was made consistent.
   (merge c9d6c78870 cc/shared-index-permbits later to maint).

 * "git rebase --stat" to transplant a piece of history onto a totally
   unrelated history were not working before and silently showed wrong
   result.  With the recent reimplementation in C, it started to instead
   die with an error message, as the original logic was not prepared
   to cope with this case.  This has now been fixed.

 * The advice message to tell the user to migrate an existing graft
   file to the replace system when a graft file was read was shown
   even when "git replace --convert-graft-file" command, which is the
   way the message suggests to use, was running, which made little
   sense.
   (merge 8821e90a09 ab/replace-graft-with-replace-advice later to maint).

 * "git diff --raw" lost ellipses to adjust the output columns for
   some time now, but the documentation still showed them.

 * Code cleanup, docfix, build fix, etc.
   (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
   (merge b9b07efdb2 tg/conflict-marker-size later to maint).
   (merge fa0aeea770 sg/doc-trace-appends later to maint).
   (merge d64324cb60 tb/void-check-attr later to maint).
   (merge c3b9bc94b9 en/double-semicolon-fix later to maint).
   (merge 79336116f5 sg/t3701-tighten-trace later to maint).
   (merge 801fa63a90 jk/dev-build-format-security later to maint).
   (merge 0597dd62ba sb/string-list-remove-unused later to maint).
   (merge db2d36fad8 bw/protocol-v2 later to maint).
   (merge 456d7cd3a9 sg/split-index-test later to maint).
   (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).
   (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).
   (merge 55f6bce2c9 fe/doc-updates later to maint).
   (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).
   (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).
   (merge 4c399442f7 ma/commit-graph-docs later to maint).
   (merge fc0503b04e ma/t1400-undebug-test later to maint).
   (merge e56b53553a nd/packobjectshook-doc-fix later to maint).
   (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).
   (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).
   (merge ad0b8f9575 mw/doc-typofixes later to maint).
   (merge d9f079ad1a jc/how-to-document-api later to maint).
   (merge b1492bf315 ma/t7005-bash-workaround later to maint).
   (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).
   (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).
   (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).
   (merge 61018fe9e0 du/cherry-is-plumbing later to maint).
   (merge c7e5fe79b9 sb/strbuf-h-update later to maint).
   (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).
   (merge 2e3c894f4b tq/branch-style-fix later to maint).
   (merge c5d844af9c sg/doc-show-branch-typofix later to maint).
   (merge 081d91618b ah/doc-updates later to maint).
   (merge b84c783882 jc/cocci-preincr later to maint).
   (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).
   (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).
   (merge 3063477445 tb/char-may-be-unsigned later to maint).
   (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
   (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).
   (merge 3006f5ee16 ma/reset-doc-rendering-fix later to maint).
   (merge 4c2eb06419 sg/daemon-test-signal-fix later to maint).
   (merge d27525e519 ss/msvc-strcasecmp later to maint).

----------------------------------------------------------------

Changes since v2.19.0 are as follows:

Aaron Lindsay (1):
      send-email: avoid empty transfer encoding header

Alban Gruin (21):
      sequencer: make three functions and an enum from sequencer.c public
      rebase -i: rewrite append_todo_help() in C
      editor: add a function to launch the sequence editor
      rebase -i: rewrite the edit-todo functionality in C
      sequencer: add a new function to silence a command, except if it fails
      rebase -i: rewrite setup_reflog_action() in C
      rebase -i: rewrite checkout_onto() in C
      sequencer: refactor append_todo_help() to write its message to a buffer
      sequencer: change the way skip_unnecessary_picks() returns its result
      t3404: todo list with commented-out commands only aborts
      rebase -i: rewrite complete_action() in C
      rebase -i: remove unused modes and functions
      rebase -i: implement the logic to initialize $revisions in C
      rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C
      rebase -i: rewrite write_basic_state() in C
      rebase -i: rewrite init_basic_state() in C
      rebase -i: implement the main part of interactive rebase as a builtin
      rebase--interactive2: rewrite the submodes of interactive rebase in C
      rebase -i: remove git-rebase--interactive.sh
      rebase -i: move rebase--helper modes to rebase--interactive
      p3400: replace calls to `git checkout -b' by `git checkout -B'

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Andreas Gruenbacher (1):
      rev-parse: clear --exclude list after 'git rev-parse --all'

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Anton Serbulov (1):
      mingw: fix getcwd when the parent directory cannot be queried

Antonio Ospite (10):
      submodule: add a print_config_from_gitmodules() helper
      submodule: factor out a config_set_in_gitmodules_file_gently function
      t7411: merge tests 5 and 6
      t7411: be nicer to future tests and really clean things up
      submodule--helper: add a new 'config' subcommand
      submodule: use the 'submodule--helper config' command
      t7506: clean up .gitmodules properly before setting up new scenario
      submodule: add a helper to check if it is safe to write to .gitmodules
      submodule: support reading .gitmodules when it's not in the working tree
      t/helper: add test-submodule-nested-repo-config

Ben Peart (19):
      checkout: optimize "git checkout -b <new_branch>"
      git-mv: allow submodules and fsmonitor to work together
      t/README: correct spelling of "uncommon"
      preload-index: use git_env_bool() not getenv() for customization
      fsmonitor: update GIT_TEST_FSMONITOR support
      read-cache: update TEST_GIT_INDEX_VERSION support
      preload-index: update GIT_FORCE_PRELOAD_TEST support
      read-cache: clean up casting and byte decoding
      eoie: add End of Index Entry (EOIE) extension
      config: add new index.threads config setting
      read-cache: load cache extensions on a worker thread
      ieot: add Index Entry Offset Table (IEOT) extension
      read-cache: load cache entries on worker threads
      reset: don't compute unstaged changes after reset when --quiet
      reset: add new reset.quiet config setting
      reset: warn when refresh_index() takes more than 2 seconds
      speed up refresh_index() by utilizing preload_index()
      add: speed up cmd_add() by utilizing read_cache_preload()
      refresh_index: remove unnecessary calls to preload_index()

Brandon Williams (1):
      config: document value 2 for protocol.version

Brendan Forster (1):
      http: add support for disabling SSL revocation checks in cURL

Carlo Marcelo Arenas Belón (8):
      unpack-trees: avoid dead store for struct progress
      multi-pack-index: avoid dead store for struct progress
      read-cache: use of memory after it is freed
      commit-slabs: move MAYBE_UNUSED out
      khash: silence -Wunused-function for delta-islands
      compat: make sure git_mmap is not expected to write
      sequencer: cleanup for gcc warning in non developer mode
      builtin/notes: remove unnecessary free

Christian Couder (3):
      pack-objects: refactor code into compute_layer_order()
      pack-objects: move tree_depth into 'struct packing_data'
      pack-objects: move 'layer' into 'struct packing_data'

Christian Hesse (2):
      subtree: add build targets 'man' and 'html'
      subtree: make install targets depend on build targets

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Denton Liu (3):
      mergetool: accept -g/--[no-]gui as arguments
      completion: support `git mergetool --[no-]gui`
      doc: document diff/merge.guitool config keys

Derrick Stolee (93):
      multi-pack-index: add design document
      multi-pack-index: add format details
      multi-pack-index: add builtin
      multi-pack-index: add 'write' verb
      midx: write header information to lockfile
      multi-pack-index: load into memory
      t5319: expand test data
      packfile: generalize pack directory list
      multi-pack-index: read packfile list
      multi-pack-index: write pack names in chunk
      midx: read pack names into array
      midx: sort and deduplicate objects from packfiles
      midx: write object ids in a chunk
      midx: write object id fanout chunk
      midx: write object offsets
      config: create core.multiPackIndex setting
      midx: read objects from multi-pack-index
      midx: use midx in abbreviation calculations
      midx: use existing midx when writing new one
      midx: use midx in approximate_object_count
      midx: prevent duplicate packfile loads
      packfile: skip loading index if in multi-pack-index
      midx: clear midx on repack
      commit-reach: move walk methods from commit.c
      commit.h: remove method declarations
      commit-reach: move ref_newer from remote.c
      commit-reach: move commit_contains from ref-filter
      upload-pack: make reachable() more generic
      upload-pack: refactor ok_to_give_up()
      upload-pack: generalize commit date cutoff
      commit-reach: move can_all_from_reach_with_flags
      test-reach: create new test tool for ref_newer
      test-reach: test in_merge_bases
      test-reach: test is_descendant_of
      test-reach: test get_merge_bases_many
      test-reach: test reduce_heads
      test-reach: test can_all_from_reach_with_flags
      test-reach: test commit_contains
      commit-reach: replace ref_newer logic
      commit-reach: make can_all_from_reach... linear
      commit-reach: use can_all_from_reach
      multi-pack-index: provide more helpful usage info
      multi-pack-index: store local property
      midx: mark bad packed objects
      midx: stop reporting garbage
      midx: fix bug that skips midx with alternates
      packfile: add all_packs list
      treewide: use get_all_packs
      midx: test a few commands that use get_all_packs
      pack-objects: consider packs in multi-pack-index
      commit-graph: update design document
      test-repository: properly init repo
      commit-graph: not compatible with replace objects
      commit-graph: not compatible with grafts
      commit-graph: not compatible with uninitialized repo
      commit-graph: close_commit_graph before shallow walk
      commit-graph: define GIT_TEST_COMMIT_GRAPH
      t3206-range-diff.sh: cover single-patch case
      t5318: use test_oid for HASH_LEN
      multi-pack-index: add 'verify' verb
      multi-pack-index: verify bad header
      multi-pack-index: verify corrupt chunk lookup table
      multi-pack-index: verify packname order
      multi-pack-index: verify missing pack
      multi-pack-index: verify oid fanout order
      multi-pack-index: verify oid lookup order
      multi-pack-index: fix 32-bit vs 64-bit size check
      multi-pack-index: verify object offsets
      multi-pack-index: report progress during 'verify'
      fsck: verify multi-pack-index
      commit-reach: properly peel tags
      commit-reach: fix memory and flag leaks
      commit-reach: cleanups in can_all_from_reach...
      commit-graph: clean up leaked memory during write
      commit-graph: reduce initial oid allocation
      midx: fix broken free() in close_midx()
      contrib: add coverage-diff script
      ci: add optional test variables
      commit-reach: fix first-parent heuristic
      midx: close multi-pack-index on repack
      multi-pack-index: define GIT_TEST_MULTI_PACK_INDEX
      packfile: close multi-pack-index in close_all_packs
      prio-queue: add 'peek' operation
      test-reach: add run_three_modes method
      test-reach: add rev-list tests
      revision.c: begin refactoring --topo-order logic
      commit/revisions: bookkeeping before refactoring
      revision.c: generation-based topo-order algorithm
      t6012: make rev-list tests more interesting
      commit-reach: implement get_reachable_subset
      test-reach: test get_reachable_subset
      remote: make add_missing_tags() linear
      pack-objects: ignore ambiguous object warnings

Elijah Newren (14):
      Remove superfluous trailing semicolons
      t4200: demonstrate rerere segfault on specially crafted merge
      rerere: avoid buffer overrun
      update-ref: fix type of update_flags variable to match its usage
      update-ref: allow --no-deref with --stdin
      sequencer: fix --allow-empty-message behavior, make it smarter
      merge-recursive: set paths correctly when three-way merging content
      merge-recursive: avoid wrapper function when unnecessary and wasteful
      merge-recursive: remove final remaining caller of merge_file_one()
      merge-recursive: rename merge_file_1() and merge_content()
      commit: fix erroneous BUG, 'multiple renames on the same target? how?'
      merge-recursive: improve auto-merging messages with path collisions
      merge-recursive: avoid showing conflicts with merge branch before HEAD
      fsck: move fsck_head_link() to get_default_heads() to avoid some globals

Eric Sunshine (26):
      format-patch: allow additional generated content in make_cover_letter()
      format-patch: add --interdiff option to embed diff in cover letter
      format-patch: teach --interdiff to respect -v/--reroll-count
      interdiff: teach show_interdiff() to indent interdiff
      log-tree: show_log: make commentary block delimiting reusable
      format-patch: allow --interdiff to apply to a lone-patch
      range-diff: respect diff_option.file rather than assuming 'stdout'
      range-diff: publish default creation factor
      range-diff: relieve callers of low-level configuration burden
      format-patch: add --range-diff option to embed diff in cover letter
      format-patch: extend --range-diff to accept revision range
      format-patch: teach --range-diff to respect -v/--reroll-count
      format-patch: add --creation-factor tweak for --range-diff
      format-patch: allow --range-diff to apply to a lone-patch
      worktree: don't die() in library function find_worktree()
      worktree: move delete_git_dir() earlier in file for upcoming new callers
      worktree: generalize delete_git_dir() to reduce code duplication
      worktree: prepare for more checks of whether path can become worktree
      worktree: disallow adding same path multiple times
      worktree: teach 'add' to respect --force for registered but missing path
      worktree: teach 'move' to override lock when --force given twice
      worktree: teach 'remove' to override lock when --force given twice
      worktree: delete .git/worktrees if empty after 'remove'
      doc-diff: fix non-portable 'man' invocation
      doc-diff: add --clean mode to remove temporary working gunk
      doc/Makefile: drop doc-diff worktree and temporary files on "make clean"

Frederick Eaton (3):
      git-archimport.1: specify what kind of Arch we're talking about
      git-column.1: clarify initial description, provide examples
      git-describe.1: clarify that "human readable" is also git-readable

Greg Hurrell (1):
      doc: update diff-format.txt for removed ellipses in --raw

James Knight (1):
      build: link with curl-defined linker flags

Jann Horn (2):
      patch-delta: fix oob read
      patch-delta: consistently report corruption

Jean-Noël Avila (1):
      i18n: fix small typos

Jeff Hostetler (2):
      t0051: test GIT_TRACE to a windows named pipe
      mingw: fix mingw_open_append to work with named pipes

Jeff King (98):
      branch: make "-l" a synonym for "--list"
      Add delta-islands.{c,h}
      pack-objects: add delta-islands support
      repack: add delta-islands support
      t5320: tests for delta islands
      t/perf: factor boilerplate out of test_perf
      t/perf: factor out percent calculations
      t/perf: add infrastructure for measuring sizes
      t/perf: add perf tests for fetches from a bitmapped server
      pack-bitmap: save "have" bitmap from walk
      pack-objects: reuse on-disk deltas for thin "have" objects
      SubmittingPatches: mention doc-diff
      rev-list: make empty --stdin not an error
      trailer: use size_t for string offsets
      trailer: use size_t for iterating trailer list
      trailer: pass process_trailer_opts to trailer_info_get()
      interpret-trailers: tighten check for "---" patch boundary
      interpret-trailers: allow suppressing "---" divider
      pretty, ref-filter: format %(trailers) with no_divider option
      sequencer: ignore "---" divider when parsing trailers
      append_signoff: use size_t for string offsets
      coccinelle: use <...> for function exclusion
      introduce hasheq() and oideq()
      convert "oidcmp() == 0" to oideq()
      convert "hashcmp() == 0" to hasheq()
      convert "oidcmp() != 0" to "!oideq()"
      convert "hashcmp() != 0" to "!hasheq()"
      convert hashmap comparison functions to oideq()
      read-cache: use oideq() in ce_compare functions
      show_dirstat: simplify same-content check
      doc-diff: always use oids inside worktree
      test-delta: read input into a heap buffer
      t5303: test some corrupt deltas
      patch-delta: handle truncated copy parameters
      t5303: use printf to generate delta bases
      doc/git-branch: remove obsolete "-l" references
      bitmap_has_sha1_in_uninteresting(): drop BUG check
      t5310: test delta reuse with bitmaps
      traverse_bitmap_commit_list(): don't free result
      pack-bitmap: drop "loaded" flag
      reopen_tempfile(): truncate opened file
      doc-diff: force worktree add
      config.mak.dev: add -Wformat-security
      pack-objects: handle island check for "external" delta base
      receive-pack: update comment with check_everything_connected
      submodule--helper: use "--" to signal end of clone options
      submodule-config: ban submodule urls that start with dash
      submodule-config: ban submodule paths that start with a dash
      fsck: detect submodule urls starting with dash
      fsck: detect submodule paths starting with dash
      more oideq/hasheq conversions
      transport: drop refnames from for_each_alternate_ref
      test-tool: show tool list on error
      config.mak.dev: enable -Wunused-function
      run-command: mark path lookup errors with ENOENT
      t5410: use longer path for sample script
      upload-pack: fix broken if/else chain in config callback
      t1450: check large blob in trailing-garbage test
      check_stream_sha1(): handle input underflow
      cat-file: handle streaming failures consistently
      ls-remote: do not send ref prefixes for patterns
      ls-remote: pass heads/tags prefixes to transport
      read_istream_pack_non_delta(): document input handling
      xdiff: provide a separate emit callback for hunks
      xdiff-interface: provide a separate consume callback for hunks
      rev-list: handle flags for --indexed-objects
      approxidate: handle pending number for "specials"
      pathspec: handle non-terminated strings with :(attr)
      diff: avoid generating unused hunk header lines
      diff: discard hunk headers for patch-ids earlier
      diff: use hunk callback for word-diff
      combine-diff: use an xdiff hunk callback
      diff: convert --check to use a hunk callback
      range-diff: use a hunk callback
      xdiff-interface: drop parse_hunk_header()
      apply: mark include/exclude options as NONEG
      am: handle --no-patch-format option
      ls-files: mark exclude options as NONEG
      pack-objects: mark index-version option as NONEG
      cat-file: mark batch options with NONEG
      status: mark --find-renames option with NONEG
      format-patch: mark "--no-numbered" option with NONEG
      show-branch: mark --reflog option as NONEG
      tag: mark "--message" option with NONEG
      cat-file: report an error on multiple --batch options
      apply: return -1 from option callback instead of calling exit(1)
      parse-options: drop OPT_DATE()
      assert NOARG/NONEG behavior of parse-options callbacks
      midx: double-check large object write loop
      merge: extract verify_merge_signature() helper
      merge: handle --verify-signatures for unborn branch
      pull: handle --verify-signatures for unborn branch
      approxidate: fix NULL dereference in date_time()
      bundle: dup() output descriptor closer to point-of-use
      pack-objects: fix tree_depth and layer invariants
      pack-objects: zero-initialize tree_depth/layer arrays
      pack-objects: fix off-by-one in delta-island tree-depth computation
      t5562: fix perl path

Johannes Schindelin (64):
      rebase -i --autosquash: demonstrate a problem skipping the last squash
      rebase -i: be careful to wrap up fixup/squash chains
      compat/poll: prepare for targeting Windows Vista
      mingw: set _WIN32_WINNT explicitly for Git for Windows
      mingw: bump the minimum Windows version to Vista
      builtin rebase: prepare for builtin rebase -i
      rebase -i: clarify what happens on a failed `exec`
      rebase -i: introduce the 'break' command
      getpwuid(mingw): initialize the structure only once
      getpwuid(mingw): provide a better default for the user name
      mingw: use domain information for default email
      http: add support for selecting SSL backends at runtime
      pack-objects: fix typo 'detla' -> 'delta'
      pack-objects (mingw): demonstrate a segmentation fault with large deltas
      pack-objects (mingw): initialize `packing_data` mutex in the correct spot
      rebase (autostash): avoid duplicate call to state_dir_path()
      rebase (autostash): store the full OID in <state-dir>/autostash
      rebase (autostash): use an explicit OID to apply the stash
      mingw: factor out code to set stat() data
      rebase --autostash: demonstrate a problem with dirty submodules
      rebase --autostash: fix issue with dirty submodules
      mingw: load system libraries the recommended way
      mingw: ensure `getcwd()` reports the correct case
      repack: point out a bug handling stale shallow info
      shallow: offer to prune only non-existing entries
      repack -ad: prune the list of shallow commits
      http: when using Secure Channel, ignore sslCAInfo by default
      t7800: fix quoting
      mingw: reencode environment variables on the fly (UTF-16 <-> UTF-8)
      config: rename `dummy` parameter to `cb` in git_default_config()
      config: allow for platform-specific core.* config settings
      config: move Windows-specific config settings into compat/mingw.c
      mingw: unset PERL5LIB by default
      mingw: fix isatty() after dup2()
      t3404: decouple some test cases from outcomes of previous test cases
      t3418: decouple test cases from a previous `rebase -p` test case
      tests: optionally skip `git rebase -p` tests
      Windows: force-recompile git.res for differing architectures
      built-in rebase: demonstrate regression with --autostash
      built-in rebase --autostash: leave the current branch alone if possible
      Update .mailmap
      rebase -r: demonstrate bug with conflicting merges
      rebase -r: do not write MERGE_HEAD unless needed
      rebase -i: include MERGE_HEAD into files to clean up
      built-in rebase --skip/--abort: clean up stale .git/<name> files
      status: rebase and merge can be in progress at the same time
      apply --recount: allow "no-op hunks"
      rebase: consolidate clean-up code before leaving reset_head()
      rebase: prepare reset_head() for more flags
      built-in rebase: reinstate `checkout -q` behavior where appropriate
      tests: fix GIT_TEST_INSTALLED's PATH to include t/helper/
      tests: respect GIT_TEST_INSTALLED when initializing repositories
      t/lib-gettext: test installed git-sh-i18n if GIT_TEST_INSTALLED is set
      mingw: use `CreateHardLink()` directly
      rebase: really just passthru the `git am` options
      rebase: validate -C<n> and --whitespace=<mode> parameters early
      config: report a bug if git_dir exists without commondir
      tests: do not require Git to be built when testing an installed Git
      tests: explicitly use `git.exe` on Windows
      mingw: replace an obsolete link with the superseding one
      legacy-rebase: backport -C<n> and --whitespace=<option> checks
      rebase: warn about the correct tree's OID
      rebase: fix GIT_REFLOG_ACTION regression
      rebase --stat: fix when rebasing to an unrelated history

Johannes Sixt (3):
      diff: don't attempt to strip prefix from absolute Windows paths
      rebase -i: recognize short commands without arguments
      t3404-rebase-interactive: test abbreviated commands

Jonathan Nieder (9):
      gc: improve handling of errors reading gc.log
      gc: exit with status 128 on failure
      gc: do not return error for prior errors in daemonized mode
      commit-reach: correct accidental #include of C file
      mailmap: consistently normalize brian m. carlson's name
      git doc: direct bug reporters to mailing list archive
      eoie: default to not writing EOIE section
      ieot: default to not writing IEOT section
      index: make index.threads=true enable ieot and eoie

Jonathan Tan (15):
      fetch-object: unify fetch_object[s] functions
      fetch-object: set exact_oid when fetching
      connected: document connectivity in partial clones
      fetch: in partial clone, check presence of targets
      fetch-pack: avoid object flags if no_dependents
      fetch-pack: exclude blobs when lazy-fetching trees
      transport: allow skipping of ref listing
      transport: do not list refs if possible
      transport: list refs before fetch if necessary
      fetch: do not list refs if fetching only hashes
      cache-tree: skip some blob checks in partial clone
      upload-pack: make have_obj not global
      upload-pack: make want_obj not global
      upload-pack: clear flags before each v2 request
      fetch-pack: be more precise in parsing v2 response

Josh Steadmon (4):
      fuzz: add basic fuzz testing target.
      fuzz: add fuzz testing for packfile indices.
      archive: initialize archivers earlier
      Makefile: use FUZZ_CXXFLAGS for linking fuzzers

Joshua Watt (1):
      send-email: explicitly disable authentication

Junio C Hamano (36):
      Revert "doc/Makefile: drop doc-diff worktree and temporary files on "make clean""
      Initial batch post 2.19
      Second batch post 2.19
      Git 2.14.5
      Git 2.15.3
      Git 2.16.5
      Git 2.17.2
      Git 2.18.1
      Git 2.19.1
      t0000: do not get self-test disrupted by environment warnings
      CodingGuidelines: document the API in *.h files
      Declare that the next one will be named 2.20
      Third batch for 2.20
      rebase: fix typoes in error messages
      Fourth batch for 2.20
      Revert "subtree: make install targets depend on build targets"
      Fifth batch for 2.20
      receive: denyCurrentBranch=updateinstead should not blindly update
      cocci: simplify "if (++u > 1)" to "if (u++)"
      fsck: s/++i > 1/i++/
      http: give curl version warnings consistently
      Sixth batch for 2.20
      Seventh batch for 2.20
      fetch: replace string-list used as a look-up table with a hashmap
      rebase: apply cocci patch
      Eighth batch for 2.20
      Ninth batch for 2.20
      Makefile: ease dynamic-gettext-poison transition
      Tenth batch for 2.20
      Git 2.20-rc0
      RelNotes: name the release properly
      Prepare for 2.20-rc1
      Git 2.19.2
      Git 2.20-rc1
      format-patch: do not let its diff-options affect --range-diff
      Git 2.20-rc2

Karsten Blees (2):
      mingw: replace MSVCRT's fstat() with a Win32-based implementation
      mingw: implement nanosecond-precision file times

Loo Rong Jie (1):
      win32: replace pthread_cond_*() with much simpler code

Lucas De Marchi (1):
      range-diff: allow to diff files regardless of submodule config

Luke Diamand (3):
      git-p4: do not fail in verbose mode for missing 'fileSize' key
      git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved
      git-p4: fully support unshelving changelists

Martin Ågren (11):
      Doc: use `--type=bool` instead of `--bool`
      git-config.txt: fix 'see: above' note
      git-commit-graph.txt: fix bullet lists
      git-commit-graph.txt: typeset more in monospace
      git-commit-graph.txt: refer to "*commit*-graph file"
      Doc: refer to the "commit-graph file" with dash
      t1400: drop debug `echo` to actually execute `test`
      builtin/commit-graph.c: UNLEAK variables
      sequencer: break out of loop explicitly
      git-reset.txt: render tables correctly under Asciidoctor
      git-reset.txt: render literal examples as monospace

Matthew DeVore (19):
      list-objects: store common func args in struct
      list-objects: refactor to process_tree_contents
      list-objects: always parse trees gently
      t/README: reformat Do, Don't, Keep in mind lists
      Documentation: add shell guidelines
      tests: standardize pipe placement
      t/*: fix ordering of expected/observed arguments
      tests: don't swallow Git errors upstream of pipes
      t9109: don't swallow Git errors upstream of pipes
      tests: order arguments to git-rev-list properly
      rev-list: handle missing tree objects properly
      revision: mark non-user-given objects instead
      list-objects-filter: use BUG rather than die
      list-objects-filter-options: do not over-strbuf_init
      list-objects-filter: implement filter tree:0
      filter-trees: code clean-up of tests
      list-objects: support for skipping tree traversal
      Documentation/git-log.txt: do not show --exclude-promisor-objects
      exclude-promisor-objects: declare when option is allowed

Max Kirillov (1):
      http-backend test: make empty CONTENT_LENGTH test more realistic

Michael Witten (3):
      docs: typo: s/go/to/
      docs: graph: remove unnecessary `graph_update()' call
      docs: typo: s/isimilar/similar/

Michał Górny (6):
      gpg-interface.c: detect and reject multiple signatures on commits
      gpg-interface.c: use flags to determine key/signer info presence
      gpg-interface.c: support getting key fingerprint via %GF format
      gpg-interface.c: obtain primary key fingerprint as well
      t/t7510-signed-commit.sh: Add %GP to custom format checks
      t/t7510-signed-commit.sh: add signing subkey to Eris Discordia key

Mihir Mehta (1):
      doc: fix a typo and clarify a sentence

Nguyễn Thái Ngọc Duy (170):
      clone: report duplicate entries on case-insensitive filesystems
      trace.h: support nested performance tracing
      unpack-trees: add performance tracing
      unpack-trees: optimize walking same trees with cache-tree
      unpack-trees: reduce malloc in cache-tree walk
      unpack-trees: reuse (still valid) cache-tree from src_index
      unpack-trees: add missing cache invalidation
      cache-tree: verify valid cache-tree in the test suite
      Document update for nd/unpack-trees-with-cache-tree
      bisect.c: make show_list() build again
      t/helper: keep test-tool command list sorted
      t/helper: merge test-dump-untracked-cache into test-tool
      t/helper: merge test-pkt-line into test-tool
      t/helper: merge test-parse-options into test-tool
      t/helper: merge test-dump-fsmonitor into test-tool
      Makefile: add a hint about TEST_BUILTINS_OBJS
      config.txt: follow camelCase naming
      config.txt: move fetch part out to a separate file
      config.txt: move format part out to a separate file
      config.txt: move gitcvs part out to a separate file
      config.txt: move gui part out to a separate file
      config.txt: move pull part out to a separate file
      config.txt: move push part out to a separate file
      config.txt: move receive part out to a separate file
      config.txt: move sendemail part out to a separate file
      config.txt: move sequence.editor out of "core" part
      config.txt: move submodule part out to a separate file
      archive.c: remove implicit dependency the_repository
      status: show progress bar if refreshing the index takes too long
      add: do not accept pathspec magic 'attr'
      completion: support "git fetch --multiple"
      read-cache.c: remove 'const' from index_has_changes()
      diff.c: reduce implicit dependency on the_index
      combine-diff.c: remove implicit dependency on the_index
      blame.c: rename "repo" argument to "r"
      diff.c: remove the_index dependency in textconv() functions
      grep.c: remove implicit dependency on the_index
      diff.c: remove implicit dependency on the_index
      read-cache.c: remove implicit dependency on the_index
      diff-lib.c: remove implicit dependency on the_index
      ll-merge.c: remove implicit dependency on the_index
      merge-blobs.c: remove implicit dependency on the_index
      merge.c: remove implicit dependency on the_index
      patch-ids.c: remove implicit dependency on the_index
      sha1-file.c: remove implicit dependency on the_index
      rerere.c: remove implicit dependency on the_index
      userdiff.c: remove implicit dependency on the_index
      line-range.c: remove implicit dependency on the_index
      submodule.c: remove implicit dependency on the_index
      tree-diff.c: remove implicit dependency on the_index
      ws.c: remove implicit dependency on the_index
      revision.c: remove implicit dependency on the_index
      revision.c: reduce implicit dependency the_repository
      read-cache.c: optimize reading index format v4
      config.txt: correct the note about uploadpack.packObjectsHook
      help -a: improve and make --verbose default
      refs.c: indent with tabs, not spaces
      Add a place for (not) sharing stuff between worktrees
      submodule.c: remove some of the_repository references
      completion: fix __gitcomp_builtin no longer consider extra options
      t1300: extract and use test_cmp_config()
      worktree: add per-worktree config files
      refs: new ref types to make per-worktree refs visible to all worktrees
      revision.c: correct a parameter name
      revision.c: better error reporting on ref from different worktrees
      fsck: check HEAD and reflog from other worktrees
      reflog expire: cover reflog from all worktrees
      Update makefile in preparation for Documentation/config/*.txt
      config.txt: move advice.* to a separate file
      config.txt: move core.* to a separate file
      config.txt: move add.* to a separate file
      config.txt: move alias.* to a separate file
      config.txt: move am.* to a separate file
      config.txt: move apply.* to a separate file
      config.txt: move blame.* to a separate file
      config.txt: move branch.* to a separate file
      config.txt: move browser.* to a separate file
      config.txt: move checkout.* to a separate file
      config.txt: move clean.* to a separate file
      config.txt: move color.* to a separate file
      config.txt: move column.* to a separate file
      config.txt: move commit.* to a separate file
      config.txt: move credential.* to a separate file
      config.txt: move completion.* to a separate file
      config.txt: move diff-config.txt to config/
      config.txt: move difftool.* to a separate file
      config.txt: move fastimport.* to a separate file
      config.txt: move fetch-config.txt to config/
      config.txt: move filter.* to a separate file
      config.txt: move format-config.txt to config/
      config.txt: move fmt-merge-msg-config.txt to config/
      config.txt: move fsck.* to a separate file
      config.txt: move gc.* to a separate file
      config.txt: move gitcvs-config.txt to config/
      config.txt: move gitweb.* to a separate file
      config.txt: move grep.* to a separate file
      config.txt: move gpg.* to a separate file
      config.txt: move gui-config.txt to config/
      config.txt: move guitool.* to a separate file
      config.txt: move help.* to a separate file
      config.txt: move ssh.* to a separate file
      config.txt: move http.* to a separate file
      config.txt: move i18n.* to a separate file
      git-imap-send.txt: move imap.* to a separate file
      config.txt: move index.* to a separate file
      config.txt: move init.* to a separate file
      config.txt: move instaweb.* to a separate file
      config.txt: move interactive.* to a separate file
      config.txt: move log.* to a separate file
      config.txt: move mailinfo.* to a separate file
      config.txt: move mailmap.* to a separate file
      config.txt: move man.* to a separate file
      config.txt: move merge-config.txt to config/
      config.txt: move mergetool.* to a separate file
      config.txt: move notes.* to a separate file
      config.txt: move pack.* to a separate file
      config.txt: move pager.* to a separate file
      config.txt: move pretty.* to a separate file
      config.txt: move protocol.* to a separate file
      config.txt: move pull-config.txt to config/
      config.txt: move push-config.txt to config/
      config.txt: move rebase-config.txt to config/
      config.txt: move receive-config.txt to config/
      config.txt: move remote.* to a separate file
      config.txt: move remotes.* to a separate file
      config.txt: move repack.* to a separate file
      config.txt: move rerere.* to a separate file
      config.txt: move reset.* to a separate file
      config.txt: move sendemail-config.txt to config/
      config.txt: move sequencer.* to a separate file
      config.txt: move showBranch.* to a separate file
      config.txt: move splitIndex.* to a separate file
      config.txt: move status.* to a separate file
      config.txt: move stash.* to a separate file
      config.txt: move submodule.* to a separate file
      config.txt: move tag.* to a separate file
      config.txt: move transfer.* to a separate file
      config.txt: move uploadarchive.* to a separate file
      config.txt: move uploadpack.* to a separate file
      config.txt: move url.* to a separate file
      config.txt: move user.* to a separate file
      config.txt: move versionsort.* to a separate file
      config.txt: move web.* to a separate file
      config.txt: move worktree.* to a separate file
      config.txt: remove config/dummy.txt
      thread-utils: macros to unconditionally compile pthreads API
      wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode
      git-worktree.txt: correct linkgit command name
      sequencer.c: remove a stray semicolon
      tree-walk.c: fix overoptimistic inclusion in :(exclude) matching
      run-command.h: include thread-utils.h instead of pthread.h
      send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c
      index-pack: remove #ifdef NO_PTHREADS
      name-hash.c: remove #ifdef NO_PTHREADS
      attr.c: remove #ifdef NO_PTHREADS
      grep: remove #ifdef NO_PTHREADS
      grep: clean up num_threads handling
      preload-index.c: remove #ifdef NO_PTHREADS
      pack-objects: remove #ifdef NO_PTHREADS
      read-cache.c: remove #ifdef NO_PTHREADS
      read-cache.c: reduce branching based on HAVE_THREADS
      read-cache.c: initialize copy_len to shut up gcc 8
      Clean up pthread_create() error handling
      completion: use __gitcomp_builtin for format-patch
      build: fix broken command-list.h generation with core.autocrlf
      format-patch: respect --stat in cover letter's diffstat
      doc: move extensions.worktreeConfig to the right place
      clone: fix colliding file detection on APFS
      files-backend.c: fix build error on Solaris
      transport-helper.c: do not translate a string twice

Nickolai Belakovski (2):
      worktree: update documentation for lock_reason and lock_reason_valid
      worktree: rename is_worktree_locked to worktree_lock_reason

Noam Postavsky (1):
      log: fix coloring of certain octopus merge shapes

Olga Telezhnaya (3):
      ref-filter: free memory from used_atom
      ls-remote: release memory instead of UNLEAK
      ref-filter: free item->value and item->value->s

Phillip Wood (11):
      diff: fix --color-moved-ws=allow-indentation-change
      diff --color-moved-ws: fix double free crash
      diff --color-moved-ws: fix out of bounds string access
      diff --color-moved-ws: fix a memory leak
      diff --color-moved-ws: fix another memory leak
      diff --color-moved: fix a memory leak
      am: don't die in read_author_script()
      am: improve author-script error reporting
      am: rename read_author_script()
      add read_author_script() to libgit
      sequencer: use read_author_script()

Pratik Karki (46):
      rebase: start implementing it as a builtin
      rebase: refactor common shell functions into their own file
      builtin/rebase: support running "git rebase <upstream>"
      builtin rebase: support --onto
      builtin rebase: support `git rebase --onto A...B`
      builtin rebase: handle the pre-rebase hook and --no-verify
      builtin rebase: support --quiet
      builtin rebase: support the `verbose` and `diffstat` options
      builtin rebase: require a clean worktree
      builtin rebase: try to fast forward when possible
      builtin rebase: support --force-rebase
      builtin rebase: start a new rebase only if none is in progress
      builtin rebase: only store fully-qualified refs in `options.head_name`
      builtin rebase: support `git rebase <upstream> <switch-to>`
      builtin rebase: support --continue
      builtin rebase: support --skip
      builtin rebase: support --abort
      builtin rebase: support --quit
      builtin rebase: support --edit-todo and --show-current-patch
      builtin rebase: actions require a rebase in progress
      builtin rebase: stop if `git am` is in progress
      builtin rebase: allow selecting the rebase "backend"
      builtin rebase: support --signoff
      builtin rebase: support --rerere-autoupdate
      builtin rebase: support --committer-date-is-author-date
      builtin rebase: support `ignore-whitespace` option
      builtin rebase: support `ignore-date` option
      builtin rebase: support `keep-empty` option
      builtin rebase: support `--autosquash`
      builtin rebase: support `--gpg-sign` option
      builtin rebase: support `-C` and `--whitespace=<type>`
      builtin rebase: support `--autostash` option
      builtin rebase: support `--exec`
      builtin rebase: support `--allow-empty-message` option
      builtin rebase: support --rebase-merges[=[no-]rebase-cousins]
      merge-base --fork-point: extract libified function
      builtin rebase: support `fork-point` option
      builtin rebase: add support for custom merge strategies
      builtin rebase: support --root
      builtin rebase: optionally auto-detect the upstream
      builtin rebase: optionally pass custom reflogs to reset_head()
      builtin rebase: fast-forward to onto if it is a proper descendant
      builtin rebase: show progress when connected to a terminal
      builtin rebase: use no-op editor when interactive is "implied"
      builtin rebase: error out on incompatible option/mode combinations
      rebase: default to using the builtin rebase

Rafael Ascensão (2):
      refs: show --exclude failure with --branches/tags/remotes=glob
      refs: fix some exclude patterns being ignored

Ralf Thielow (2):
      git-rebase.sh: fix typos in error messages
      builtin/rebase.c: remove superfluous space in messages

Ramsay Jones (12):
      Makefile: add a hdr-check target
      json-writer.h: add missing include (hdr-check)
      ewah/ewok_rlw.h: add missing include (hdr-check)
      refs/ref-cache.h: add missing declarations (hdr-check)
      refs/packed-backend.h: add missing declaration (hdr-check)
      refs/refs-internal.h: add missing declarations (hdr-check)
      midx.h: add missing forward declarations (hdr-check)
      delta-islands.h: add missing forward declarations (hdr-check)
      headers: normalize the spelling of some header guards
      fetch-object.h: add missing declaration (hdr-check)
      ewok_rlw.h: add missing 'inline' to function definition
      commit-reach.h: add missing declarations (hdr-check)

Rasmus Villemoes (6):
      help: redirect to aliased commands for "git cmd --help"
      git.c: handle_alias: prepend alias info when first argument is -h
      git-help.txt: document "git help cmd" vs "git cmd --help" for aliases
      Documentation/git-send-email.txt: style fixes
      send-email: only consider lines containing @ or <> for automatic Cc'ing
      send-email: also pick up cc addresses from -by trailers

René Scharfe (12):
      mailinfo: support format=flowed
      fsck: add a performance test for skipList
      fsck: use strbuf_getline() to read skiplist file
      fsck: use oidset instead of oid_array for skipList
      sequencer: use return value of oidset_insert()
      grep: add -r/--[no-]recursive
      fetch-pack: factor out is_unmatched_ref()
      fetch-pack: load tip_oids eagerly iff needed
      khash: factor out kh_release_*
      oidset: use khash
      oidset: uninline oidset_init()
      commit-reach: fix cast in compare_commits_by_gen()

Roger Strain (1):
      subtree: performance improvement for finding unexpected parent commits

SZEDER Gábor (20):
      t1404: increase core.packedRefsTimeout to avoid occasional test failure
      Documentation/git.txt: clarify that GIT_TRACE=/path appends
      t3701-add-interactive: tighten the check of trace output
      t1700-split-index: drop unnecessary 'grep'
      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
      t1700-split-index: document why FSMONITOR is disabled in this test script
      split-index: add tests to demonstrate the racy split index problem
      t1700-split-index: date back files to avoid racy situations
      split-index: count the number of deleted entries
      split-index: don't compare cached data of entries already marked for split index
      split-index: smudge and add racily clean cache entries to split index
      split-index: BUG() when cache entry refers to non-existing shared entry
      object_id.cocci: match only expressions of type 'struct object_id'
      test-lib: introduce the '-V' short option for '--verbose-log'
      travis-ci: install packages in 'ci/install-dependencies.sh'
      coccicheck: introduce 'pending' semantic patches
      ref-filter: don't look for objects when outside of a repository
      tests: send "bug in the test script" errors to the script's stderr
      test-lib-functions: make 'test_cmp_rev' more informative on failure
      t/lib-git-daemon: fix signal checking

Sam McKelvie (1):
      rev-parse: --show-superproject-working-tree should work during a merge

Saulius Gurklys (1):
      doc: fix small typo in git show-branch

Sebastian Staudt (1):
      travis-ci: no longer use containers

Shulhan (1):
      builtin/remote: quote remote name on error to display empty name

Stefan Beller (25):
      git-submodule.sh: align error reporting for update mode to use path
      git-submodule.sh: rename unused variables
      builtin/submodule--helper: factor out submodule updating
      builtin/submodule--helper: store update_clone information in a struct
      builtin/submodule--helper: factor out method to update a single submodule
      submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
      submodule--helper: introduce new update-module-mode helper
      test_decode_color: understand FAINT and ITALIC
      t3206: add color test for range-diff --dual-color
      diff.c: simplify caller of emit_line_0
      diff.c: reorder arguments for emit_line_ws_markup
      diff.c: add set_sign to emit_line_0
      diff: use emit_line_0 once per line
      diff.c: omit check for line prefix in emit_line_0
      diff.c: rewrite emit_line_0 more understandably
      diff.c: add --output-indicator-{new, old, context}
      range-diff: make use of different output indicators
      range-diff: indent special lines as context
      refs.c: migrate internal ref iteration to pass thru repository argument
      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
      string-list: remove unused function print_string_list
      strbuf.h: format according to coding guidelines
      diff.c: pass sign_index to emit_line_ws_markup
      submodule helper: convert relative URL to absolute URL if needed
      builtin/submodule--helper: remove debugging leftover tracing

Stephen P. Smith (10):
      wt-status.c: move has_unmerged earlier in the file
      wt-status: rename commitable to committable
      t7501: add test of "commit --dry-run --short"
      wt-status.c: set the committable flag in the collect phase
      roll wt_status_state into wt_status and populate in the collect phase
      t2000: rename and combine checkout clash tests
      t7509: cleanup description and filename
      t7502: rename commit test script to comply with naming convention
      t7500: rename commit tests script to comply with naming convention
      t7501: rename commit test to comply with naming convention

Steve Hoelzer (1):
      poll: use GetTickCount64() to avoid wrap-around issues

Steven Fernandez (1):
      git-completion.bash: add completion for stash list

Strain, Roger L (4):
      subtree: refactor split of a commit into standalone method
      subtree: make --ignore-joins pay attention to adds
      subtree: use commits before rejoins for splits
      subtree: improve decision on merges kept in split

Sven Strickroth (1):
      msvc: directly use MS version (_stricmp) of strcasecmp

Tao Qingyun (3):
      refs: docstring typo
      builtin/branch.c: remove useless branch_get
      branch: trivial style fix

Taylor Blau (4):
      transport.c: extract 'fill_alternate_refs_command'
      transport.c: introduce core.alternateRefsCommand
      transport.c: introduce core.alternateRefsPrefixes
      Documentation/config.txt: fix typo in core.alternateRefsCommand

Thomas Gummerer (17):
      rerere: unify error messages when read_cache fails
      rerere: lowercase error messages
      rerere: wrap paths in output in sq
      rerere: mark strings for translation
      rerere: add documentation for conflict normalization
      rerere: fix crash with files rerere can't handle
      rerere: only return whether a path has conflicts or not
      rerere: factor out handle_conflict function
      rerere: return strbuf from handle path
      rerere: teach rerere to handle nested conflicts
      rerere: recalculate conflict ID when unresolved conflict is committed
      rerere: mention caveat about unmatched conflict markers
      rerere: add note about files with existing conflict markers
      .gitattributes: add conflict-marker-size for relevant files
      linear-assignment: fix potential out of bounds memory access
      t5551: move setup code inside test_expect blocks
      t5551: compare sorted cookies files

Tim Schumacher (4):
      Documentation/Makefile: make manpage-base-url.xsl generation quieter
      alias: add support for aliases of an alias
      alias: show the call history when an alias is looping
      t0014: introduce an alias testing suite

Todd Zullinger (1):
      Documentation: build technical/multi-pack-index

Torsten Bögershausen (5):
      Make git_check_attr() a void function
      path.c: char is not (always) signed
      Upcast size_t variables to uintmax_t when printing
      remote-curl.c: xcurl_off_t is not portable (on 32 bit platfoms)
      t5601-99: Enable colliding file detection for MINGW

Uwe Kleine-König (1):
      howto/using-merge-subtree: mention --allow-unrelated-histories

brian m. carlson (26):
      t: add test functions to translate hash-related values
      t0000: use hash translation table
      t0000: update tests for SHA-256
      t0002: abstract away SHA-1 specific constants
      t0064: make hash size independent
      t1006: make hash size independent
      t1400: switch hard-coded object ID to variable
      t1405: make hash size independent
      t1406: make hash-size independent
      t1407: make hash size independent
      editorconfig: provide editor settings for Git developers
      editorconfig: indicate settings should be kept in sync
      pack-bitmap-write: use GIT_MAX_RAWSZ for allocation
      builtin/repack: replace hard-coded constants
      builtin/mktree: remove hard-coded constant
      builtin/fetch-pack: remove constants with parse_oid_hex
      pack-revindex: express constants in terms of the_hash_algo
      packfile: express constants in terms of the_hash_algo
      refs/packed-backend: express constants using the_hash_algo
      upload-pack: express constants in terms of the_hash_algo
      transport: use parse_oid_hex instead of a constant
      tag: express constant in terms of the_hash_algo
      apply: replace hard-coded constants
      apply: rename new_sha1_prefix and old_sha1_prefix
      submodule: make zero-oid comparison hash function agnostic
      rerere: convert to use the_hash_algo

Ævar Arnfjörð Bjarmason (35):
      fetch: change "branch" to "reference" in --force -h output
      push tests: make use of unused $1 in test description
      push tests: use spaces in interpolated string
      fetch tests: add a test for clobbering tag behavior
      push doc: remove confusing mention of remote merger
      push doc: move mention of "tag <tag>" later in the prose
      push doc: correct lies about how push refspecs work
      fetch: document local ref updates with/without --force
      fetch: stop clobbering existing tags without --force
      fsck tests: setup of bogus commit object
      fsck tests: add a test for no skipList input
      fsck: document and test sorted skipList input
      fsck: document and test commented & empty line skipList input
      fsck: document that skipList input must be unabbreviated
      fsck: add a performance test
      fsck: support comments & empty lines in skipList
      commit-graph write: add progress output
      commit-graph verify: add progress output
      config doc: add missing list separator for checkout.optimizeNewBranch
      push doc: add spacing between two words
      fetch doc: correct grammar in --force docs
      gc: fix regression in 7b0f229222 impacting --quiet
      gc doc: mention the commit-graph in the intro
      pack-objects test: modernize style
      pack-objects tests: don't leave test .git corrupt at end
      index-pack tests: don't leave test repo dirty at end
      i18n: make GETTEXT_POISON a runtime option
      range-diff doc: add a section about output stability
      range-diff: fix regression in passing along diff options
      range-diff: make diff option behavior (e.g. --stat) consistent
      push: change needlessly ambiguous example in error
      rebase doc: document rebase.useBuiltin
      tests: add a special setup where rebase.useBuiltin is off
      read-cache: make the split index obey umask settings
      advice: don't pointlessly suggest --convert-graft-file

Đoàn Trần Công Danh (1):
      git-compat-util: prefer poll.h to sys/poll.h


^ permalink raw reply	[relevance 2%]

* Git Test Coverage Report (Friday Nov 30)
@ 2018-11-30 18:03  3% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-30 18:03 UTC (permalink / raw)
  To: Git List

Here is today's test coverage report.

Thanks,
-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=277

---

pu: 5a1a9a96d55fbb80426189a921d7b6cc66564c78
jch: 71c29cabb7379fe9abaacbbbd1350268d0c18b4f
next: a9faaff8c120bf4783cb892c157871fe524b3608
master: 7068cbc4abac53d9c3675dfba81c1e97d25e8eeb
master@{1}: 7f4e64169352e03476b0ea64e7e2973669e491a2

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

protocol.c
24c10f7473  37) die(_("Unrecognized protocol version"));
24c10f7473  39) die(_("Unrecognized protocol_version"));

remote-curl.c
24c10f7473  403) return 0;

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

strbuf.c
10a40f5700  397) return 0;

submodule.c
e2419f7e30 1376) strbuf_release(&gitdir);
7454fe5cb6 1499) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1503) get_next_submodule_task_release(task);
7454fe5cb6 1530) return 0;
7454fe5cb6 1534) goto out;
7454fe5cb6 1549) return 0;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Anders Waldenborg      10a40f570: strbuf: separate callback for 
strbuf_expand:ing literals
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Josh Steadmon      24c10f747: protocol: advertise multiple supported 
versions
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

pathspec.c
22af33bece 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
ee70c12820 1730) if (advice_unknown_index_extension) {
ee70c12820 1731) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1732) advise(_("This is likely due to the file having been 
written by a newer\n"

sequencer.c
18e711a162 2387) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

tree.c
e092073d64 104) commit = lookup_commit(r, entry.oid);

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths
Nguyễn Thái Ngọc Duy      22af33bec: dir.c: move, rename and export 
match_attrs()
Nguyễn Thái Ngọc Duy      e092073d6: tree.c: make read_tree*() take 
'struct repository *'



Uncovered code in 'next' not in 'master'
--------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 421) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 460) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 584) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 619) fprintf_ln(stderr, _("Checking object 
directory"));
5215bd2f7d builtin/fsck.c 637) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
5215bd2f7d builtin/fsck.c 642) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 671) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 687) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  135) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/rebase.c
13a5a9f0fd  789) return; /* only override it if it is "rebase" */

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
5215bd2f7d 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
5215bd2f7d 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
a965bb3116 1821) read_next_command();

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2251) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2286) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3100) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3247) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  236) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2353) return error(_("option `%s' is incompatible with 
--no-merged"),

remote-curl.c
afa5d74929  359) die("invalid server response; expected service, got 
flush packet");

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2145) return r;

Commits introducing uncovered code:
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      afa5d7492: remote-curl: refactor smart-http discovery
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Johannes Schindelin      13a5a9f0f: rebase: fix GIT_REFLOG_ACTION regression
Junio C Hamano      5215bd2f7: Merge branch 'nd/i18n' into next
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

transport-helper.c
739fb7167d  576) die(_("unknown response to connect: %s"),

Commits introducing uncovered code:
Nguyễn Thái Ngọc Duy      739fb7167: transport-helper.c: do not 
translate a string twice



^ permalink raw reply	[relevance 3%]

* Re: [PATCH v2 6/7] checkout: split into switch-branch and checkout-files
  2018-11-29 18:14  5%             ` Stefan Beller
@ 2018-11-29 18:30  4%               ` Duy Nguyen
  0 siblings, 0 replies; 200+ results
From: Duy Nguyen @ 2018-11-29 18:30 UTC (permalink / raw)
  To: Stefan Beller
  Cc: Stefan Xenos, Junio C Hamano,
	Ævar Arnfjörð Bjarmason, Git Mailing List,
	Thomas Gummerer

On Thu, Nov 29, 2018 at 7:14 PM Stefan Beller <sbeller@google.com> wrote:
>
> > > Idea:
> > > If git checkout-files modifies the submodules file, it could also
> > > auto-update the submodules. (For example, with something like "git
> > > submodule update --init --recursive --progress").
> >
> > This one is tricky because we should deal with submodule autoupdate
> > consistently across all porcelain commands (or at least common ones),
> > not just checkout-files. I'd prefer to delay this until later. Once we
> > figure out what to do with other commands, then we can still change
> > defaults for checkout-files.
>
> checkout/reset are respecting the submodule.recurse setting for this
> already, and as your patches only change the UX frontend
>
>     git -c submodule.recurse checkout-files <pathsspec>
>
> would also touch submodules. Given that deep down in
> the submodules it's all about files again, we could think
> checkout-files is still a good name.
>
> I think Stefan X. is asking for making submodule.recurse
> to default to true, which is indeed unrelated to this.

Yes and I'm concerned that checkout-files now recurses into submodules
this by default but grep for example does not. That just adds more
confusion.
-- 
Duy

^ permalink raw reply	[relevance 4%]

* Re: [PATCH v2 6/7] checkout: split into switch-branch and checkout-files
  @ 2018-11-29 18:14  5%             ` Stefan Beller
  2018-11-29 18:30  4%               ` Duy Nguyen
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-29 18:14 UTC (permalink / raw)
  To: Duy Nguyen
  Cc: Stefan Xenos, Junio C Hamano,
	Ævar Arnfjörð Bjarmason, git, Thomas Gummerer

> > Idea:
> > If git checkout-files modifies the submodules file, it could also
> > auto-update the submodules. (For example, with something like "git
> > submodule update --init --recursive --progress").
>
> This one is tricky because we should deal with submodule autoupdate
> consistently across all porcelain commands (or at least common ones),
> not just checkout-files. I'd prefer to delay this until later. Once we
> figure out what to do with other commands, then we can still change
> defaults for checkout-files.

checkout/reset are respecting the submodule.recurse setting for this
already, and as your patches only change the UX frontend

    git -c submodule.recurse checkout-files <pathsspec>

would also touch submodules. Given that deep down in
the submodules it's all about files again, we could think
checkout-files is still a good name.

I think Stefan X. is asking for making submodule.recurse
to default to true, which is indeed unrelated to this.

Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 09/10] fetch: try fetching submodules if needed objects were not fetched
  @ 2018-11-29  0:30  4%   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:30 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: git

On Fri, Oct 26, 2018 at 1:41 PM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > But this default fetch is not sufficient, as a newly fetched commit in
> > the superproject could point to a commit in the submodule that is not
> > in the default refspec. This is common in workflows like Gerrit's.
> > When fetching a Gerrit change under review (from refs/changes/??), the
> > commits in that change likely point to submodule commits that have not
> > been merged to a branch yet.
> >
> > Try fetching a submodule by object id if the object id that the
> > superproject points to, cannot be found.
>
> I see that these suggestions of mine (from [1]) was implemented, but not
> others. If you disagree, that's fine, but I think they should be
> discussed.

ok.

>
> > -             if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
> > -                 (recurse_submodules != RECURSE_SUBMODULES_ON))
> > +             if (recurse_submodules != RECURSE_SUBMODULES_OFF)
>
> I think the next patch should be squashed into this patch. Then you can
> say that these are now redundant and can be removed.

ok.

>
> > @@ -1218,8 +1218,12 @@ struct submodule_parallel_fetch {
> >       int result;
> >
> >       struct string_list changed_submodule_names;
> > +     struct get_next_submodule_task **fetch_specific_oids;
> > +     int fetch_specific_oids_nr, fetch_specific_oids_alloc;
> >  };
>
> Add documentation for fetch_specific_oids. Also, it might be better to
> call these oid_fetch_tasks and the struct, "struct fetch_task".

ok.

> Here, struct get_next_submodule_task is used for 2 different things:
>  (1) After the first round fetch, fetch_finish() uses it to determine if
>      a second round is needed.
>  (2) In submodule_parallel_fetch.fetch_specific_oids, to tell the
>      parallel runner (through get_next_submodule_task()) to do this
>      fetch.
>
> I think that it's better to have 2 different structs for these 2
> different uses. (Note that task_cb can be NULL for the second round.
> Unless we plan to recheck the OIDs? Currently we recheck them, but we
> don't do anything either way.)

I think it is easier to only have one struct until we have substantially
more to communicate. (1) is a boolean answer, for which (non-)NULL
is sufficient.


> I think that this is best described as the submodule that has no entry
> in .gitmodules? Maybe call it "get_non_gitmodules_submodule" and
> document it with a similar comment as in get_submodule_repo_for().

done.

>
> > +
> > +static struct get_next_submodule_task *get_next_submodule_task_create(
> > +     struct repository *r, const char *path)
> > +{
> > +     struct get_next_submodule_task *task = xmalloc(sizeof(*task));
> > +     memset(task, 0, sizeof(*task));
> > +
> > +     task->sub = submodule_from_path(r, &null_oid, path);
> > +     if (!task->sub) {
> > +             task->sub = get_default_submodule(path);
> > +             task->free_sub = 1;
> > +     }
> > +
> > +     return task;
> > +}
>
> Clearer to me would be to make get_next_submodule_task_create() return
> NULL if submodule_from_path() returns NULL.

I doubled down on this one and return NULL when get_default_submodule
(now renamed to get_non_gitmodules_submodule) returns NULL, as then we
can move the free() from get_next_submodule here and there we'll just have

    task = fetch_task_create(spf->r, ce->name);
    if (!task)
        continue;

which helps get_next_submodule to stay readable.


> Same comment about "on-demand" as in my previous e-mail.

I'd want to push back on refactoring and defer that to a later series.

> Break lines to 80.
[...]
> Same comment about "s--h" as in my previous e-mail.

done

> > +     /* Are there commits that do not exist? */
> > +     if (commits->nr) {
> > +             /* We already tried fetching them, do not try again. */
> > +             if (task->commits)
> > +                     return 0;
>
> Same comment about "task->commits" as in my previous e-mail.

Good call. I reordered the function read easier and added a comment
on any early return how it could happen.

>
> > diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
> > index 6c2f9b2ba2..5a75b57852 100755
>
> One more thing to test is the case where a submodule doesn't have a
> .gitmodules entry.

added a test.

I just resent the series.

Stefan

^ permalink raw reply	[relevance 4%]

* [PATCH 9/9] fetch: try fetching submodules if needed objects were not fetched
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (6 preceding siblings ...)
  2018-11-29  0:27 17% ` [PATCH 8/9] submodule.c: fetch in submodules git directory instead of in worktree Stefan Beller
@ 2018-11-29  0:27 22% ` Stefan Beller
  2018-12-05  3:10  7% ` [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Junio C Hamano
  2018-12-07  0:25  6% ` Josh Steadmon
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

Currently when git-fetch is asked to recurse into submodules, it dispatches
a plain "git-fetch -C <submodule-dir>" (with some submodule related options
such as prefix and recusing strategy, but) without any information of the
remote or the tip that should be fetched.

But this default fetch is not sufficient, as a newly fetched commit in
the superproject could point to a commit in the submodule that is not
in the default refspec. This is common in workflows like Gerrit's.
When fetching a Gerrit change under review (from refs/changes/??), the
commits in that change likely point to submodule commits that have not
been merged to a branch yet.

Try fetching a submodule by object id if the object id that the
superproject points to, cannot be found.

builtin/fetch used to only inspect submodules when they were fetched
"on-demand", as in either on/off case it was clear whether the submodule
needs to be fetched. However to know whether we need to try fetching the
object ids, we need to identify the object names, which is done in this
function check_for_new_submodule_commits(), so we'll also run that code
in case the submodule recursion is set to "on".

The submodule checks were done only when a ref in the superproject
changed, these checks were extended to also be performed when fetching
into FETCH_HEAD for completeness, and add a test for that too.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/fetch.c             |  11 +-
 submodule.c                 | 206 +++++++++++++++++++++++++++++++-----
 t/t5526-fetch-submodules.sh |  86 +++++++++++++++
 3 files changed, 265 insertions(+), 38 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index e0140327aa..91f9b7d9c8 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -763,9 +763,6 @@ static int update_local_ref(struct ref *ref,
 			what = _("[new ref]");
 		}
 
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
-			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref(msg, ref, 0);
 		format_display(display, r ? '!' : '*', what,
 			       r ? _("unable to update local ref") : NULL,
@@ -779,9 +776,6 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "..");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
-			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("fast-forward", ref, 1);
 		format_display(display, r ? '!' : ' ', quickref.buf,
 			       r ? _("unable to update local ref") : NULL,
@@ -794,9 +788,6 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "...");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
-			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("forced-update", ref, 1);
 		format_display(display, r ? '!' : '+', quickref.buf,
 			       r ? _("unable to update local ref") : _("forced update"),
@@ -892,6 +883,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 				ref->force = rm->peer_ref->force;
 			}
 
+			if (recurse_submodules != RECURSE_SUBMODULES_OFF)
+				check_for_new_submodule_commits(&rm->old_oid);
 
 			if (!strcmp(rm->name, "HEAD")) {
 				kind = "";
diff --git a/submodule.c b/submodule.c
index d1b6646f42..1ce944a737 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1231,8 +1231,14 @@ struct submodule_parallel_fetch {
 	int result;
 
 	struct string_list changed_submodule_names;
+
+	/* The submodules to fetch in */
+	struct fetch_task **oid_fetch_tasks;
+	int oid_fetch_tasks_nr, oid_fetch_tasks_alloc;
 };
-#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \
+		  STRING_LIST_INIT_DUP, \
+		  NULL, 0, 0}
 
 static int get_fetch_recurse_config(const struct submodule *submodule,
 				    struct submodule_parallel_fetch *spf)
@@ -1259,6 +1265,73 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+struct fetch_task {
+	struct repository *repo;
+	const struct submodule *sub;
+	unsigned free_sub : 1; /* Do we need to free the submodule? */
+
+	/* fetch specific oids if set, otherwise fetch default refspec */
+	struct oid_array *commits;
+};
+
+/**
+ * When a submodule is not defined in .gitmodules, we cannot access it
+ * via the regular submodule-config. Create a fake submodule, which we can
+ * work on.
+ */
+static const struct submodule *get_non_gitmodules_submodule(const char *path)
+{
+	struct submodule *ret = NULL;
+	const char *name = default_name_or_path(path);
+
+	if (!name)
+		return NULL;
+
+	ret = xmalloc(sizeof(*ret));
+	memset(ret, 0, sizeof(*ret));
+	ret->path = name;
+	ret->name = name;
+
+	return (const struct submodule *) ret;
+}
+
+static struct fetch_task *fetch_task_create(struct repository *r,
+					    const char *path)
+{
+	struct fetch_task *task = xmalloc(sizeof(*task));
+	memset(task, 0, sizeof(*task));
+
+	task->sub = submodule_from_path(r, &null_oid, path);
+	if (!task->sub) {
+		/*
+		 * No entry in .gitmodules? Technically not a submodule,
+		 * but historically we supported repositories that happen to be
+		 * in-place where a gitlink is. Keep supporting them.
+		 */
+		task->sub = get_non_gitmodules_submodule(path);
+		if (!task->sub) {
+			free(task);
+			return NULL;
+		}
+
+		task->free_sub = 1;
+	}
+
+	return task;
+}
+
+static void fetch_task_release(struct fetch_task *p)
+{
+	if (p->free_sub)
+		free((void*)p->sub);
+	p->free_sub = 0;
+	p->sub = NULL;
+
+	if (p->repo)
+		repo_clear(p->repo);
+	FREE_AND_NULL(p->repo);
+}
+
 static struct repository *get_submodule_repo_for(struct repository *r,
 						 const struct submodule *sub)
 {
@@ -1286,39 +1359,32 @@ static struct repository *get_submodule_repo_for(struct repository *r,
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
-	int ret = 0;
 	struct submodule_parallel_fetch *spf = data;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
-		struct strbuf submodule_prefix = STRBUF_INIT;
+		int recurse_config;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *default_argv;
-		const struct submodule *submodule;
-		struct repository *repo;
-		struct submodule default_submodule = SUBMODULE_INIT;
+		struct fetch_task *task;
 
 		if (!S_ISGITLINK(ce->ce_mode))
 			continue;
 
-		submodule = submodule_from_path(spf->r, &null_oid, ce->name);
-		if (!submodule) {
-			const char *name = default_name_or_path(ce->name);
-			if (name) {
-				default_submodule.path = name;
-				default_submodule.name = name;
-				submodule = &default_submodule;
-			}
-		}
+		task = fetch_task_create(spf->r, ce->name);
+		if (!task)
+			continue;
+
+		recurse_config = get_fetch_recurse_config(task->sub, spf);
 
-		switch (get_fetch_recurse_config(submodule, spf))
+		switch (recurse_config)
 		{
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule ||
+			if (!task->sub ||
 			    !string_list_lookup(
 					&spf->changed_submodule_names,
-					submodule->name))
+					task->sub->name))
 				continue;
 			default_argv = "on-demand";
 			break;
@@ -1329,11 +1395,11 @@ static int get_next_submodule(struct child_process *cp,
 			continue;
 		}
 
-		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
-		repo = get_submodule_repo_for(spf->r, submodule);
-		if (repo) {
+		task->repo = get_submodule_repo_for(spf->r, task->sub);
+		if (task->repo) {
+			struct strbuf submodule_prefix = STRBUF_INIT;
 			child_process_init(cp);
-			cp->dir = xstrdup(repo->gitdir);
+			cp->dir = task->repo->gitdir;
 			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
 			cp->git_cmd = 1;
 			if (!spf->quiet)
@@ -1343,12 +1409,22 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_pushv(&cp->args, spf->args.argv);
 			argv_array_push(&cp->args, default_argv);
 			argv_array_push(&cp->args, "--submodule-prefix");
+
+			strbuf_addf(&submodule_prefix, "%s%s/",
+						       spf->prefix,
+						       task->sub->path);
 			argv_array_push(&cp->args, submodule_prefix.buf);
 
-			repo_clear(repo);
-			free(repo);
-			ret = 1;
+			spf->count++;
+			*task_cb = task;
+
+			strbuf_release(&submodule_prefix);
+			return 1;
 		} else {
+
+			fetch_task_release(task);
+			free(task);
+
 			/*
 			 * An empty directory is normal,
 			 * the submodule is not initialized
@@ -1361,12 +1437,38 @@ static int get_next_submodule(struct child_process *cp,
 					    ce->name);
 			}
 		}
+	}
+
+	if (spf->oid_fetch_tasks_nr) {
+		struct fetch_task *task =
+			spf->oid_fetch_tasks[spf->oid_fetch_tasks_nr - 1];
+		struct strbuf submodule_prefix = STRBUF_INIT;
+		spf->oid_fetch_tasks_nr--;
+
+		strbuf_addf(&submodule_prefix, "%s%s/",
+			    spf->prefix, task->sub->path);
+
+		child_process_init(cp);
+		prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+		cp->git_cmd = 1;
+		cp->dir = task->repo->gitdir;
+
+		argv_array_init(&cp->args);
+		argv_array_pushv(&cp->args, spf->args.argv);
+		argv_array_push(&cp->args, "on-demand");
+		argv_array_push(&cp->args, "--submodule-prefix");
+		argv_array_push(&cp->args, submodule_prefix.buf);
+
+		/* NEEDSWORK: have get_default_remote from submodule--helper */
+		argv_array_push(&cp->args, "origin");
+		oid_array_for_each_unique(task->commits,
+					  append_oid_to_argv, &cp->args);
+
+		*task_cb = task;
 		strbuf_release(&submodule_prefix);
-		if (ret) {
-			spf->count++;
-			return 1;
-		}
+		return 1;
 	}
+
 	return 0;
 }
 
@@ -1374,20 +1476,66 @@ static int fetch_start_failure(struct strbuf *err,
 			       void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct fetch_task *task = task_cb;
 
 	spf->result = 1;
 
+	fetch_task_release(task);
 	return 0;
 }
 
+static int commit_exists_in_sub(const struct object_id *oid, void *data)
+{
+	struct repository *subrepo = data;
+
+	enum object_type type = oid_object_info(subrepo, oid, NULL);
+
+	return type != OBJ_COMMIT;
+}
+
 static int fetch_finish(int retvalue, struct strbuf *err,
 			void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct fetch_task *task = task_cb;
+
+	struct string_list_item *it;
+	struct oid_array *commits;
 
 	if (retvalue)
 		spf->result = 1;
 
+	if (!task || !task->sub)
+		BUG("callback cookie bogus");
+
+	/* Is this the second time we process this submodule? */
+	if (task->commits)
+		return 0;
+
+	it = string_list_lookup(&spf->changed_submodule_names, task->sub->name);
+	if (!it)
+		/* Could be an unchanged submodule, not contained in the list */
+		goto out;
+
+	commits = it->util;
+	oid_array_filter(commits,
+			 commit_exists_in_sub,
+			 task->repo);
+
+	/* Are there commits we want, but do not exist? */
+	if (commits->nr) {
+		task->commits = commits;
+		ALLOC_GROW(spf->oid_fetch_tasks,
+			   spf->oid_fetch_tasks_nr + 1,
+			   spf->oid_fetch_tasks_alloc);
+		spf->oid_fetch_tasks[spf->oid_fetch_tasks_nr] = task;
+		spf->oid_fetch_tasks_nr++;
+		return 0;
+	}
+
+out:
+	fetch_task_release(task);
+
 	return 0;
 }
 
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 6c2f9b2ba2..8a016272bc 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -600,4 +600,90 @@ test_expect_success "fetch new commits when submodule got renamed" '
 	test_cmp expect actual
 '
 
+test_expect_success "fetch new submodule commits on-demand outside standard refspec" '
+	# add a second submodule and ensure it is around in downstream first
+	git clone submodule sub1 &&
+	git submodule add ./sub1 &&
+	git commit -m "adding a second submodule" &&
+	git -C downstream pull &&
+	git -C downstream submodule update --init --recursive &&
+
+	git checkout --detach &&
+
+	C=$(git -C submodule commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/1 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	test_tick &&
+
+	D=$(git -C sub1 commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
+	git -C sub1 update-ref refs/changes/2 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+
+	git commit -m "updated submodules outside of refs/heads" &&
+	E=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/3 $E &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/3:refs/heads/my_branch &&
+		git -C submodule cat-file -t $C &&
+		git -C sub1 cat-file -t $D &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
+test_expect_success 'fetch new submodule commits on-demand in FETCH_HEAD' '
+	# depends on the previous test for setup
+
+	C=$(git -C submodule commit-tree -m "another change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/4 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	test_tick &&
+
+	D=$(git -C sub1 commit-tree -m "another change outside refs/heads" HEAD^{tree}) &&
+	git -C sub1 update-ref refs/changes/5 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+
+	git commit -m "updated submodules outside of refs/heads" &&
+	E=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/6 $E &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/6 &&
+		git -C submodule cat-file -t $C &&
+		git -C sub1 cat-file -t $D &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
+test_expect_success 'fetch new submodule commits on-demand without .gitmodules entry' '
+	# depends on the previous test for setup
+
+	git config -f .gitmodules --remove-section submodule.sub1 &&
+	git add .gitmodules &&
+	git commit -m "delete gitmodules file" &&
+	git checkout -B master &&
+	git -C downstream fetch &&
+	git -C downstream checkout origin/master &&
+
+	C=$(git -C submodule commit-tree -m "yet another change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/7 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	test_tick &&
+
+	D=$(git -C sub1 commit-tree -m "yet another change outside refs/heads" HEAD^{tree}) &&
+	git -C sub1 update-ref refs/changes/8 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+
+	git commit -m "updated submodules outside of refs/heads" &&
+	E=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/9 $E &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/9 &&
+		git -C submodule cat-file -t $C &&
+		git -C sub1 cat-file -t $D &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
 test_done
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related	[relevance 22%]

* [PATCH 8/9] submodule.c: fetch in submodules git directory instead of in worktree
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (5 preceding siblings ...)
  2018-11-29  0:27 23% ` [PATCH 7/9] submodule: migrate get_next_submodule to use repository structs Stefan Beller
@ 2018-11-29  0:27 17% ` Stefan Beller
  2018-11-29  0:27 22% ` [PATCH 9/9] fetch: try fetching submodules if needed objects were not fetched Stefan Beller
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

Keep the properties introduced in 10f5c52656 (submodule: avoid
auto-discovery in prepare_submodule_repo_env(), 2016-09-01), by fixating
the git directory of the submodule.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/submodule.c b/submodule.c
index 77ace5e784..d1b6646f42 100644
--- a/submodule.c
+++ b/submodule.c
@@ -494,6 +494,12 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
+static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out)
+{
+	prepare_submodule_repo_env_no_git_dir(out);
+	argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT);
+}
+
 /* Helper function to display the submodule header line prior to the full
  * summary output. If it can locate the submodule objects directory it will
  * attempt to lookup both the left and right commits and put them into the
@@ -1327,8 +1333,8 @@ static int get_next_submodule(struct child_process *cp,
 		repo = get_submodule_repo_for(spf->r, submodule);
 		if (repo) {
 			child_process_init(cp);
-			cp->dir = xstrdup(repo->worktree);
-			prepare_submodule_repo_env(&cp->env_array);
+			cp->dir = xstrdup(repo->gitdir);
+			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related	[relevance 17%]

* [PATCH 7/9] submodule: migrate get_next_submodule to use repository structs
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (4 preceding siblings ...)
  2018-11-29  0:27 25% ` [PATCH 6/9] repository: repo_submodule_init to take a submodule struct Stefan Beller
@ 2018-11-29  0:27 23% ` Stefan Beller
  2019-02-02  1:58  4%   ` Jonathan Nieder
  2018-11-29  0:27 17% ` [PATCH 8/9] submodule.c: fetch in submodules git directory instead of in worktree Stefan Beller
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

We used to recurse into submodules, even if they were broken having
only an objects directory. The child process executed in the submodule
would fail though if the submodule was broken. This is tested via
"fetching submodule into a broken repository" in t5526.

This patch tightens the check upfront, such that we do not need
to spawn a child process to find out if the submodule is broken.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 56 +++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 44 insertions(+), 12 deletions(-)

diff --git a/submodule.c b/submodule.c
index 0c81aca6f2..77ace5e784 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1253,6 +1253,30 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+static struct repository *get_submodule_repo_for(struct repository *r,
+						 const struct submodule *sub)
+{
+	struct repository *ret = xmalloc(sizeof(*ret));
+
+	if (repo_submodule_init(ret, r, sub)) {
+		/*
+		 * No entry in .gitmodules? Technically not a submodule,
+		 * but historically we supported repositories that happen to be
+		 * in-place where a gitlink is. Keep supporting them.
+		 */
+		struct strbuf gitdir = STRBUF_INIT;
+		strbuf_repo_worktree_path(&gitdir, r, "%s/.git", sub->path);
+		if (repo_init(ret, gitdir.buf, NULL)) {
+			strbuf_release(&gitdir);
+			free(ret);
+			return NULL;
+		}
+		strbuf_release(&gitdir);
+	}
+
+	return ret;
+}
+
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
@@ -1260,12 +1284,11 @@ static int get_next_submodule(struct child_process *cp,
 	struct submodule_parallel_fetch *spf = data;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
-		struct strbuf submodule_path = STRBUF_INIT;
-		struct strbuf submodule_git_dir = STRBUF_INIT;
 		struct strbuf submodule_prefix = STRBUF_INIT;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
-		const char *git_dir, *default_argv;
+		const char *default_argv;
 		const struct submodule *submodule;
+		struct repository *repo;
 		struct submodule default_submodule = SUBMODULE_INIT;
 
 		if (!S_ISGITLINK(ce->ce_mode))
@@ -1300,15 +1323,11 @@ static int get_next_submodule(struct child_process *cp,
 			continue;
 		}
 
-		strbuf_repo_worktree_path(&submodule_path, spf->r, "%s", ce->name);
-		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
 		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
-		git_dir = read_gitfile(submodule_git_dir.buf);
-		if (!git_dir)
-			git_dir = submodule_git_dir.buf;
-		if (is_directory(git_dir)) {
+		repo = get_submodule_repo_for(spf->r, submodule);
+		if (repo) {
 			child_process_init(cp);
-			cp->dir = strbuf_detach(&submodule_path, NULL);
+			cp->dir = xstrdup(repo->worktree);
 			prepare_submodule_repo_env(&cp->env_array);
 			cp->git_cmd = 1;
 			if (!spf->quiet)
@@ -1319,10 +1338,23 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_push(&cp->args, default_argv);
 			argv_array_push(&cp->args, "--submodule-prefix");
 			argv_array_push(&cp->args, submodule_prefix.buf);
+
+			repo_clear(repo);
+			free(repo);
 			ret = 1;
+		} else {
+			/*
+			 * An empty directory is normal,
+			 * the submodule is not initialized
+			 */
+			if (S_ISGITLINK(ce->ce_mode) &&
+			    !is_empty_dir(ce->name)) {
+				spf->result = 1;
+				strbuf_addf(err,
+					    _("Could not access submodule '%s'"),
+					    ce->name);
+			}
 		}
-		strbuf_release(&submodule_path);
-		strbuf_release(&submodule_git_dir);
 		strbuf_release(&submodule_prefix);
 		if (ret) {
 			spf->count++;
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related	[relevance 23%]

* [PATCH 6/9] repository: repo_submodule_init to take a submodule struct
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (3 preceding siblings ...)
  2018-11-29  0:27 16% ` [PATCH 5/9] submodule: store OIDs in changed_submodule_names Stefan Beller
@ 2018-11-29  0:27 25% ` Stefan Beller
  2018-11-29  0:27 23% ` [PATCH 7/9] submodule: migrate get_next_submodule to use repository structs Stefan Beller
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

When constructing a struct repository for a submodule for some revision
of the superproject where the submodule is not contained in the index,
it may not be present in the working tree currently either. In that
situation giving a 'path' argument is not useful. Upgrade the
repo_submodule_init function to take a struct submodule instead.
The submodule struct can be obtained via submodule_from_{path, name} or
an artificial submodule struct can be passed in.

While we are at it, rename the repository struct in the repo_submodule_init
function, which is to be initialized, to a name that is not confused with
the struct submodule as easily. Perform such renames in similar functions
as well.

Also move its documentation into the header file.

Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/grep.c                               | 17 +++++++-----
 builtin/ls-files.c                           | 12 +++++----
 builtin/submodule--helper.c                  |  2 +-
 repository.c                                 | 27 ++++++++------------
 repository.h                                 | 12 +++++++--
 t/helper/test-submodule-nested-repo-config.c |  8 +++---
 6 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 71df52a333..d6bd887b2d 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -404,7 +404,10 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 			  const struct object_id *oid,
 			  const char *filename, const char *path)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub = submodule_from_path(superproject,
+							  &null_oid, path);
+
 	int hit;
 
 	/*
@@ -420,12 +423,12 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 		return 0;
 	}
 
-	if (repo_submodule_init(&submodule, superproject, path)) {
+	if (repo_submodule_init(&subrepo, superproject, sub)) {
 		grep_read_unlock();
 		return 0;
 	}
 
-	repo_read_gitmodules(&submodule);
+	repo_read_gitmodules(&subrepo);
 
 	/*
 	 * NEEDSWORK: This adds the submodule's object directory to the list of
@@ -437,7 +440,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 	 * store is no longer global and instead is a member of the repository
 	 * object.
 	 */
-	add_to_alternates_memory(submodule.objects->objectdir);
+	add_to_alternates_memory(subrepo.objects->objectdir);
 	grep_read_unlock();
 
 	if (oid) {
@@ -462,14 +465,14 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 
 		init_tree_desc(&tree, data, size);
 		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-				object->type == OBJ_COMMIT, &submodule);
+				object->type == OBJ_COMMIT, &subrepo);
 		strbuf_release(&base);
 		free(data);
 	} else {
-		hit = grep_cache(opt, &submodule, pathspec, 1);
+		hit = grep_cache(opt, &subrepo, pathspec, 1);
 	}
 
-	repo_clear(&submodule);
+	repo_clear(&subrepo);
 	return hit;
 }
 
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c70a9c7158..583a0e1ca2 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -206,17 +206,19 @@ static void show_files(struct repository *repo, struct dir_struct *dir);
 static void show_submodule(struct repository *superproject,
 			   struct dir_struct *dir, const char *path)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub = submodule_from_path(superproject,
+							  &null_oid, path);
 
-	if (repo_submodule_init(&submodule, superproject, path))
+	if (repo_submodule_init(&subrepo, superproject, sub))
 		return;
 
-	if (repo_read_index(&submodule) < 0)
+	if (repo_read_index(&subrepo) < 0)
 		die("index file corrupt");
 
-	show_files(&submodule, dir);
+	show_files(&subrepo, dir);
 
-	repo_clear(&submodule);
+	repo_clear(&subrepo);
 }
 
 static void show_ce(struct repository *repo, struct dir_struct *dir,
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index d38113a31a..4eceb8f040 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2053,7 +2053,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
 	if (!sub)
 		BUG("We could get the submodule handle before?");
 
-	if (repo_submodule_init(&subrepo, the_repository, path))
+	if (repo_submodule_init(&subrepo, the_repository, sub))
 		die(_("could not get a repository handle for submodule '%s'"), path);
 
 	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
diff --git a/repository.c b/repository.c
index 5dd1486718..aabe64ee5d 100644
--- a/repository.c
+++ b/repository.c
@@ -166,30 +166,23 @@ int repo_init(struct repository *repo,
 	return -1;
 }
 
-/*
- * Initialize 'submodule' as the submodule given by 'path' in parent repository
- * 'superproject'.
- * Return 0 upon success and a non-zero value upon failure.
- */
-int repo_submodule_init(struct repository *submodule,
+int repo_submodule_init(struct repository *subrepo,
 			struct repository *superproject,
-			const char *path)
+			const struct submodule *sub)
 {
-	const struct submodule *sub;
 	struct strbuf gitdir = STRBUF_INIT;
 	struct strbuf worktree = STRBUF_INIT;
 	int ret = 0;
 
-	sub = submodule_from_path(superproject, &null_oid, path);
 	if (!sub) {
 		ret = -1;
 		goto out;
 	}
 
-	strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path);
-	strbuf_repo_worktree_path(&worktree, superproject, "%s", path);
+	strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", sub->path);
+	strbuf_repo_worktree_path(&worktree, superproject, "%s", sub->path);
 
-	if (repo_init(submodule, gitdir.buf, worktree.buf)) {
+	if (repo_init(subrepo, gitdir.buf, worktree.buf)) {
 		/*
 		 * If initilization fails then it may be due to the submodule
 		 * not being populated in the superproject's worktree.  Instead
@@ -201,16 +194,16 @@ int repo_submodule_init(struct repository *submodule,
 		strbuf_repo_git_path(&gitdir, superproject,
 				     "modules/%s", sub->name);
 
-		if (repo_init(submodule, gitdir.buf, NULL)) {
+		if (repo_init(subrepo, gitdir.buf, NULL)) {
 			ret = -1;
 			goto out;
 		}
 	}
 
-	submodule->submodule_prefix = xstrfmt("%s%s/",
-					      superproject->submodule_prefix ?
-					      superproject->submodule_prefix :
-					      "", path);
+	subrepo->submodule_prefix = xstrfmt("%s%s/",
+					    superproject->submodule_prefix ?
+					    superproject->submodule_prefix :
+					    "", sub->path);
 
 out:
 	strbuf_release(&gitdir);
diff --git a/repository.h b/repository.h
index 9f16c42c1e..0e482b7d49 100644
--- a/repository.h
+++ b/repository.h
@@ -116,9 +116,17 @@ void repo_set_worktree(struct repository *repo, const char *path);
 void repo_set_hash_algo(struct repository *repo, int algo);
 void initialize_the_repository(void);
 int repo_init(struct repository *r, const char *gitdir, const char *worktree);
-int repo_submodule_init(struct repository *submodule,
+
+/*
+ * Initialize the repository 'subrepo' as the submodule given by the
+ * struct submodule 'sub' in parent repository 'superproject'.
+ * Return 0 upon success and a non-zero value upon failure, which may happen
+ * if the submodule is not found, or 'sub' is NULL.
+ */
+struct submodule;
+int repo_submodule_init(struct repository *subrepo,
 			struct repository *superproject,
-			const char *path);
+			const struct submodule *sub);
 void repo_clear(struct repository *repo);
 
 /*
diff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c
index a31e2a9bea..bc97929bbc 100644
--- a/t/helper/test-submodule-nested-repo-config.c
+++ b/t/helper/test-submodule-nested-repo-config.c
@@ -10,19 +10,21 @@ static void die_usage(int argc, const char **argv, const char *msg)
 
 int cmd__submodule_nested_repo_config(int argc, const char **argv)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub;
 
 	if (argc < 3)
 		die_usage(argc, argv, "Wrong number of arguments.");
 
 	setup_git_directory();
 
-	if (repo_submodule_init(&submodule, the_repository, argv[1])) {
+	sub = submodule_from_path(the_repository, &null_oid, argv[1]);
+	if (repo_submodule_init(&subrepo, the_repository, sub)) {
 		die_usage(argc, argv, "Submodule not found.");
 	}
 
 	/* Read the config of _child_ submodules. */
-	print_config_from_gitmodules(&submodule, argv[2]);
+	print_config_from_gitmodules(&subrepo, argv[2]);
 
 	submodule_free(the_repository);
 
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related	[relevance 25%]

* [PATCH 5/9] submodule: store OIDs in changed_submodule_names
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (2 preceding siblings ...)
  2018-11-29  0:27 16% ` [PATCH 4/9] submodule.c: tighten scope of changed_submodule_names struct Stefan Beller
@ 2018-11-29  0:27 16% ` Stefan Beller
  2018-11-29  0:27 25% ` [PATCH 6/9] repository: repo_submodule_init to take a submodule struct Stefan Beller
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

'calculate_changed_submodule_paths' uses a local list to compute the
changed submodules, and then produces the result by copying appropriate
items into the result list.

Instead use the result list directly and prune items afterwards
using string_list_remove_empty_items.

By doing so we'll have access to the util pointer for longer that
contains the commits that we need to fetch, which will be
useful in a later patch.

Signed-off-by: Stefan Beller <sbeller@google.com>
Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
---
 submodule.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/submodule.c b/submodule.c
index f93f0aff82..0c81aca6f2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1139,8 +1139,7 @@ static void calculate_changed_submodule_paths(struct repository *r,
 		struct string_list *changed_submodule_names)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
-	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
-	const struct string_list_item *name;
+	struct string_list_item *name;
 
 	/* No need to check if there are no submodules configured */
 	if (!submodule_from_path(r, NULL, NULL))
@@ -1157,9 +1156,9 @@ static void calculate_changed_submodule_paths(struct repository *r,
 	 * Collect all submodules (whether checked out or not) for which new
 	 * commits have been recorded upstream in "changed_submodule_names".
 	 */
-	collect_changed_submodules(r, &changed_submodules, &argv);
+	collect_changed_submodules(r, changed_submodule_names, &argv);
 
-	for_each_string_list_item(name, &changed_submodules) {
+	for_each_string_list_item(name, changed_submodule_names) {
 		struct oid_array *commits = name->util;
 		const struct submodule *submodule;
 		const char *path = NULL;
@@ -1173,12 +1172,14 @@ static void calculate_changed_submodule_paths(struct repository *r,
 		if (!path)
 			continue;
 
-		if (!submodule_has_commits(r, path, commits))
-			string_list_append(changed_submodule_names,
-					   name->string);
+		if (submodule_has_commits(r, path, commits)) {
+			oid_array_clear(commits);
+			*name->string = '\0';
+		}
 	}
 
-	free_submodules_oids(&changed_submodules);
+	string_list_remove_empty_items(changed_submodule_names, 1);
+
 	argv_array_clear(&argv);
 	oid_array_clear(&ref_tips_before_fetch);
 	oid_array_clear(&ref_tips_after_fetch);
@@ -1389,7 +1390,7 @@ int fetch_populated_submodules(struct repository *r,
 
 	argv_array_clear(&spf.args);
 out:
-	string_list_clear(&spf.changed_submodule_names, 1);
+	free_submodules_oids(&spf.changed_submodule_names);
 	return spf.result;
 }
 
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related	[relevance 16%]

* [PATCH 4/9] submodule.c: tighten scope of changed_submodule_names struct
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
  2018-11-29  0:27 24% ` [PATCH 2/9] submodule.c: fix indentation Stefan Beller
  2018-11-29  0:27 16% ` [PATCH 3/9] submodule.c: sort changed_submodule_names before searching it Stefan Beller
@ 2018-11-29  0:27 16% ` Stefan Beller
  2018-11-29  0:27 16% ` [PATCH 5/9] submodule: store OIDs in changed_submodule_names Stefan Beller
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

The `changed_submodule_names` are only used for fetching, so let's make it
part of the struct that is passed around for fetching submodules.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/submodule.c b/submodule.c
index 3c388f85cc..f93f0aff82 100644
--- a/submodule.c
+++ b/submodule.c
@@ -25,7 +25,6 @@
 #include "commit-reach.h"
 
 static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
-static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
 static int initialized_fetch_ref_tips;
 static struct oid_array ref_tips_before_fetch;
 static struct oid_array ref_tips_after_fetch;
@@ -1136,7 +1135,8 @@ void check_for_new_submodule_commits(struct object_id *oid)
 	oid_array_append(&ref_tips_after_fetch, oid);
 }
 
-static void calculate_changed_submodule_paths(struct repository *r)
+static void calculate_changed_submodule_paths(struct repository *r,
+		struct string_list *changed_submodule_names)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
 	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
@@ -1174,7 +1174,8 @@ static void calculate_changed_submodule_paths(struct repository *r)
 			continue;
 
 		if (!submodule_has_commits(r, path, commits))
-			string_list_append(&changed_submodule_names, name->string);
+			string_list_append(changed_submodule_names,
+					   name->string);
 	}
 
 	free_submodules_oids(&changed_submodules);
@@ -1221,8 +1222,10 @@ struct submodule_parallel_fetch {
 	int default_option;
 	int quiet;
 	int result;
+
+	struct string_list changed_submodule_names;
 };
-#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0}
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
 
 static int get_fetch_recurse_config(const struct submodule *submodule,
 				    struct submodule_parallel_fetch *spf)
@@ -1284,7 +1287,7 @@ static int get_next_submodule(struct child_process *cp,
 		case RECURSE_SUBMODULES_ON_DEMAND:
 			if (!submodule ||
 			    !string_list_lookup(
-					&changed_submodule_names,
+					&spf->changed_submodule_names,
 					submodule->name))
 				continue;
 			default_argv = "on-demand";
@@ -1376,8 +1379,8 @@ int fetch_populated_submodules(struct repository *r,
 	argv_array_push(&spf.args, "--recurse-submodules-default");
 	/* default value, "--submodule-prefix" and its value are added later */
 
-	calculate_changed_submodule_paths(r);
-	string_list_sort(&changed_submodule_names);
+	calculate_changed_submodule_paths(r, &spf.changed_submodule_names);
+	string_list_sort(&spf.changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
@@ -1386,7 +1389,7 @@ int fetch_populated_submodules(struct repository *r,
 
 	argv_array_clear(&spf.args);
 out:
-	string_list_clear(&changed_submodule_names, 1);
+	string_list_clear(&spf.changed_submodule_names, 1);
 	return spf.result;
 }
 
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related	[relevance 16%]

* [PATCH 3/9] submodule.c: sort changed_submodule_names before searching it
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
  2018-11-29  0:27 24% ` [PATCH 2/9] submodule.c: fix indentation Stefan Beller
@ 2018-11-29  0:27 16% ` Stefan Beller
  2018-11-29  0:27 16% ` [PATCH 4/9] submodule.c: tighten scope of changed_submodule_names struct Stefan Beller
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller, Junio C Hamano

We can string_list_insert() to maintain sorted-ness of the
list as we find new items, or we can string_list_append() to
build an unsorted list and sort it at the end just once.

As we do not rely on the sortedness while building the
list, we pick the "append and sort at the end" as it
has better worst case execution times.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/submodule.c b/submodule.c
index bc48ea3b68..3c388f85cc 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1283,7 +1283,7 @@ static int get_next_submodule(struct child_process *cp,
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
 			if (!submodule ||
-			    !unsorted_string_list_lookup(
+			    !string_list_lookup(
 					&changed_submodule_names,
 					submodule->name))
 				continue;
@@ -1377,6 +1377,7 @@ int fetch_populated_submodules(struct repository *r,
 	/* default value, "--submodule-prefix" and its value are added later */
 
 	calculate_changed_submodule_paths(r);
+	string_list_sort(&changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related	[relevance 16%]

* [PATCH 2/9] submodule.c: fix indentation
  2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
@ 2018-11-29  0:27 24% ` Stefan Beller
  2018-11-29  0:27 16% ` [PATCH 3/9] submodule.c: sort changed_submodule_names before searching it Stefan Beller
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller, Junio C Hamano

The submodule subsystem is really bad at staying within 80 characters.
Fix it while we are here.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index 6415cc5580..bc48ea3b68 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1271,7 +1271,8 @@ static int get_next_submodule(struct child_process *cp,
 		if (!submodule) {
 			const char *name = default_name_or_path(ce->name);
 			if (name) {
-				default_submodule.path = default_submodule.name = name;
+				default_submodule.path = name;
+				default_submodule.name = name;
 				submodule = &default_submodule;
 			}
 		}
@@ -1281,8 +1282,10 @@ static int get_next_submodule(struct child_process *cp,
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule || !unsorted_string_list_lookup(&changed_submodule_names,
-							 submodule->name))
+			if (!submodule ||
+			    !unsorted_string_list_lookup(
+					&changed_submodule_names,
+					submodule->name))
 				continue;
 			default_argv = "on-demand";
 			break;
-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply related	[relevance 24%]

* [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip
@ 2018-11-29  0:27 10% Stefan Beller
  2018-11-29  0:27 24% ` [PATCH 2/9] submodule.c: fix indentation Stefan Beller
                   ` (9 more replies)
  0 siblings, 10 replies; 200+ results
From: Stefan Beller @ 2018-11-29  0:27 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

This is a resend of sb/submodule-recursive-fetch-gets-the-tip,
with all feedback addressed. As it took some time, I'll send it
without range-diff, but would ask for full review.

I plan on resending after the next release as this got delayed quite a bit,
which is why I also rebased it to master.

Thanks,
Stefan

Previous round:
https://public-inbox.org/git/20181016181327.107186-1-sbeller@google.com/

Stefan Beller (9):
  sha1-array: provide oid_array_filter
  submodule.c: fix indentation
  submodule.c: sort changed_submodule_names before searching it
  submodule.c: tighten scope of changed_submodule_names struct
  submodule: store OIDs in changed_submodule_names
  repository: repo_submodule_init to take a submodule struct
  submodule: migrate get_next_submodule to use repository structs
  submodule.c: fetch in submodules git directory instead of in worktree
  fetch: try fetching submodules if needed objects were not fetched

 Documentation/technical/api-oid-array.txt    |   5 +
 builtin/fetch.c                              |  11 +-
 builtin/grep.c                               |  17 +-
 builtin/ls-files.c                           |  12 +-
 builtin/submodule--helper.c                  |   2 +-
 repository.c                                 |  27 +-
 repository.h                                 |  12 +-
 sha1-array.c                                 |  17 ++
 sha1-array.h                                 |   3 +
 submodule.c                                  | 284 ++++++++++++++++---
 t/helper/test-submodule-nested-repo-config.c |   8 +-
 t/t5526-fetch-submodules.sh                  |  86 ++++++
 12 files changed, 395 insertions(+), 89 deletions(-)

-- 
2.20.0.rc1.387.gf8505762e3-goog


^ permalink raw reply	[relevance 10%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-16  0:31  6%               ` Michael Forney
@ 2018-11-27  0:03  4%                 ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-27  0:03 UTC (permalink / raw)
  To: Michael Forney; +Cc: git

On Thu, Nov 15, 2018 at 4:31 PM Michael Forney <mforney@mforney.org> wrote:
>
> On 2018-11-15, Stefan Beller <sbeller@google.com> wrote:
> > On Thu, Nov 15, 2018 at 1:33 PM Michael Forney <mforney@mforney.org> wrote:
> >> Well, currently the submodule config can be disabled in diff_flags by
> >> setting override_submodule_config=1. However, I'm thinking it may be
> >> simpler to selectively *enable* the submodule config in diff_flags
> >> where it is needed instead of disabling it everywhere else (i.e.
> >> use_submodule_config instead of override_submodule_config).
> >
> > This sounds like undoing the good(?) part of the series that introduced
> > this regression, as before that we selectively loaded the submodule
> > config, which lead to confusion when you forgot it. Selectively *enabling*
> > the submodule config sounds like that state before?
> >
> > Or do we *only* talk about enabling the ignore flag, while loading the
> > rest of the submodule config automatic?
>
> Yes, that is what I meant. I believe the automatic loading of
> submodule config is the right thing to do, it just uncovered cases
> where the current handling of override_submodule_config is not quite
> sufficient.

That sounds good.

>
> My suggestion of replacing override_submodule_config with
> use_submodule_config is because it seems like there are fewer places
> where we want to apply the ignore config than not. I think it should
> only apply in diffs against the working tree and when staging changes
> to the index (unless specified explicitly). The documentation just
> mentions the "diff family", but all but one of the possible values for
> submodule.<name>.ignore ("all") don't make sense unless comparing with
> the working tree. This is also how show/log -p behaved in git <2.15.
> So I think that clarifying that it is about modifications *to the
> working tree* would be a good idea.
>
> >> I'm also starting to see why this is tricky. The only difference that
> >> diff.c:run_diff_files sees between `git add inner` and `git add --all`
> >> is whether the index entry matched the pathspec exactly or not.
> >
> > Unrelated to the trickiness, I think we'd need to document the behavior
> > of the -a flag in git-add and git-commit better as adding the diff below
> > will depart from the "all" rule again, which I thought was a strong
> > motivator for Brandons series (IIRC).
>
> Can you explain what you mean by the "all" rule?

-a as short for --all in git commit, and I presumed it to be
'--all-content', but documentation tells me it's about files
only, so there is no really an "all" rule, but rather me misunderstanding
to what it applies.

^ permalink raw reply	[relevance 4%]

* Re: What's cooking in git.git (Nov 2018, #06; Wed, 21)
  2018-11-26 21:57  2% ` Stefan Beller
@ 2018-11-26 23:34  2%   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-11-26 23:34 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

>> * sb/submodule-recursive-fetch-gets-the-tip (2018-10-31) 11 commits
>> [...]
>>
>>  "git fetch --recurse-submodules" may not fetch the necessary commit
>>  that is bound to the superproject, which is getting corrected.
>>
>>  Is the discussion on this topic over?  What was the outcome?
>
> Please don't merge down the topic in the current state.

Thanks.  It won't happen until the final anyway ;-)

^ permalink raw reply	[relevance 2%]

* Re: What's cooking in git.git (Nov 2018, #06; Wed, 21)
  @ 2018-11-26 21:57  2% ` Stefan Beller
  2018-11-26 23:34  2%   ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-26 21:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

>
> * sb/submodule-recursive-fetch-gets-the-tip (2018-10-31) 11 commits
> [...]
>
>  "git fetch --recurse-submodules" may not fetch the necessary commit
>  that is bound to the superproject, which is getting corrected.
>
>  Is the discussion on this topic over?  What was the outcome?

Please don't merge down the topic in the current state.

I have a local updated version sitting on my disk and plan to send
it once I made sure it addressed all comments of various revisions.

^ permalink raw reply	[relevance 2%]

* Re: [PATCH] grep: use grep_opt->repo instead of explict repo argument
  @ 2018-11-26 19:52  7% ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-26 19:52 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

On Sun, Nov 18, 2018 at 8:38 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
>
> This command is probably the first one that operates on a repository
> other than the_repository, in f9ee2fcdfa (grep: recurse in-process
> using 'struct repository' - 2017-08-02). An explicit 'struct
> repository *' was added in that commit to pass around the repository
> that we're supposed to grep from.
>
> Since 38bbc2ea39 (grep.c: remove implicit dependency on the_index -
> 2018-09-21). 'struct grep_opt *' carries in itself a repository
> parameter for grepping. We should now be able to reuse grep_opt to
> hold the submodule repo instead of a separate argument, which is just
> room for mistakes.

That makes sense. Assuming we did not make a mistake yet, the
test suite would not need changes (further assuming we do test for it,
but we do as we have explicit submodule grep tests).

>
> While at there, use the right reference instead of the_repository and
> the_index in this code. I was a bit careless in my attempt to kick
> the_repository / the_index out of library code. It's normally safe to
> just stick the_repository / the_index in bultin/ code, but it's not
> the case for grep.

Reviewed-by: Stefan Beller <sbeller@google.com>

> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>

^ permalink raw reply	[relevance 7%]

* [ANNOUNCE] Git v2.20.0-rc1
@ 2018-11-21 15:20  2% Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-11-21 15:20 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

A release candidate Git v2.20.0-rc1 is now available for testing
at the usual places.  It is comprised of 915 non-merge commits
since v2.19.0, contributed by 73 people, 24 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.20.0-rc1' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.19.0 are as follows.
Welcome to the Git development community!

  Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan
  Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis, David
  Zych, Đoàn Trần Công Danh, Frederick Eaton, James Knight,
  Jann Horn, Joshua Watt, Loo Rong Jie, Lucas De Marchi, Matthew
  DeVore, Mihir Mehta, Nickolai Belakovski, Roger Strain, Sam
  McKelvie, Saulius Gurklys, Shulhan, Steven Fernandez, Strain,
  Roger L, and Tim Schumacher.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Alban Gruin, Andreas Gruenbacher,
  Andreas Heiduk, Antonio Ospite, Ben Peart, Brandon Williams,
  brian m. carlson, Christian Couder, Christian Hesse, Denton Liu,
  Derrick Stolee, Elijah Newren, Eric Sunshine, Jeff Hostetler,
  Jeff King, Johannes Schindelin, Johannes Sixt, Jonathan Nieder,
  Jonathan Tan, Josh Steadmon, Junio C Hamano, Karsten Blees,
  Luke Diamand, Martin Ågren, Max Kirillov, Michael Witten,
  Michał Górny, Nguyễn Thái Ngọc Duy, Noam Postavsky,
  Olga Telezhnaya, Phillip Wood, Pratik Karki, Rafael Ascensão,
  Ralf Thielow, Ramsay Jones, Rasmus Villemoes, René Scharfe,
  Sebastian Staudt, Stefan Beller, Stephen P. Smith, Steve Hoelzer,
  SZEDER Gábor, Tao Qingyun, Taylor Blau, Thomas Gummerer,
  Todd Zullinger, Torsten Bögershausen, and Uwe Kleine-König.

----------------------------------------------------------------

Git 2.20 Release Notes (draft)
==============================

Backward Compatibility Notes
----------------------------

 * "git branch -l <foo>" used to be a way to ask a reflog to be
   created while creating a new branch, but that is no longer the
   case.  It is a short-hand for "git branch --list <foo>" now.

 * "git push" into refs/tags/* hierarchy is rejected without getting
   forced, but "git fetch" (misguidedly) used the "fast forwarding"
   rule used for the refs/heads/* hierarchy; this has been corrected,
   which means some fetches of tags that did not fail with older
   version of Git will fail without "--force" with this version.

 * "git help -a" now gives verbose output (same as "git help -av").
   Those who want the old output may say "git help --no-verbose -a"..

 * "git cpn --help", when "cpn" is an alias to, say, "cherry-pick -n",
   reported only the alias expansion of "cpn" in earlier versions of
   Git.  It now runs "git cherry-pick --help" to show the manual page
   of the command, while sending the alias expansion to the standard
   error stream.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by". This is a backward-incompatible
   change.  Adding "--suppress-cc=misc-by" on the command line, or
   setting sendemail.suppresscc configuration variable to "misc-by",
   can be used to disable this behaviour.


Updates since v2.19
-------------------

UI, Workflows & Features

 * Running "git clone" against a project that contain two files with
   pathnames that differ only in cases on a case insensitive
   filesystem would result in one of the files lost because the
   underlying filesystem is incapable of holding both at the same
   time.  An attempt is made to detect such a case and warn.

 * "git checkout -b newbranch [HEAD]" should not have to do as much as
   checking out a commit different from HEAD.  An attempt is made to
   optimize this special case.

 * "git rev-list --stdin </dev/null" used to be an error; it now shows
   no output without an error.  "git rev-list --stdin --default HEAD"
   still falls back to the given default when nothing is given on the
   standard input.

 * Lift code from GitHub to restrict delta computation so that an
   object that exists in one fork is not made into a delta against
   another object that does not appear in the same forked repository.

 * "git format-patch" learned new "--interdiff" and "--range-diff"
   options to explain the difference between this version and the
   previous attempt in the cover letter (or after the three-dashes as
   a comment).

 * "git mailinfo" used in "git am" learned to make a best-effort
   recovery of a patch corrupted by MUA that sends text/plain with
   format=flawed option.
   (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).

 * The rules used by "git push" and "git fetch" to determine if a ref
   can or cannot be updated were inconsistent; specifically, fetching
   to update existing tags were allowed even though tags are supposed
   to be unmoving anchoring points.  "git fetch" was taught to forbid
   updates to existing tags without the "--force" option.

 * "git multi-pack-index" learned to detect corruption in the .midx
   file it uses, and this feature has been integrated into "git fsck".

 * Generation of (experimental) commit-graph files have so far been
   fairly silent, even though it takes noticeable amount of time in a
   meaningfully large repository.  The users will now see progress
   output.

 * The minimum version of Windows supported by Windows port of Git is
   now set to Vista.

 * The completion script (in contrib/) learned to complete a handful of
   options "git stash list" command takes.

 * The completion script (in contrib/) learned that "git fetch
   --multiple" only takes remote names as arguments and no refspecs.

 * "git status" learns to show progress bar when refreshing the index
   takes a long time.
   (merge ae9af12287 nd/status-refresh-progress later to maint).

 * "git help -a" and "git help -av" give different pieces of
   information, and generally the "verbose" version is more friendly
   to the new users.  "git help -a" by default now uses the more
   verbose output (with "--no-verbose", you can go back to the
   original).  Also "git help -av" now lists aliases and external
   commands, which it did not used to.

 * Unlike "grep", "git grep" by default recurses to the whole tree.
   The command learned "git grep --recursive" option, so that "git
   grep --no-recursive" can serve as a synonym to setting the
   max-depth to 0.

 * When pushing into a repository that borrows its objects from an
   alternate object store, "git receive-pack" that responds to the
   push request on the other side lists the tips of refs in the
   alternate to reduce the amount of objects transferred.  This
   sometimes is detrimental when the number of refs in the alternate
   is absurdly large, in which case the bandwidth saved in potentially
   fewer objects transferred is wasted in excessively large ref
   advertisement.  The alternate refs that are advertised are now
   configurable with a pair of configuration variables.

 * "git cmd --help" when "cmd" is aliased used to only say "cmd is
   aliased to ...".  Now it shows that to the standard error stream
   and runs "git $cmd --help" where $cmd is the first word of the
   alias expansion.

 * The documentation of "git gc" has been updated to mention that it
   is no longer limited to "pruning away crufts" but also updates
   ancillary files like commit-graph as a part of repository
   optimization.

 * "git p4 unshelve" improvements.

 * The logic to select the default user name and e-mail on Windows has
   been improved.
   (merge 501afcb8b0 js/mingw-default-ident later to maint).

 * The "rev-list --filter" feature learned to exclude all trees via
   "tree:0" filter.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by"; --suppress-cc=misc-by on the
   command line, or setting sendemail.suppresscc configuration
   variable to "misc-by", can be used to disable this behaviour.

 * Developer builds now uses -Wunused-function compilation option.

 * One of our CI tests to run with "unusual/experimental/random"
   settings now also uses commit-graph and midx.

 * "git mergetool" learned to take the "--[no-]gui" option, just like
   "git difftool" does.

 * "git rebase -i" learned a new insn, 'break', that the user can
   insert in the to-do list.  Upon hitting it, the command returns
   control back to the user.

 * New "--pretty=format:" placeholders %GF and %GP that show the GPG
   key fingerprints have been invented.

 * On platforms with recent cURL library, http.sslBackend configuration
   variable can be used to choose a different SSL backend at runtime.
   The Windows port uses this mechanism to switch between OpenSSL and
   Secure Channel while talking over the HTTPS protocol.

 * "git send-email" learned to disable SMTP authentication via the
   "--smtp-auth=none" option, even when the smtp username is given
   (which turns the authentication on by default).

 * A fourth class of configuration files (in addition to the
   traditional "system wide", "per user in the $HOME directory" and
   "per repository in the $GIT_DIR/config") has been introduced so
   that different worktrees that share the same repository (hence the
   same $GIT_DIR/config file) can use different customization.

 * A pattern with '**' that does not have a slash on either side used
   to be an invalid one, but the code now treats such double-asterisks
   the same way as two normal asterisks that happen to be adjacent to
   each other.
   (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).

 * The "--no-patch" option, which can be used to get a high-level
   overview without the actual line-by-line patch difference shown, of
   the "range-diff" command was earlier broken, which has been
   corrected.

 * The recently merged "rebase in C" has an escape hatch to use the
   scripted version when necessary, but it hasn't been documented,
   which has been corrected.


Performance, Internal Implementation, Development Support etc.

 * When there are too many packfiles in a repository (which is not
   recommended), looking up an object in these would require
   consulting many pack .idx files; a new mechanism to have a single
   file that consolidates all of these .idx files is introduced.

 * "git submodule update" is getting rewritten piece-by-piece into C.

 * The code for computing history reachability has been shuffled,
   obtained a bunch of new tests to cover them, and then being
   improved.

 * The unpack_trees() API used in checking out a branch and merging
   walks one or more trees along with the index.  When the cache-tree
   in the index tells us that we are walking a tree whose flattened
   contents is known (i.e. matches a span in the index), as linearly
   scanning a span in the index is much more efficient than having to
   open tree objects recursively and listing their entries, the walk
   can be optimized, which has been done.

 * When creating a thin pack, which allows objects to be made into a
   delta against another object that is not in the resulting pack but
   is known to be present on the receiving end, the code learned to
   take advantage of the reachability bitmap; this allows the server
   to send a delta against a base beyond the "boundary" commit.

 * spatch transformation to replace boolean uses of !hashcmp() to
   newly introduced oideq() is added, and applied, to regain
   performance lost due to support of multiple hash algorithms.

 * Fix a bug in which the same path could be registered under multiple
   worktree entries if the path was missing (for instance, was removed
   manually).  Also, as a convenience, expand the number of cases in
   which --force is applicable.

 * Split Documentation/config.txt for easier maintenance.
   (merge 6014363f0b nd/config-split later to maint).

 * Test helper binaries clean-up.
   (merge c9a1f4161f nd/test-tool later to maint).

 * Various tests have been updated to make it easier to swap the
   hash function used for object identification.
   (merge ae0c89d41b bc/hash-independent-tests later to maint).

 * Update fsck.skipList implementation and documentation.
   (merge 371a655074 ab/fsck-skiplist later to maint).

 * An alias that expands to another alias has so far been forbidden,
   but now it is allowed to create such an alias.

 * Various test scripts have been updated for style and also correct
   handling of exit status of various commands.

 * "gc --auto" ended up calling exit(-1) upon error, which has been
   corrected to use exit(1).  Also the error reporting behaviour when
   daemonized has been updated to exit with zero status when stopping
   due to a previously discovered error (which implies there is no
   point running gc to improve the situation); we used to exit with
   failure in such a case.

 * Various codepaths in the core-ish part learned to work on an
   arbitrary in-core index structure, not necessarily the default
   instance "the_index".
   (merge b3c7eef9b0 nd/the-index later to maint).

 * Code clean-up in the internal machinery used by "git status" and
   "git commit --dry-run".
   (merge 73ba5d78b4 ss/wt-status-committable later to maint).

 * Some environment variables that control the runtime options of Git
   used during tests are getting renamed for consistency.
   (merge 4231d1ba99 bp/rename-test-env-var later to maint).

 * A pair of new extensions to the index file have been introduced.
   They allow the index file to be read in parallel for performance.

 * The oidset API was built on top of the oidmap API which in turn is
   on the hashmap API.  Replace the implementation to build on top of
   the khash API and gain performance.

 * Over some transports, fetching objects with an exact commit object
   name can be done without first seeing the ref advertisements.  The
   code has been optimized to exploit this.

 * In a partial clone that will lazily be hydrated from the
   originating repository, we generally want to avoid "does this
   object exist (locally)?" on objects that we deliberately omitted
   when we created the clone.  The cache-tree codepath (which is used
   to write a tree object out of the index) however insisted that the
   object exists, even for paths that are outside of the partial
   checkout area.  The code has been updated to avoid such a check.

 * To help developers, an EditorConfig file that attempts to follow
   the project convention has been added.
   (merge b548d698a0 bc/editorconfig later to maint).

 * The result of coverage test can be combined with "git blame" to
   check the test coverage of code introduced recently with a new
   'coverage-diff' tool (in contrib/).
   (merge 783faedd65 ds/coverage-diff later to maint).

 * An experiment to fuzz test a few areas, hopefully we can gain more
   coverage to various areas.

 * More codepaths are moving away from hardcoded hash sizes.

 * The way the Windows port figures out the current directory has been
   improved.

 * The way DLLs are loaded on the Windows port has been improved.

 * Some tests have been reorganized and renamed; "ls t/" now gives a
   better overview of what is tested for these scripts than before.

 * "git rebase" and "git rebase -i" have been reimplemented in C.

 * Windows port learned to use nano-second resolution file timestamps.

 * The overly large Documentation/config.txt file have been split into
   million little pieces.  This potentially allows each individual piece
   included into the manual page of the command it affects more easily.

 * Replace three string-list instances used as look-up tables in "git
   fetch" with hashmaps.

 * Unify code to read the author-script used in "git am" and the
   commands that use the sequencer machinery, e.g. "git rebase -i".

 * In preparation to the day when we can deprecate and remove the
   "rebase -p", make sure we can skip and later remove tests for
   it.

 * The history traversal used to implement the tag-following has been
   optimized by introducing a new helper.

 * The helper function to refresh the cached stat information in the
   in-core index has learned to perform the lstat() part of the
   operation in parallel on multi-core platforms.

 * The code to traverse objects for reachability, used to decide what
   objects are unreferenced and expendable, have been taught to also
   consider per-worktree refs of other worktrees as starting points to
   prevent data loss.

 * "git add" needs to internally run "diff-files" equivalent, and the
   codepath learned the same optimization as "diff-files" has to run
   lstat(2) in parallel to find which paths have been updated in the
   working tree.

 * The procedure to install dependencies before testing at Travis CI
   is getting revamped for both simplicity and flexibility, taking
   advantage of the recent move to the vm-based environment.

 * The support for format-patch (and send-email) by the command-line
   completion script (in contrib/) has been simplified a bit.

 * The revision walker machinery learned to take advantage of the
   commit generation numbers stored in the commit-graph file.

 * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".

 * The way -lcurl library gets linked has been simplified by taking
   advantage of the fact that we can just ask curl-config command how.

 * Various functions have been audited for "-Wunused-parameter" warnings
   and bugs in them got fixed.

 * A sanity check for start-up sequence has been added in the config
   API codepath.

 * The build procedure to link for fuzzing test has been made
   customizable with a new Makefile variable.

 * The way "git rebase" parses and forwards the command line options
   meant for underlying "git am" has been revamped, which fixed for
   options with parameters that were not passed correctly.

 * Our testing framework uses a special i18n "poisoned localization"
   feature to find messages that ought to stay constant but are
   incorrectly marked to be translated.  This feature has been made
   into a runtime option (it used to be a compile-time option).

 * "git push" used to check ambiguities between object-names and
   refnames while processing the list of refs' old and new values,
   which was unnecessary (as it knew that it is feeding raw object
   names).  This has been optimized out.

 * The xcurl_off_t() helper function is used to cast size_t to
   curl_off_t, but some compilers gave warnings against the code to
   ensure the casting is done without wraparound, when size_t is
   narrower than curl_off_t.  This warning has been squelched.

 * Code preparation to replace ulong vars with size_t vars where
   appropriate continues.

 * The "test installed Git" mode of our test suite has been updated to
   work better.

 * A coding convention around the Coccinelle semantic patches to have
   two classes to ease code migration process has been proposed and
   its support has been added to the Makefile.


Fixes since v2.19
-----------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.
   (merge 66e83d9b41 jk/trailer-fixes later to maint).

 * Malformed or crafted data in packstream can make our code attempt
   to read or write past the allocated buffer and abort, instead of
   reporting an error, which has been fixed.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.
   (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.
   (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.
   (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).

 * Further fix for O_APPEND emulation on Windows
   (merge eeaf7ddac7 js/mingw-o-append later to maint).

 * A corner case bugfix in "git rerere" code.
   (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.
   (merge 84d938b732 nd/attr-pathspec-fix later to maint).

 * Recent update broke the reachability algorithm when refs (e.g.
   tags) that point at objects that are not commit were involved,
   which has been fixed.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.
   (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.
   (merge e68302011c jt/lazy-object-fetch-fix later to maint).

 * Update error messages given by "git remote" and make them consistent.
   (merge 5025425dff ms/remote-error-message-update later to maint).

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.
   (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.
   (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.
   (merge 829a321569 ds/commit-graph-with-grafts later to maint).

 * The mailmap file update.
   (merge 255eb03edf jn/mailmap-update later to maint).

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.
   (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).

 * "git fetch $repo $object" in a partial clone did not correctly
   fetch the asked-for object that is referenced by an object in
   promisor packfile, which has been fixed.

 * A corner-case bugfix.
   (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).

 * Various fixes to "diff --color-moved-ws".

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.
   (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.
   (merge 4c490f3d32 sg/split-index-racefix later to maint).

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.
   (merge 04005834ed np/log-graph-octopus-fix later to maint).

 * "git range-diff" did not work well when the compared ranges had
   changes in submodules and the "--submodule=log" was used.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.
   (merge f67b980771 jk/run-command-notdot later to maint).

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.
   (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.
   (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.
   (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).

 * The logic to determine the archive type "git archive" uses did not
   correctly kick in for "git archive --remote", which has been
   corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.
   (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).

 * Some codepaths failed to form a proper URL when .gitmodules record
   the URL to a submodule repository as relative to the repository of
   superproject, which has been corrected.
   (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).

 * "git fetch" over protocol v2 into a shallow repository failed to
   fetch full history behind a new tip of history that was diverged
   before the cut-off point of the history that was previously fetched
   shallowly.

 * The command line completion machinery (in contrib/) has been
   updated to allow the completion script to tweak the list of options
   that are reported by the parse-options machinery correctly.
   (merge 276b49ff34 nd/completion-negation later to maint).

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.
   (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.
   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.
   (merge a5f52c6dab sg/test-verbose-log later to maint).

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.
   (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).

 * "git ls-remote $there foo" was broken by recent update for the
   protocol v2 and stopped showing refs that match 'foo' that are not
   refs/{heads,tags}/foo, which has been fixed.
   (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).

 * Additional comment on a tricky piece of code to help developers.
   (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).

 * A couple of tests used to leave the repository in a state that is
   deliberately corrupt, which have been corrected.
   (merge aa984dbe5e ab/pack-tests-cleanup later to maint).

 * The submodule support has been updated to read from the blob at
   HEAD:.gitmodules when the .gitmodules file is missing from the
   working tree.
   (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).

 * "git fetch" was a bit loose in parsing responses from the other side
   when talking over the protocol v2.

 * "git rev-parse --exclude=* --branches --branches"  (i.e. first
   saying "add only things that do not match '*' out of all branches"
   and then adding all branches, without any exclusion this time")
   worked as expected, but "--exclude=* --all --all" did not work the
   same way, which has been fixed.
   (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).

 * "git send-email --transfer-encoding=..." in recent versions of Git
   sometimes produced an empty "Content-Transfer-Encoding:" header,
   which has been corrected.
   (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).

 * The interface into "xdiff" library used to discover the offset and
   size of a generated patch hunk by first formatting it into the
   textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
   out.  A new interface has been introduced to allow callers a more
   direct access to them.
   (merge 5eade0746e jk/xdiff-interface later to maint).

 * Pathspec matching against a tree object were buggy when negative
   pathspec elements were involved, which has been fixed.
   (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).

 * "git merge" and "git pull" that merges into an unborn branch used
   to completely ignore "--verify-signatures", which has been
   corrected.
   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).

 * "git rebase --autostash" did not correctly re-attach the HEAD at times.

 * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
   quite work, which has been corrected.
   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).

 * When editing a patch in a "git add -i" session, a hunk could be
   made to no-op.  The "git apply" program used to reject a patch with
   such a no-op hunk to catch user mistakes, but it is now updated to
   explicitly allow a no-op hunk in an edited patch.
   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).

 * The URL to an MSDN page in a comment has been updated.
   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).

 * "git ls-remote --sort=<thing>" can feed an object that is not yet
   available into the comparison machinery and segfault, which has
   been corrected to check such a request upfront and reject it.

 * When "git bundle" aborts due to an empty commit ranges
   (i.e. resulting in an empty pack), it left a file descriptor to an
   lockfile open, which resulted in leftover lockfile on Windows where
   you cannot remove a file with an open file descriptor.  This has
   been corrected.
   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).

 * "git format-patch --stat=<width>" can be used to specify the width
   used by the diffstat (shown in the cover letter).
   (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).

 * The way .git/index and .git/sharedindex* files were initially
   created gave these files different perm bits until they were
   adjusted for shared repository settings.  This was made consistent.
   (merge c9d6c78870 cc/shared-index-permbits later to maint).

 * Code cleanup, docfix, build fix, etc.
   (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
   (merge b9b07efdb2 tg/conflict-marker-size later to maint).
   (merge fa0aeea770 sg/doc-trace-appends later to maint).
   (merge d64324cb60 tb/void-check-attr later to maint).
   (merge c3b9bc94b9 en/double-semicolon-fix later to maint).
   (merge 79336116f5 sg/t3701-tighten-trace later to maint).
   (merge 801fa63a90 jk/dev-build-format-security later to maint).
   (merge 0597dd62ba sb/string-list-remove-unused later to maint).
   (merge db2d36fad8 bw/protocol-v2 later to maint).
   (merge 456d7cd3a9 sg/split-index-test later to maint).
   (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).
   (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).
   (merge 55f6bce2c9 fe/doc-updates later to maint).
   (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).
   (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).
   (merge 4c399442f7 ma/commit-graph-docs later to maint).
   (merge fc0503b04e ma/t1400-undebug-test later to maint).
   (merge e56b53553a nd/packobjectshook-doc-fix later to maint).
   (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).
   (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).
   (merge ad0b8f9575 mw/doc-typofixes later to maint).
   (merge d9f079ad1a jc/how-to-document-api later to maint).
   (merge b1492bf315 ma/t7005-bash-workaround later to maint).
   (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).
   (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).
   (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).
   (merge 61018fe9e0 du/cherry-is-plumbing later to maint).
   (merge c7e5fe79b9 sb/strbuf-h-update later to maint).
   (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).
   (merge 2e3c894f4b tq/branch-style-fix later to maint).
   (merge c5d844af9c sg/doc-show-branch-typofix later to maint).
   (merge 081d91618b ah/doc-updates later to maint).
   (merge b84c783882 jc/cocci-preincr later to maint).
   (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).
   (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).
   (merge 3063477445 tb/char-may-be-unsigned later to maint).
   (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
   (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).

----------------------------------------------------------------

Changes since v2.19.0 are as follows:

Aaron Lindsay (1):
      send-email: avoid empty transfer encoding header

Alban Gruin (21):
      sequencer: make three functions and an enum from sequencer.c public
      rebase -i: rewrite append_todo_help() in C
      editor: add a function to launch the sequence editor
      rebase -i: rewrite the edit-todo functionality in C
      sequencer: add a new function to silence a command, except if it fails
      rebase -i: rewrite setup_reflog_action() in C
      rebase -i: rewrite checkout_onto() in C
      sequencer: refactor append_todo_help() to write its message to a buffer
      sequencer: change the way skip_unnecessary_picks() returns its result
      t3404: todo list with commented-out commands only aborts
      rebase -i: rewrite complete_action() in C
      rebase -i: remove unused modes and functions
      rebase -i: implement the logic to initialize $revisions in C
      rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C
      rebase -i: rewrite write_basic_state() in C
      rebase -i: rewrite init_basic_state() in C
      rebase -i: implement the main part of interactive rebase as a builtin
      rebase--interactive2: rewrite the submodes of interactive rebase in C
      rebase -i: remove git-rebase--interactive.sh
      rebase -i: move rebase--helper modes to rebase--interactive
      p3400: replace calls to `git checkout -b' by `git checkout -B'

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Andreas Gruenbacher (1):
      rev-parse: clear --exclude list after 'git rev-parse --all'

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Anton Serbulov (1):
      mingw: fix getcwd when the parent directory cannot be queried

Antonio Ospite (10):
      submodule: add a print_config_from_gitmodules() helper
      submodule: factor out a config_set_in_gitmodules_file_gently function
      t7411: merge tests 5 and 6
      t7411: be nicer to future tests and really clean things up
      submodule--helper: add a new 'config' subcommand
      submodule: use the 'submodule--helper config' command
      t7506: clean up .gitmodules properly before setting up new scenario
      submodule: add a helper to check if it is safe to write to .gitmodules
      submodule: support reading .gitmodules when it's not in the working tree
      t/helper: add test-submodule-nested-repo-config

Ben Peart (19):
      checkout: optimize "git checkout -b <new_branch>"
      git-mv: allow submodules and fsmonitor to work together
      t/README: correct spelling of "uncommon"
      preload-index: use git_env_bool() not getenv() for customization
      fsmonitor: update GIT_TEST_FSMONITOR support
      read-cache: update TEST_GIT_INDEX_VERSION support
      preload-index: update GIT_FORCE_PRELOAD_TEST support
      read-cache: clean up casting and byte decoding
      eoie: add End of Index Entry (EOIE) extension
      config: add new index.threads config setting
      read-cache: load cache extensions on a worker thread
      ieot: add Index Entry Offset Table (IEOT) extension
      read-cache: load cache entries on worker threads
      reset: don't compute unstaged changes after reset when --quiet
      reset: add new reset.quiet config setting
      reset: warn when refresh_index() takes more than 2 seconds
      speed up refresh_index() by utilizing preload_index()
      add: speed up cmd_add() by utilizing read_cache_preload()
      refresh_index: remove unnecessary calls to preload_index()

Brandon Williams (1):
      config: document value 2 for protocol.version

Brendan Forster (1):
      http: add support for disabling SSL revocation checks in cURL

Carlo Marcelo Arenas Belón (8):
      unpack-trees: avoid dead store for struct progress
      multi-pack-index: avoid dead store for struct progress
      read-cache: use of memory after it is freed
      commit-slabs: move MAYBE_UNUSED out
      khash: silence -Wunused-function for delta-islands
      compat: make sure git_mmap is not expected to write
      sequencer: cleanup for gcc warning in non developer mode
      builtin/notes: remove unnecessary free

Christian Couder (3):
      pack-objects: refactor code into compute_layer_order()
      pack-objects: move tree_depth into 'struct packing_data'
      pack-objects: move 'layer' into 'struct packing_data'

Christian Hesse (2):
      subtree: add build targets 'man' and 'html'
      subtree: make install targets depend on build targets

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Denton Liu (3):
      mergetool: accept -g/--[no-]gui as arguments
      completion: support `git mergetool --[no-]gui`
      doc: document diff/merge.guitool config keys

Derrick Stolee (93):
      multi-pack-index: add design document
      multi-pack-index: add format details
      multi-pack-index: add builtin
      multi-pack-index: add 'write' verb
      midx: write header information to lockfile
      multi-pack-index: load into memory
      t5319: expand test data
      packfile: generalize pack directory list
      multi-pack-index: read packfile list
      multi-pack-index: write pack names in chunk
      midx: read pack names into array
      midx: sort and deduplicate objects from packfiles
      midx: write object ids in a chunk
      midx: write object id fanout chunk
      midx: write object offsets
      config: create core.multiPackIndex setting
      midx: read objects from multi-pack-index
      midx: use midx in abbreviation calculations
      midx: use existing midx when writing new one
      midx: use midx in approximate_object_count
      midx: prevent duplicate packfile loads
      packfile: skip loading index if in multi-pack-index
      midx: clear midx on repack
      commit-reach: move walk methods from commit.c
      commit.h: remove method declarations
      commit-reach: move ref_newer from remote.c
      commit-reach: move commit_contains from ref-filter
      upload-pack: make reachable() more generic
      upload-pack: refactor ok_to_give_up()
      upload-pack: generalize commit date cutoff
      commit-reach: move can_all_from_reach_with_flags
      test-reach: create new test tool for ref_newer
      test-reach: test in_merge_bases
      test-reach: test is_descendant_of
      test-reach: test get_merge_bases_many
      test-reach: test reduce_heads
      test-reach: test can_all_from_reach_with_flags
      test-reach: test commit_contains
      commit-reach: replace ref_newer logic
      commit-reach: make can_all_from_reach... linear
      commit-reach: use can_all_from_reach
      multi-pack-index: provide more helpful usage info
      multi-pack-index: store local property
      midx: mark bad packed objects
      midx: stop reporting garbage
      midx: fix bug that skips midx with alternates
      packfile: add all_packs list
      treewide: use get_all_packs
      midx: test a few commands that use get_all_packs
      pack-objects: consider packs in multi-pack-index
      commit-graph: update design document
      test-repository: properly init repo
      commit-graph: not compatible with replace objects
      commit-graph: not compatible with grafts
      commit-graph: not compatible with uninitialized repo
      commit-graph: close_commit_graph before shallow walk
      commit-graph: define GIT_TEST_COMMIT_GRAPH
      t3206-range-diff.sh: cover single-patch case
      t5318: use test_oid for HASH_LEN
      multi-pack-index: add 'verify' verb
      multi-pack-index: verify bad header
      multi-pack-index: verify corrupt chunk lookup table
      multi-pack-index: verify packname order
      multi-pack-index: verify missing pack
      multi-pack-index: verify oid fanout order
      multi-pack-index: verify oid lookup order
      multi-pack-index: fix 32-bit vs 64-bit size check
      multi-pack-index: verify object offsets
      multi-pack-index: report progress during 'verify'
      fsck: verify multi-pack-index
      commit-reach: properly peel tags
      commit-reach: fix memory and flag leaks
      commit-reach: cleanups in can_all_from_reach...
      commit-graph: clean up leaked memory during write
      commit-graph: reduce initial oid allocation
      midx: fix broken free() in close_midx()
      contrib: add coverage-diff script
      ci: add optional test variables
      commit-reach: fix first-parent heuristic
      midx: close multi-pack-index on repack
      multi-pack-index: define GIT_TEST_MULTI_PACK_INDEX
      packfile: close multi-pack-index in close_all_packs
      prio-queue: add 'peek' operation
      test-reach: add run_three_modes method
      test-reach: add rev-list tests
      revision.c: begin refactoring --topo-order logic
      commit/revisions: bookkeeping before refactoring
      revision.c: generation-based topo-order algorithm
      t6012: make rev-list tests more interesting
      commit-reach: implement get_reachable_subset
      test-reach: test get_reachable_subset
      remote: make add_missing_tags() linear
      pack-objects: ignore ambiguous object warnings

Elijah Newren (14):
      Remove superfluous trailing semicolons
      t4200: demonstrate rerere segfault on specially crafted merge
      rerere: avoid buffer overrun
      update-ref: fix type of update_flags variable to match its usage
      update-ref: allow --no-deref with --stdin
      sequencer: fix --allow-empty-message behavior, make it smarter
      merge-recursive: set paths correctly when three-way merging content
      merge-recursive: avoid wrapper function when unnecessary and wasteful
      merge-recursive: remove final remaining caller of merge_file_one()
      merge-recursive: rename merge_file_1() and merge_content()
      commit: fix erroneous BUG, 'multiple renames on the same target? how?'
      merge-recursive: improve auto-merging messages with path collisions
      merge-recursive: avoid showing conflicts with merge branch before HEAD
      fsck: move fsck_head_link() to get_default_heads() to avoid some globals

Eric Sunshine (26):
      format-patch: allow additional generated content in make_cover_letter()
      format-patch: add --interdiff option to embed diff in cover letter
      format-patch: teach --interdiff to respect -v/--reroll-count
      interdiff: teach show_interdiff() to indent interdiff
      log-tree: show_log: make commentary block delimiting reusable
      format-patch: allow --interdiff to apply to a lone-patch
      range-diff: respect diff_option.file rather than assuming 'stdout'
      range-diff: publish default creation factor
      range-diff: relieve callers of low-level configuration burden
      format-patch: add --range-diff option to embed diff in cover letter
      format-patch: extend --range-diff to accept revision range
      format-patch: teach --range-diff to respect -v/--reroll-count
      format-patch: add --creation-factor tweak for --range-diff
      format-patch: allow --range-diff to apply to a lone-patch
      worktree: don't die() in library function find_worktree()
      worktree: move delete_git_dir() earlier in file for upcoming new callers
      worktree: generalize delete_git_dir() to reduce code duplication
      worktree: prepare for more checks of whether path can become worktree
      worktree: disallow adding same path multiple times
      worktree: teach 'add' to respect --force for registered but missing path
      worktree: teach 'move' to override lock when --force given twice
      worktree: teach 'remove' to override lock when --force given twice
      worktree: delete .git/worktrees if empty after 'remove'
      doc-diff: fix non-portable 'man' invocation
      doc-diff: add --clean mode to remove temporary working gunk
      doc/Makefile: drop doc-diff worktree and temporary files on "make clean"

Frederick Eaton (3):
      git-archimport.1: specify what kind of Arch we're talking about
      git-column.1: clarify initial description, provide examples
      git-describe.1: clarify that "human readable" is also git-readable

James Knight (1):
      build: link with curl-defined linker flags

Jann Horn (2):
      patch-delta: fix oob read
      patch-delta: consistently report corruption

Jeff Hostetler (2):
      t0051: test GIT_TRACE to a windows named pipe
      mingw: fix mingw_open_append to work with named pipes

Jeff King (97):
      branch: make "-l" a synonym for "--list"
      Add delta-islands.{c,h}
      pack-objects: add delta-islands support
      repack: add delta-islands support
      t5320: tests for delta islands
      t/perf: factor boilerplate out of test_perf
      t/perf: factor out percent calculations
      t/perf: add infrastructure for measuring sizes
      t/perf: add perf tests for fetches from a bitmapped server
      pack-bitmap: save "have" bitmap from walk
      pack-objects: reuse on-disk deltas for thin "have" objects
      SubmittingPatches: mention doc-diff
      rev-list: make empty --stdin not an error
      trailer: use size_t for string offsets
      trailer: use size_t for iterating trailer list
      trailer: pass process_trailer_opts to trailer_info_get()
      interpret-trailers: tighten check for "---" patch boundary
      interpret-trailers: allow suppressing "---" divider
      pretty, ref-filter: format %(trailers) with no_divider option
      sequencer: ignore "---" divider when parsing trailers
      append_signoff: use size_t for string offsets
      coccinelle: use <...> for function exclusion
      introduce hasheq() and oideq()
      convert "oidcmp() == 0" to oideq()
      convert "hashcmp() == 0" to hasheq()
      convert "oidcmp() != 0" to "!oideq()"
      convert "hashcmp() != 0" to "!hasheq()"
      convert hashmap comparison functions to oideq()
      read-cache: use oideq() in ce_compare functions
      show_dirstat: simplify same-content check
      doc-diff: always use oids inside worktree
      test-delta: read input into a heap buffer
      t5303: test some corrupt deltas
      patch-delta: handle truncated copy parameters
      t5303: use printf to generate delta bases
      doc/git-branch: remove obsolete "-l" references
      bitmap_has_sha1_in_uninteresting(): drop BUG check
      t5310: test delta reuse with bitmaps
      traverse_bitmap_commit_list(): don't free result
      pack-bitmap: drop "loaded" flag
      reopen_tempfile(): truncate opened file
      doc-diff: force worktree add
      config.mak.dev: add -Wformat-security
      pack-objects: handle island check for "external" delta base
      receive-pack: update comment with check_everything_connected
      submodule--helper: use "--" to signal end of clone options
      submodule-config: ban submodule urls that start with dash
      submodule-config: ban submodule paths that start with a dash
      fsck: detect submodule urls starting with dash
      fsck: detect submodule paths starting with dash
      more oideq/hasheq conversions
      transport: drop refnames from for_each_alternate_ref
      test-tool: show tool list on error
      config.mak.dev: enable -Wunused-function
      run-command: mark path lookup errors with ENOENT
      t5410: use longer path for sample script
      upload-pack: fix broken if/else chain in config callback
      t1450: check large blob in trailing-garbage test
      check_stream_sha1(): handle input underflow
      cat-file: handle streaming failures consistently
      ls-remote: do not send ref prefixes for patterns
      ls-remote: pass heads/tags prefixes to transport
      read_istream_pack_non_delta(): document input handling
      xdiff: provide a separate emit callback for hunks
      xdiff-interface: provide a separate consume callback for hunks
      rev-list: handle flags for --indexed-objects
      approxidate: handle pending number for "specials"
      pathspec: handle non-terminated strings with :(attr)
      diff: avoid generating unused hunk header lines
      diff: discard hunk headers for patch-ids earlier
      diff: use hunk callback for word-diff
      combine-diff: use an xdiff hunk callback
      diff: convert --check to use a hunk callback
      range-diff: use a hunk callback
      xdiff-interface: drop parse_hunk_header()
      apply: mark include/exclude options as NONEG
      am: handle --no-patch-format option
      ls-files: mark exclude options as NONEG
      pack-objects: mark index-version option as NONEG
      cat-file: mark batch options with NONEG
      status: mark --find-renames option with NONEG
      format-patch: mark "--no-numbered" option with NONEG
      show-branch: mark --reflog option as NONEG
      tag: mark "--message" option with NONEG
      cat-file: report an error on multiple --batch options
      apply: return -1 from option callback instead of calling exit(1)
      parse-options: drop OPT_DATE()
      assert NOARG/NONEG behavior of parse-options callbacks
      midx: double-check large object write loop
      merge: extract verify_merge_signature() helper
      merge: handle --verify-signatures for unborn branch
      pull: handle --verify-signatures for unborn branch
      approxidate: fix NULL dereference in date_time()
      bundle: dup() output descriptor closer to point-of-use
      pack-objects: fix tree_depth and layer invariants
      pack-objects: zero-initialize tree_depth/layer arrays
      pack-objects: fix off-by-one in delta-island tree-depth computation

Johannes Schindelin (62):
      rebase -i --autosquash: demonstrate a problem skipping the last squash
      rebase -i: be careful to wrap up fixup/squash chains
      compat/poll: prepare for targeting Windows Vista
      mingw: set _WIN32_WINNT explicitly for Git for Windows
      mingw: bump the minimum Windows version to Vista
      builtin rebase: prepare for builtin rebase -i
      rebase -i: clarify what happens on a failed `exec`
      rebase -i: introduce the 'break' command
      getpwuid(mingw): initialize the structure only once
      getpwuid(mingw): provide a better default for the user name
      mingw: use domain information for default email
      http: add support for selecting SSL backends at runtime
      pack-objects: fix typo 'detla' -> 'delta'
      pack-objects (mingw): demonstrate a segmentation fault with large deltas
      pack-objects (mingw): initialize `packing_data` mutex in the correct spot
      rebase (autostash): avoid duplicate call to state_dir_path()
      rebase (autostash): store the full OID in <state-dir>/autostash
      rebase (autostash): use an explicit OID to apply the stash
      mingw: factor out code to set stat() data
      rebase --autostash: demonstrate a problem with dirty submodules
      rebase --autostash: fix issue with dirty submodules
      mingw: load system libraries the recommended way
      mingw: ensure `getcwd()` reports the correct case
      repack: point out a bug handling stale shallow info
      shallow: offer to prune only non-existing entries
      repack -ad: prune the list of shallow commits
      http: when using Secure Channel, ignore sslCAInfo by default
      t7800: fix quoting
      mingw: reencode environment variables on the fly (UTF-16 <-> UTF-8)
      config: rename `dummy` parameter to `cb` in git_default_config()
      config: allow for platform-specific core.* config settings
      config: move Windows-specific config settings into compat/mingw.c
      mingw: unset PERL5LIB by default
      mingw: fix isatty() after dup2()
      t3404: decouple some test cases from outcomes of previous test cases
      t3418: decouple test cases from a previous `rebase -p` test case
      tests: optionally skip `git rebase -p` tests
      Windows: force-recompile git.res for differing architectures
      built-in rebase: demonstrate regression with --autostash
      built-in rebase --autostash: leave the current branch alone if possible
      Update .mailmap
      rebase -r: demonstrate bug with conflicting merges
      rebase -r: do not write MERGE_HEAD unless needed
      rebase -i: include MERGE_HEAD into files to clean up
      built-in rebase --skip/--abort: clean up stale .git/<name> files
      status: rebase and merge can be in progress at the same time
      apply --recount: allow "no-op hunks"
      rebase: consolidate clean-up code before leaving reset_head()
      rebase: prepare reset_head() for more flags
      built-in rebase: reinstate `checkout -q` behavior where appropriate
      tests: fix GIT_TEST_INSTALLED's PATH to include t/helper/
      tests: respect GIT_TEST_INSTALLED when initializing repositories
      t/lib-gettext: test installed git-sh-i18n if GIT_TEST_INSTALLED is set
      mingw: use `CreateHardLink()` directly
      rebase: really just passthru the `git am` options
      rebase: validate -C<n> and --whitespace=<mode> parameters early
      config: report a bug if git_dir exists without commondir
      tests: do not require Git to be built when testing an installed Git
      tests: explicitly use `git.exe` on Windows
      mingw: replace an obsolete link with the superseding one
      legacy-rebase: backport -C<n> and --whitespace=<option> checks
      rebase: warn about the correct tree's OID

Johannes Sixt (3):
      diff: don't attempt to strip prefix from absolute Windows paths
      rebase -i: recognize short commands without arguments
      t3404-rebase-interactive: test abbreviated commands

Jonathan Nieder (9):
      gc: improve handling of errors reading gc.log
      gc: exit with status 128 on failure
      gc: do not return error for prior errors in daemonized mode
      commit-reach: correct accidental #include of C file
      mailmap: consistently normalize brian m. carlson's name
      git doc: direct bug reporters to mailing list archive
      eoie: default to not writing EOIE section
      ieot: default to not writing IEOT section
      index: make index.threads=true enable ieot and eoie

Jonathan Tan (15):
      fetch-object: unify fetch_object[s] functions
      fetch-object: set exact_oid when fetching
      connected: document connectivity in partial clones
      fetch: in partial clone, check presence of targets
      fetch-pack: avoid object flags if no_dependents
      fetch-pack: exclude blobs when lazy-fetching trees
      transport: allow skipping of ref listing
      transport: do not list refs if possible
      transport: list refs before fetch if necessary
      fetch: do not list refs if fetching only hashes
      cache-tree: skip some blob checks in partial clone
      upload-pack: make have_obj not global
      upload-pack: make want_obj not global
      upload-pack: clear flags before each v2 request
      fetch-pack: be more precise in parsing v2 response

Josh Steadmon (4):
      fuzz: add basic fuzz testing target.
      fuzz: add fuzz testing for packfile indices.
      archive: initialize archivers earlier
      Makefile: use FUZZ_CXXFLAGS for linking fuzzers

Joshua Watt (1):
      send-email: explicitly disable authentication

Junio C Hamano (34):
      Revert "doc/Makefile: drop doc-diff worktree and temporary files on "make clean""
      Initial batch post 2.19
      Second batch post 2.19
      Git 2.14.5
      Git 2.15.3
      Git 2.16.5
      Git 2.17.2
      Git 2.18.1
      Git 2.19.1
      t0000: do not get self-test disrupted by environment warnings
      CodingGuidelines: document the API in *.h files
      Declare that the next one will be named 2.20
      Third batch for 2.20
      rebase: fix typoes in error messages
      Fourth batch for 2.20
      Revert "subtree: make install targets depend on build targets"
      Fifth batch for 2.20
      receive: denyCurrentBranch=updateinstead should not blindly update
      cocci: simplify "if (++u > 1)" to "if (u++)"
      fsck: s/++i > 1/i++/
      http: give curl version warnings consistently
      Sixth batch for 2.20
      Seventh batch for 2.20
      fetch: replace string-list used as a look-up table with a hashmap
      rebase: apply cocci patch
      Eighth batch for 2.20
      Ninth batch for 2.20
      Makefile: ease dynamic-gettext-poison transition
      Tenth batch for 2.20
      Git 2.20-rc0
      RelNotes: name the release properly
      Prepare for 2.20-rc1
      Git 2.19.2
      Git 2.20-rc1

Karsten Blees (2):
      mingw: replace MSVCRT's fstat() with a Win32-based implementation
      mingw: implement nanosecond-precision file times

Loo Rong Jie (1):
      win32: replace pthread_cond_*() with much simpler code

Lucas De Marchi (1):
      range-diff: allow to diff files regardless of submodule config

Luke Diamand (3):
      git-p4: do not fail in verbose mode for missing 'fileSize' key
      git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved
      git-p4: fully support unshelving changelists

Martin Ågren (9):
      Doc: use `--type=bool` instead of `--bool`
      git-config.txt: fix 'see: above' note
      git-commit-graph.txt: fix bullet lists
      git-commit-graph.txt: typeset more in monospace
      git-commit-graph.txt: refer to "*commit*-graph file"
      Doc: refer to the "commit-graph file" with dash
      t1400: drop debug `echo` to actually execute `test`
      builtin/commit-graph.c: UNLEAK variables
      sequencer: break out of loop explicitly

Matthew DeVore (19):
      list-objects: store common func args in struct
      list-objects: refactor to process_tree_contents
      list-objects: always parse trees gently
      t/README: reformat Do, Don't, Keep in mind lists
      Documentation: add shell guidelines
      tests: standardize pipe placement
      t/*: fix ordering of expected/observed arguments
      tests: don't swallow Git errors upstream of pipes
      t9109: don't swallow Git errors upstream of pipes
      tests: order arguments to git-rev-list properly
      rev-list: handle missing tree objects properly
      revision: mark non-user-given objects instead
      list-objects-filter: use BUG rather than die
      list-objects-filter-options: do not over-strbuf_init
      list-objects-filter: implement filter tree:0
      filter-trees: code clean-up of tests
      list-objects: support for skipping tree traversal
      Documentation/git-log.txt: do not show --exclude-promisor-objects
      exclude-promisor-objects: declare when option is allowed

Max Kirillov (1):
      http-backend test: make empty CONTENT_LENGTH test more realistic

Michael Witten (3):
      docs: typo: s/go/to/
      docs: graph: remove unnecessary `graph_update()' call
      docs: typo: s/isimilar/similar/

Michał Górny (6):
      gpg-interface.c: detect and reject multiple signatures on commits
      gpg-interface.c: use flags to determine key/signer info presence
      gpg-interface.c: support getting key fingerprint via %GF format
      gpg-interface.c: obtain primary key fingerprint as well
      t/t7510-signed-commit.sh: Add %GP to custom format checks
      t/t7510-signed-commit.sh: add signing subkey to Eris Discordia key

Mihir Mehta (1):
      doc: fix a typo and clarify a sentence

Nguyễn Thái Ngọc Duy (168):
      clone: report duplicate entries on case-insensitive filesystems
      trace.h: support nested performance tracing
      unpack-trees: add performance tracing
      unpack-trees: optimize walking same trees with cache-tree
      unpack-trees: reduce malloc in cache-tree walk
      unpack-trees: reuse (still valid) cache-tree from src_index
      unpack-trees: add missing cache invalidation
      cache-tree: verify valid cache-tree in the test suite
      Document update for nd/unpack-trees-with-cache-tree
      bisect.c: make show_list() build again
      t/helper: keep test-tool command list sorted
      t/helper: merge test-dump-untracked-cache into test-tool
      t/helper: merge test-pkt-line into test-tool
      t/helper: merge test-parse-options into test-tool
      t/helper: merge test-dump-fsmonitor into test-tool
      Makefile: add a hint about TEST_BUILTINS_OBJS
      config.txt: follow camelCase naming
      config.txt: move fetch part out to a separate file
      config.txt: move format part out to a separate file
      config.txt: move gitcvs part out to a separate file
      config.txt: move gui part out to a separate file
      config.txt: move pull part out to a separate file
      config.txt: move push part out to a separate file
      config.txt: move receive part out to a separate file
      config.txt: move sendemail part out to a separate file
      config.txt: move sequence.editor out of "core" part
      config.txt: move submodule part out to a separate file
      archive.c: remove implicit dependency the_repository
      status: show progress bar if refreshing the index takes too long
      add: do not accept pathspec magic 'attr'
      completion: support "git fetch --multiple"
      read-cache.c: remove 'const' from index_has_changes()
      diff.c: reduce implicit dependency on the_index
      combine-diff.c: remove implicit dependency on the_index
      blame.c: rename "repo" argument to "r"
      diff.c: remove the_index dependency in textconv() functions
      grep.c: remove implicit dependency on the_index
      diff.c: remove implicit dependency on the_index
      read-cache.c: remove implicit dependency on the_index
      diff-lib.c: remove implicit dependency on the_index
      ll-merge.c: remove implicit dependency on the_index
      merge-blobs.c: remove implicit dependency on the_index
      merge.c: remove implicit dependency on the_index
      patch-ids.c: remove implicit dependency on the_index
      sha1-file.c: remove implicit dependency on the_index
      rerere.c: remove implicit dependency on the_index
      userdiff.c: remove implicit dependency on the_index
      line-range.c: remove implicit dependency on the_index
      submodule.c: remove implicit dependency on the_index
      tree-diff.c: remove implicit dependency on the_index
      ws.c: remove implicit dependency on the_index
      revision.c: remove implicit dependency on the_index
      revision.c: reduce implicit dependency the_repository
      read-cache.c: optimize reading index format v4
      config.txt: correct the note about uploadpack.packObjectsHook
      help -a: improve and make --verbose default
      refs.c: indent with tabs, not spaces
      Add a place for (not) sharing stuff between worktrees
      submodule.c: remove some of the_repository references
      completion: fix __gitcomp_builtin no longer consider extra options
      t1300: extract and use test_cmp_config()
      worktree: add per-worktree config files
      refs: new ref types to make per-worktree refs visible to all worktrees
      revision.c: correct a parameter name
      revision.c: better error reporting on ref from different worktrees
      fsck: check HEAD and reflog from other worktrees
      reflog expire: cover reflog from all worktrees
      Update makefile in preparation for Documentation/config/*.txt
      config.txt: move advice.* to a separate file
      config.txt: move core.* to a separate file
      config.txt: move add.* to a separate file
      config.txt: move alias.* to a separate file
      config.txt: move am.* to a separate file
      config.txt: move apply.* to a separate file
      config.txt: move blame.* to a separate file
      config.txt: move branch.* to a separate file
      config.txt: move browser.* to a separate file
      config.txt: move checkout.* to a separate file
      config.txt: move clean.* to a separate file
      config.txt: move color.* to a separate file
      config.txt: move column.* to a separate file
      config.txt: move commit.* to a separate file
      config.txt: move credential.* to a separate file
      config.txt: move completion.* to a separate file
      config.txt: move diff-config.txt to config/
      config.txt: move difftool.* to a separate file
      config.txt: move fastimport.* to a separate file
      config.txt: move fetch-config.txt to config/
      config.txt: move filter.* to a separate file
      config.txt: move format-config.txt to config/
      config.txt: move fmt-merge-msg-config.txt to config/
      config.txt: move fsck.* to a separate file
      config.txt: move gc.* to a separate file
      config.txt: move gitcvs-config.txt to config/
      config.txt: move gitweb.* to a separate file
      config.txt: move grep.* to a separate file
      config.txt: move gpg.* to a separate file
      config.txt: move gui-config.txt to config/
      config.txt: move guitool.* to a separate file
      config.txt: move help.* to a separate file
      config.txt: move ssh.* to a separate file
      config.txt: move http.* to a separate file
      config.txt: move i18n.* to a separate file
      git-imap-send.txt: move imap.* to a separate file
      config.txt: move index.* to a separate file
      config.txt: move init.* to a separate file
      config.txt: move instaweb.* to a separate file
      config.txt: move interactive.* to a separate file
      config.txt: move log.* to a separate file
      config.txt: move mailinfo.* to a separate file
      config.txt: move mailmap.* to a separate file
      config.txt: move man.* to a separate file
      config.txt: move merge-config.txt to config/
      config.txt: move mergetool.* to a separate file
      config.txt: move notes.* to a separate file
      config.txt: move pack.* to a separate file
      config.txt: move pager.* to a separate file
      config.txt: move pretty.* to a separate file
      config.txt: move protocol.* to a separate file
      config.txt: move pull-config.txt to config/
      config.txt: move push-config.txt to config/
      config.txt: move rebase-config.txt to config/
      config.txt: move receive-config.txt to config/
      config.txt: move remote.* to a separate file
      config.txt: move remotes.* to a separate file
      config.txt: move repack.* to a separate file
      config.txt: move rerere.* to a separate file
      config.txt: move reset.* to a separate file
      config.txt: move sendemail-config.txt to config/
      config.txt: move sequencer.* to a separate file
      config.txt: move showBranch.* to a separate file
      config.txt: move splitIndex.* to a separate file
      config.txt: move status.* to a separate file
      config.txt: move stash.* to a separate file
      config.txt: move submodule.* to a separate file
      config.txt: move tag.* to a separate file
      config.txt: move transfer.* to a separate file
      config.txt: move uploadarchive.* to a separate file
      config.txt: move uploadpack.* to a separate file
      config.txt: move url.* to a separate file
      config.txt: move user.* to a separate file
      config.txt: move versionsort.* to a separate file
      config.txt: move web.* to a separate file
      config.txt: move worktree.* to a separate file
      config.txt: remove config/dummy.txt
      thread-utils: macros to unconditionally compile pthreads API
      wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode
      git-worktree.txt: correct linkgit command name
      sequencer.c: remove a stray semicolon
      tree-walk.c: fix overoptimistic inclusion in :(exclude) matching
      run-command.h: include thread-utils.h instead of pthread.h
      send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c
      index-pack: remove #ifdef NO_PTHREADS
      name-hash.c: remove #ifdef NO_PTHREADS
      attr.c: remove #ifdef NO_PTHREADS
      grep: remove #ifdef NO_PTHREADS
      grep: clean up num_threads handling
      preload-index.c: remove #ifdef NO_PTHREADS
      pack-objects: remove #ifdef NO_PTHREADS
      read-cache.c: remove #ifdef NO_PTHREADS
      read-cache.c: reduce branching based on HAVE_THREADS
      read-cache.c: initialize copy_len to shut up gcc 8
      Clean up pthread_create() error handling
      completion: use __gitcomp_builtin for format-patch
      build: fix broken command-list.h generation with core.autocrlf
      format-patch: respect --stat in cover letter's diffstat
      doc: move extensions.worktreeConfig to the right place
      clone: fix colliding file detection on APFS

Nickolai Belakovski (2):
      worktree: update documentation for lock_reason and lock_reason_valid
      worktree: rename is_worktree_locked to worktree_lock_reason

Noam Postavsky (1):
      log: fix coloring of certain octopus merge shapes

Olga Telezhnaya (3):
      ref-filter: free memory from used_atom
      ls-remote: release memory instead of UNLEAK
      ref-filter: free item->value and item->value->s

Phillip Wood (11):
      diff: fix --color-moved-ws=allow-indentation-change
      diff --color-moved-ws: fix double free crash
      diff --color-moved-ws: fix out of bounds string access
      diff --color-moved-ws: fix a memory leak
      diff --color-moved-ws: fix another memory leak
      diff --color-moved: fix a memory leak
      am: don't die in read_author_script()
      am: improve author-script error reporting
      am: rename read_author_script()
      add read_author_script() to libgit
      sequencer: use read_author_script()

Pratik Karki (46):
      rebase: start implementing it as a builtin
      rebase: refactor common shell functions into their own file
      builtin/rebase: support running "git rebase <upstream>"
      builtin rebase: support --onto
      builtin rebase: support `git rebase --onto A...B`
      builtin rebase: handle the pre-rebase hook and --no-verify
      builtin rebase: support --quiet
      builtin rebase: support the `verbose` and `diffstat` options
      builtin rebase: require a clean worktree
      builtin rebase: try to fast forward when possible
      builtin rebase: support --force-rebase
      builtin rebase: start a new rebase only if none is in progress
      builtin rebase: only store fully-qualified refs in `options.head_name`
      builtin rebase: support `git rebase <upstream> <switch-to>`
      builtin rebase: support --continue
      builtin rebase: support --skip
      builtin rebase: support --abort
      builtin rebase: support --quit
      builtin rebase: support --edit-todo and --show-current-patch
      builtin rebase: actions require a rebase in progress
      builtin rebase: stop if `git am` is in progress
      builtin rebase: allow selecting the rebase "backend"
      builtin rebase: support --signoff
      builtin rebase: support --rerere-autoupdate
      builtin rebase: support --committer-date-is-author-date
      builtin rebase: support `ignore-whitespace` option
      builtin rebase: support `ignore-date` option
      builtin rebase: support `keep-empty` option
      builtin rebase: support `--autosquash`
      builtin rebase: support `--gpg-sign` option
      builtin rebase: support `-C` and `--whitespace=<type>`
      builtin rebase: support `--autostash` option
      builtin rebase: support `--exec`
      builtin rebase: support `--allow-empty-message` option
      builtin rebase: support --rebase-merges[=[no-]rebase-cousins]
      merge-base --fork-point: extract libified function
      builtin rebase: support `fork-point` option
      builtin rebase: add support for custom merge strategies
      builtin rebase: support --root
      builtin rebase: optionally auto-detect the upstream
      builtin rebase: optionally pass custom reflogs to reset_head()
      builtin rebase: fast-forward to onto if it is a proper descendant
      builtin rebase: show progress when connected to a terminal
      builtin rebase: use no-op editor when interactive is "implied"
      builtin rebase: error out on incompatible option/mode combinations
      rebase: default to using the builtin rebase

Rafael Ascensão (2):
      refs: show --exclude failure with --branches/tags/remotes=glob
      refs: fix some exclude patterns being ignored

Ralf Thielow (1):
      git-rebase.sh: fix typos in error messages

Ramsay Jones (12):
      Makefile: add a hdr-check target
      json-writer.h: add missing include (hdr-check)
      ewah/ewok_rlw.h: add missing include (hdr-check)
      refs/ref-cache.h: add missing declarations (hdr-check)
      refs/packed-backend.h: add missing declaration (hdr-check)
      refs/refs-internal.h: add missing declarations (hdr-check)
      midx.h: add missing forward declarations (hdr-check)
      delta-islands.h: add missing forward declarations (hdr-check)
      headers: normalize the spelling of some header guards
      fetch-object.h: add missing declaration (hdr-check)
      ewok_rlw.h: add missing 'inline' to function definition
      commit-reach.h: add missing declarations (hdr-check)

Rasmus Villemoes (6):
      help: redirect to aliased commands for "git cmd --help"
      git.c: handle_alias: prepend alias info when first argument is -h
      git-help.txt: document "git help cmd" vs "git cmd --help" for aliases
      Documentation/git-send-email.txt: style fixes
      send-email: only consider lines containing @ or <> for automatic Cc'ing
      send-email: also pick up cc addresses from -by trailers

René Scharfe (12):
      mailinfo: support format=flowed
      fsck: add a performance test for skipList
      fsck: use strbuf_getline() to read skiplist file
      fsck: use oidset instead of oid_array for skipList
      sequencer: use return value of oidset_insert()
      grep: add -r/--[no-]recursive
      fetch-pack: factor out is_unmatched_ref()
      fetch-pack: load tip_oids eagerly iff needed
      khash: factor out kh_release_*
      oidset: use khash
      oidset: uninline oidset_init()
      commit-reach: fix cast in compare_commits_by_gen()

Roger Strain (1):
      subtree: performance improvement for finding unexpected parent commits

SZEDER Gábor (17):
      t1404: increase core.packedRefsTimeout to avoid occasional test failure
      Documentation/git.txt: clarify that GIT_TRACE=/path appends
      t3701-add-interactive: tighten the check of trace output
      t1700-split-index: drop unnecessary 'grep'
      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
      t1700-split-index: document why FSMONITOR is disabled in this test script
      split-index: add tests to demonstrate the racy split index problem
      t1700-split-index: date back files to avoid racy situations
      split-index: count the number of deleted entries
      split-index: don't compare cached data of entries already marked for split index
      split-index: smudge and add racily clean cache entries to split index
      split-index: BUG() when cache entry refers to non-existing shared entry
      object_id.cocci: match only expressions of type 'struct object_id'
      test-lib: introduce the '-V' short option for '--verbose-log'
      travis-ci: install packages in 'ci/install-dependencies.sh'
      coccicheck: introduce 'pending' semantic patches
      ref-filter: don't look for objects when outside of a repository

Sam McKelvie (1):
      rev-parse: --show-superproject-working-tree should work during a merge

Saulius Gurklys (1):
      doc: fix small typo in git show-branch

Sebastian Staudt (1):
      travis-ci: no longer use containers

Shulhan (1):
      builtin/remote: quote remote name on error to display empty name

Stefan Beller (25):
      git-submodule.sh: align error reporting for update mode to use path
      git-submodule.sh: rename unused variables
      builtin/submodule--helper: factor out submodule updating
      builtin/submodule--helper: store update_clone information in a struct
      builtin/submodule--helper: factor out method to update a single submodule
      submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
      submodule--helper: introduce new update-module-mode helper
      test_decode_color: understand FAINT and ITALIC
      t3206: add color test for range-diff --dual-color
      diff.c: simplify caller of emit_line_0
      diff.c: reorder arguments for emit_line_ws_markup
      diff.c: add set_sign to emit_line_0
      diff: use emit_line_0 once per line
      diff.c: omit check for line prefix in emit_line_0
      diff.c: rewrite emit_line_0 more understandably
      diff.c: add --output-indicator-{new, old, context}
      range-diff: make use of different output indicators
      range-diff: indent special lines as context
      refs.c: migrate internal ref iteration to pass thru repository argument
      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
      string-list: remove unused function print_string_list
      strbuf.h: format according to coding guidelines
      diff.c: pass sign_index to emit_line_ws_markup
      submodule helper: convert relative URL to absolute URL if needed
      builtin/submodule--helper: remove debugging leftover tracing

Stephen P. Smith (10):
      wt-status.c: move has_unmerged earlier in the file
      wt-status: rename commitable to committable
      t7501: add test of "commit --dry-run --short"
      wt-status.c: set the committable flag in the collect phase
      roll wt_status_state into wt_status and populate in the collect phase
      t2000: rename and combine checkout clash tests
      t7509: cleanup description and filename
      t7502: rename commit test script to comply with naming convention
      t7500: rename commit tests script to comply with naming convention
      t7501: rename commit test to comply with naming convention

Steve Hoelzer (1):
      poll: use GetTickCount64() to avoid wrap-around issues

Steven Fernandez (1):
      git-completion.bash: add completion for stash list

Strain, Roger L (4):
      subtree: refactor split of a commit into standalone method
      subtree: make --ignore-joins pay attention to adds
      subtree: use commits before rejoins for splits
      subtree: improve decision on merges kept in split

Tao Qingyun (3):
      refs: docstring typo
      builtin/branch.c: remove useless branch_get
      branch: trivial style fix

Taylor Blau (4):
      transport.c: extract 'fill_alternate_refs_command'
      transport.c: introduce core.alternateRefsCommand
      transport.c: introduce core.alternateRefsPrefixes
      Documentation/config.txt: fix typo in core.alternateRefsCommand

Thomas Gummerer (17):
      rerere: unify error messages when read_cache fails
      rerere: lowercase error messages
      rerere: wrap paths in output in sq
      rerere: mark strings for translation
      rerere: add documentation for conflict normalization
      rerere: fix crash with files rerere can't handle
      rerere: only return whether a path has conflicts or not
      rerere: factor out handle_conflict function
      rerere: return strbuf from handle path
      rerere: teach rerere to handle nested conflicts
      rerere: recalculate conflict ID when unresolved conflict is committed
      rerere: mention caveat about unmatched conflict markers
      rerere: add note about files with existing conflict markers
      .gitattributes: add conflict-marker-size for relevant files
      linear-assignment: fix potential out of bounds memory access
      t5551: move setup code inside test_expect blocks
      t5551: compare sorted cookies files

Tim Schumacher (4):
      Documentation/Makefile: make manpage-base-url.xsl generation quieter
      alias: add support for aliases of an alias
      alias: show the call history when an alias is looping
      t0014: introduce an alias testing suite

Todd Zullinger (1):
      Documentation: build technical/multi-pack-index

Torsten Bögershausen (4):
      Make git_check_attr() a void function
      path.c: char is not (always) signed
      Upcast size_t variables to uintmax_t when printing
      remote-curl.c: xcurl_off_t is not portable (on 32 bit platfoms)

Uwe Kleine-König (1):
      howto/using-merge-subtree: mention --allow-unrelated-histories

brian m. carlson (26):
      t: add test functions to translate hash-related values
      t0000: use hash translation table
      t0000: update tests for SHA-256
      t0002: abstract away SHA-1 specific constants
      t0064: make hash size independent
      t1006: make hash size independent
      t1400: switch hard-coded object ID to variable
      t1405: make hash size independent
      t1406: make hash-size independent
      t1407: make hash size independent
      editorconfig: provide editor settings for Git developers
      editorconfig: indicate settings should be kept in sync
      pack-bitmap-write: use GIT_MAX_RAWSZ for allocation
      builtin/repack: replace hard-coded constants
      builtin/mktree: remove hard-coded constant
      builtin/fetch-pack: remove constants with parse_oid_hex
      pack-revindex: express constants in terms of the_hash_algo
      packfile: express constants in terms of the_hash_algo
      refs/packed-backend: express constants using the_hash_algo
      upload-pack: express constants in terms of the_hash_algo
      transport: use parse_oid_hex instead of a constant
      tag: express constant in terms of the_hash_algo
      apply: replace hard-coded constants
      apply: rename new_sha1_prefix and old_sha1_prefix
      submodule: make zero-oid comparison hash function agnostic
      rerere: convert to use the_hash_algo

Ævar Arnfjörð Bjarmason (33):
      fetch: change "branch" to "reference" in --force -h output
      push tests: make use of unused $1 in test description
      push tests: use spaces in interpolated string
      fetch tests: add a test for clobbering tag behavior
      push doc: remove confusing mention of remote merger
      push doc: move mention of "tag <tag>" later in the prose
      push doc: correct lies about how push refspecs work
      fetch: document local ref updates with/without --force
      fetch: stop clobbering existing tags without --force
      fsck tests: setup of bogus commit object
      fsck tests: add a test for no skipList input
      fsck: document and test sorted skipList input
      fsck: document and test commented & empty line skipList input
      fsck: document that skipList input must be unabbreviated
      fsck: add a performance test
      fsck: support comments & empty lines in skipList
      commit-graph write: add progress output
      commit-graph verify: add progress output
      config doc: add missing list separator for checkout.optimizeNewBranch
      push doc: add spacing between two words
      fetch doc: correct grammar in --force docs
      gc: fix regression in 7b0f229222 impacting --quiet
      gc doc: mention the commit-graph in the intro
      pack-objects test: modernize style
      pack-objects tests: don't leave test .git corrupt at end
      index-pack tests: don't leave test repo dirty at end
      i18n: make GETTEXT_POISON a runtime option
      range-diff doc: add a section about output stability
      range-diff: fix regression in passing along diff options
      range-diff: make diff option behavior (e.g. --stat) consistent
      rebase doc: document rebase.useBuiltin
      tests: add a special setup where rebase.useBuiltin is off
      read-cache: make the split index obey umask settings

Đoàn Trần Công Danh (1):
      git-compat-util: prefer poll.h to sys/poll.h


^ permalink raw reply	[relevance 2%]

* [ANNOUNCE] Git v2.19.2
@ 2018-11-21 15:19  2% Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-11-21 15:19 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

The latest maintenance release Git v2.19.2 is now available at the
usual places.  This is a collection of small fixes that have been
accumulated on the primary development track, merged on top of
v2.19.1 released earlier in the year.  On the 'master' front, we are
nearing the upcoming future release, by the way.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/

The following public repositories all have a copy of the 'v2.19.2'
tag and the 'maint' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

----------------------------------------------------------------

Git v2.19.2 Release Notes
=========================

Fixes since v2.19.1
-------------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.

 * Further fix for O_APPEND emulation on Windows

 * A corner case bugfix in "git rerere" code.

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.

 * Update error messages given by "git remote" and make them consistent.

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.

 * The mailmap file update.

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.

 * A corner-case bugfix.

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.

Also contains various documentation updates and code clean-ups.

----------------------------------------------------------------

Changes since v2.19.1 are as follows:

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Ben Peart (1):
      git-mv: allow submodules and fsmonitor to work together

Brandon Williams (1):
      config: document value 2 for protocol.version

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Derrick Stolee (6):
      commit-graph: update design document
      test-repository: properly init repo
      commit-graph: not compatible with replace objects
      commit-graph: not compatible with grafts
      commit-graph: not compatible with uninitialized repo
      commit-graph: close_commit_graph before shallow walk

Elijah Newren (7):
      Remove superfluous trailing semicolons
      t4200: demonstrate rerere segfault on specially crafted merge
      rerere: avoid buffer overrun
      update-ref: fix type of update_flags variable to match its usage
      update-ref: allow --no-deref with --stdin
      sequencer: fix --allow-empty-message behavior, make it smarter
      commit: fix erroneous BUG, 'multiple renames on the same target? how?'

Frederick Eaton (3):
      git-archimport.1: specify what kind of Arch we're talking about
      git-column.1: clarify initial description, provide examples
      git-describe.1: clarify that "human readable" is also git-readable

Jeff Hostetler (2):
      t0051: test GIT_TRACE to a windows named pipe
      mingw: fix mingw_open_append to work with named pipes

Jeff King (16):
      trailer: use size_t for string offsets
      trailer: use size_t for iterating trailer list
      trailer: pass process_trailer_opts to trailer_info_get()
      interpret-trailers: tighten check for "---" patch boundary
      interpret-trailers: allow suppressing "---" divider
      pretty, ref-filter: format %(trailers) with no_divider option
      sequencer: ignore "---" divider when parsing trailers
      append_signoff: use size_t for string offsets
      reopen_tempfile(): truncate opened file
      config.mak.dev: add -Wformat-security
      receive-pack: update comment with check_everything_connected
      run-command: mark path lookup errors with ENOENT
      upload-pack: fix broken if/else chain in config callback
      t1450: check large blob in trailing-garbage test
      check_stream_sha1(): handle input underflow
      cat-file: handle streaming failures consistently

Johannes Schindelin (8):
      rebase -i --autosquash: demonstrate a problem skipping the last squash
      rebase -i: be careful to wrap up fixup/squash chains
      pack-objects: fix typo 'detla' -> 'delta'
      pack-objects (mingw): demonstrate a segmentation fault with large deltas
      pack-objects (mingw): initialize `packing_data` mutex in the correct spot
      repack: point out a bug handling stale shallow info
      shallow: offer to prune only non-existing entries
      repack -ad: prune the list of shallow commits

Johannes Sixt (2):
      diff: don't attempt to strip prefix from absolute Windows paths
      t3404-rebase-interactive: test abbreviated commands

Jonathan Nieder (2):
      mailmap: consistently normalize brian m. carlson's name
      git doc: direct bug reporters to mailing list archive

Jonathan Tan (4):
      fetch-object: unify fetch_object[s] functions
      fetch-object: set exact_oid when fetching
      fetch-pack: avoid object flags if no_dependents
      fetch-pack: exclude blobs when lazy-fetching trees

Junio C Hamano (5):
      CodingGuidelines: document the API in *.h files
      receive: denyCurrentBranch=updateinstead should not blindly update
      cocci: simplify "if (++u > 1)" to "if (u++)"
      fsck: s/++i > 1/i++/
      Git 2.19.2

Martin Ågren (5):
      git-commit-graph.txt: fix bullet lists
      git-commit-graph.txt: typeset more in monospace
      git-commit-graph.txt: refer to "*commit*-graph file"
      Doc: refer to the "commit-graph file" with dash
      t1400: drop debug `echo` to actually execute `test`

Matthew DeVore (2):
      Documentation/git-log.txt: do not show --exclude-promisor-objects
      exclude-promisor-objects: declare when option is allowed

Michael Witten (3):
      docs: typo: s/go/to/
      docs: graph: remove unnecessary `graph_update()' call
      docs: typo: s/isimilar/similar/

Mihir Mehta (1):
      doc: fix a typo and clarify a sentence

Nguyễn Thái Ngọc Duy (2):
      add: do not accept pathspec magic 'attr'
      config.txt: correct the note about uploadpack.packObjectsHook

Noam Postavsky (1):
      log: fix coloring of certain octopus merge shapes

René Scharfe (1):
      sequencer: use return value of oidset_insert()

SZEDER Gábor (12):
      Documentation/git.txt: clarify that GIT_TRACE=/path appends
      t3701-add-interactive: tighten the check of trace output
      t1700-split-index: drop unnecessary 'grep'
      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
      t1700-split-index: document why FSMONITOR is disabled in this test script
      split-index: add tests to demonstrate the racy split index problem
      t1700-split-index: date back files to avoid racy situations
      split-index: count the number of deleted entries
      split-index: don't compare cached data of entries already marked for split index
      split-index: smudge and add racily clean cache entries to split index
      split-index: BUG() when cache entry refers to non-existing shared entry
      test-lib: introduce the '-V' short option for '--verbose-log'

Sam McKelvie (1):
      rev-parse: --show-superproject-working-tree should work during a merge

Saulius Gurklys (1):
      doc: fix small typo in git show-branch

Sebastian Staudt (1):
      travis-ci: no longer use containers

Shulhan (1):
      builtin/remote: quote remote name on error to display empty name

Stefan Beller (4):
      refs.c: migrate internal ref iteration to pass thru repository argument
      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
      string-list: remove unused function print_string_list
      strbuf.h: format according to coding guidelines

Tao Qingyun (3):
      refs: docstring typo
      builtin/branch.c: remove useless branch_get
      branch: trivial style fix

Thomas Gummerer (4):
      .gitattributes: add conflict-marker-size for relevant files
      linear-assignment: fix potential out of bounds memory access
      t5551: move setup code inside test_expect blocks
      t5551: compare sorted cookies files

Tim Schumacher (1):
      Documentation/Makefile: make manpage-base-url.xsl generation quieter

Torsten Bögershausen (2):
      Make git_check_attr() a void function
      path.c: char is not (always) signed

Uwe Kleine-König (1):
      howto/using-merge-subtree: mention --allow-unrelated-histories


^ permalink raw reply	[relevance 2%]

* Git Test Coverage Report (Wednesday Nov 21)
@ 2018-11-21 14:46  2% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-21 14:46 UTC (permalink / raw)
  To: Git List

Here is today's test report.

Thanks,
-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=271&view=logs

---

pu: c4a21f043160e02a25755bbf43e4d2fa0b9766aa
jch: 29ea8ddbcef3ec1c79fffa23cc5751a45344754c
next: 68bc7959f8dc2d629c09be1a52f1b95b977b3a13
master: bb75be6cb916297f271c846f2f9caa3daaaec718
master@{1}: d166e6afe5f257217836ef24a73764eba390c58d

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
c4a21f0431 builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/describe.c
c4a21f0431 builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/pack-objects.c
c4a21f0431 builtin/pack-objects.c 2834) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fast-import.c
c4a21f0431 2793) buf = repo_read_object_file(the_repository, oid, &type, 
&size);
c4a21f0431 2899) buf = repo_read_object_file(the_repository, oid, &unused,

fsck.c
c4a21f0431  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
c4a21f0431  878) repo_read_object_file(the_repository,
c4a21f0431  879)       &tag->object.oid, &type, &size);

http-push.c
c4a21f0431 1635) if (!repo_has_object_file(the_repository, &head_oid))
c4a21f0431 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

negotiator/default.c
c4a21f0431  71) if (repo_parse_commit(the_repository, commit))

protocol.c
24c10f7473  37) die(_("Unrecognized protocol version"));
24c10f7473  39) die(_("Unrecognized protocol_version"));

remote-curl.c
24c10f7473  403) return 0;

revision.c
c4a21f0431  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
c4a21f0431 1643) repo_unuse_commit_buffer(the_repository, head_commit,
c4a21f0431 3914) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

strbuf.c
10a40f5700  397) return 0;

submodule.c
e2419f7e30 1376) strbuf_release(&gitdir);
7454fe5cb6 1499) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1503) get_next_submodule_task_release(task);
7454fe5cb6 1530) return 0;
7454fe5cb6 1534) goto out;
7454fe5cb6 1549) return 0;

tree.c
c4a21f0431 110) if (repo_parse_commit(the_repository, commit))

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Anders Waldenborg      10a40f570: strbuf: separate callback for 
strbuf_expand:ing literals
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Josh Steadmon      24c10f747: protocol: advertise multiple supported 
versions
Junio C Hamano      c4a21f043: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

pathspec.c
22af33bece 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
ee70c12820 1730) if (advice_unknown_index_extension) {
ee70c12820 1731) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1732) advise(_("This is likely due to the file having been 
written by a newer\n"

sequencer.c
18e711a162 2387) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

tree.c
e092073d64 104) commit = lookup_commit(r, entry.oid);

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths
Nguyễn Thái Ngọc Duy      22af33bec: dir.c: move, rename and export 
match_attrs()
Nguyễn Thái Ngọc Duy      e092073d6: tree.c: make read_tree*() take 
'struct repository *'



Uncovered code in 'next' not in 'master'
--------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 421) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 460) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 584) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 619) fprintf_ln(stderr, _("Checking object 
directory"));
5215bd2f7d builtin/fsck.c 637) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
5215bd2f7d builtin/fsck.c 642) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 671) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 687) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/rebase.c
4d86503eed  585) ret = error(_("failed to find tree of %s"),

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
5215bd2f7d 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
5215bd2f7d 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

config.c
2a9dedef2e 2309) *dest = val ? 0 : 1;
2a9dedef2e 2311) *dest = val;
2a9dedef2e 2312) return 0;

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

entry.c
e66ceca94b 422) if ((trust_ino && !match_stat_data(&dup->ce_stat_data, 
st)) ||

fast-import.c
a965bb3116 1821) read_next_command();

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2251) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2286) die(_("broken index, expect %s in %s, got %s"),
d8465500c3 2699) return val;
429160544d 2714) return val;
9d0a9e9089 3100) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3247) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  236) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2353) return error(_("option `%s' is incompatible with 
--no-merged"),

remote-curl.c
afa5d74929  359) die("invalid server response; expected service, got 
flush packet");

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2145) return r;

Commits introducing uncovered code:
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      afa5d7492: remote-curl: refactor smart-http discovery
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Johannes Schindelin      4d86503ee: rebase: warn about the correct 
tree's OID
Jonathan Nieder      2a9dedef2: index: make index.threads=true enable 
ieot and eoie
Jonathan Nieder      429160544: ieot: default to not writing IEOT section
Jonathan Nieder      d8465500c: eoie: default to not writing EOIE section
Junio C Hamano      5215bd2f7: Merge branch 'nd/i18n' into next
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      e66ceca94: clone: fix colliding file detection 
on APFS
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

apply.c
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

builtin/am.c
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/cat-file.c
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/grep.c
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/log.c
517fe807d6 builtin/log.c 1194) BUG_ON_OPT_NEG(unset);

builtin/pack-objects.c
ca473cef91 builtin/pack-objects.c 2086) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2087) oid_to_hex(&trg_entry->idx.oid), 
(uintmax_t)sz,
ca473cef91 builtin/pack-objects.c 2113) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2114) oid_to_hex(&src_entry->idx.oid), 
(uintmax_t)sz,

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/rebase.c
3249c1251e  556) ret = -1;
3249c1251e  557) goto leave_reset_head;
bac2a1e36f  561) ret = error(_("could not determine HEAD revision"));
bac2a1e36f  562) goto leave_reset_head;
3249c1251e  580) ret = error(_("could not read index"));
3249c1251e  581) goto leave_reset_head;
bac2a1e36f  585) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
bac2a1e36f  586) goto leave_reset_head;
3249c1251e  590) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
3249c1251e  591) goto leave_reset_head;
3249c1251e  604) goto leave_reset_head;

builtin/show-branch.c
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

bundle.c
2c8ee1f53c 267) error_errno(_("unable to dup bundle descriptor"));
2c8ee1f53c 268) child_process_clear(&pack_objects);
2c8ee1f53c 269) return -1;
2c8ee1f53c 478) rollback_lock_file(&lock);

config.c
fast-import.c
ca473cef91 2958) strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),

midx.c
name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

preload-index.c
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

revision.c
b45424181e 2915) define_commit_slab(author_date_slab, timestamp_t);
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2948) record_author_date(&info->author_date, c);
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3031) info->topo_queue.compare = compare_commits_by_commit_date;
b45424181e 3032) break;
b45424181e 3034) init_author_date_slab(&info->author_date);
b45424181e 3035) info->topo_queue.compare = compare_commits_by_author_date;
b45424181e 3036) info->topo_queue.cb_data = &info->author_date;
b45424181e 3037) break;
b45424181e 3048) continue;
b45424181e 3059) record_author_date(&info->author_date, c);
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

Commits introducing uncovered code:
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      2c8ee1f53: bundle: dup() output descriptor closer to 
point-of-use
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      fce566480: am: handle --no-patch-format option
Johannes Schindelin      3249c1251: rebase: consolidate clean-up code 
before leaving reset_head()
Johannes Schindelin      bac2a1e36: built-in rebase: reinstate `checkout 
-q` behavior where appropriate
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling
Torsten Bögershausen      ca473cef9: Upcast size_t variables to 
uintmax_t when printing


^ permalink raw reply	[relevance 2%]

* Git Test Coverage Report (v2.20.0-rc0)
@ 2018-11-19  2:54  3% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-19  2:54 UTC (permalink / raw)
  To: git@vger.kernel.org

Here is a test coverage report for the uncovered lines introduced in 
v2.20.0-rc0 compared to v2.19.1.

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=263&view=logs

---


apply.c
eccb5a5f3d 4071) return get_oid_hex(p->old_oid_prefix, oid);
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

blame.c
a470beea39  113)  !strcmp(r->index->cache[-1 - pos]->name, path))
a470beea39  272) int pos = index_name_pos(r->index, path, len);
a470beea39  274) mode = r->index->cache[pos]->ce_mode;

builtin/add.c
d1664e73ad builtin/add.c 458) die(_("index file corrupt"));

builtin/am.c
2abf350385 1362) repo_init_revisions(the_repository, &rev_info, NULL);
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/checkout.c
fa655d8411 builtin/checkout.c  539) return 0;
fa655d8411 builtin/checkout.c  953) return error(_("index file corrupt"));

builtin/difftool.c
4a7e27e957 441) if (oideq(&loid, &roid))

builtin/fast-export.c
4a7e27e957 builtin/fast-export.c  387) if (oideq(&ospec->oid, &spec->oid) &&

builtin/fetch.c
builtin/fsck.c
b29759d89a builtin/fsck.c 613) fprintf(stderr, "Checking %s link\n", 
head_ref_name);
b29759d89a builtin/fsck.c 618) return error("Invalid %s", head_ref_name);
454ea2e4d7 builtin/fsck.c 769) for (p = get_all_packs(the_repository); p;
66ec0390e7 builtin/fsck.c 888) midx_argv[2] = "--object-dir";
66ec0390e7 builtin/fsck.c 889) midx_argv[3] = alt->path;
66ec0390e7 builtin/fsck.c 890) if (run_command(&midx_verify))
66ec0390e7 builtin/fsck.c 891) errors_found |= ERROR_COMMIT_GRAPH;

builtin/gc.c
3029970275 builtin/gc.c 461) ret = error_errno(_("cannot stat '%s'"), 
gc_log_path);
3029970275 builtin/gc.c 470) ret = error_errno(_("cannot read '%s'"), 
gc_log_path);
fec2ed2187 builtin/gc.c 495) die(FAILED_RUN, pack_refs_cmd.argv[0]);
fec2ed2187 builtin/gc.c 498) die(FAILED_RUN, reflog.argv[0]);
3029970275 builtin/gc.c 585) exit(128);
fec2ed2187 builtin/gc.c 637) die(FAILED_RUN, repack.argv[0]);
fec2ed2187 builtin/gc.c 647) die(FAILED_RUN, prune.argv[0]);
fec2ed2187 builtin/gc.c 654) die(FAILED_RUN, prune_worktrees.argv[0]);
fec2ed2187 builtin/gc.c 658) die(FAILED_RUN, rerere.argv[0]);

builtin/grep.c
76e9bdc437 builtin/grep.c  424) grep_read_unlock();
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/help.c
e6e76baaf4 builtin/help.c 429) if (!exclude_guides || alias[0] == '!') {
e6e76baaf4 builtin/help.c 430) printf_ln(_("'%s' is aliased to '%s'"), 
cmd, alias);
e6e76baaf4 builtin/help.c 431) free(alias);
e6e76baaf4 builtin/help.c 432) exit(0);
e6e76baaf4 builtin/help.c 441) fprintf_ln(stderr, _("'%s' is aliased to 
'%s'"), cmd, alias);
e6e76baaf4 builtin/help.c 442) count = split_cmdline(alias, &argv);
e6e76baaf4 builtin/help.c 443) if (count < 0)
e6e76baaf4 builtin/help.c 444) die(_("bad alias.%s string: %s"), cmd,
e6e76baaf4 builtin/help.c 446) free(argv);
e6e76baaf4 builtin/help.c 448) return alias;

builtin/log.c
517fe807d6 builtin/log.c 1196) BUG_ON_OPT_NEG(unset);
2e6fd71a52 builtin/log.c 1472) die(_("failed to infer range-diff ranges"));
ee6cbf712e builtin/log.c 1818) die(_("--interdiff requires 
--cover-letter or single patch"));
8631bf1cdd builtin/log.c 1828) else if (!rdiff_prev)
8631bf1cdd builtin/log.c 1829) die(_("--creation-factor requires 
--range-diff"));
40ce41604d builtin/log.c 1833) die(_("--range-diff requires 
--cover-letter or single patch"));

builtin/multi-pack-index.c
6d68e6a461 35) usage_with_options(builtin_multi_pack_index_usage,
6d68e6a461 39) die(_("too many arguments"));
6d68e6a461 48) die(_("unrecognized verb: %s"), argv[0]);

builtin/pack-objects.c
6a22d52126 builtin/pack-objects.c 1091) continue;
2fa233a554 builtin/pack-objects.c 1512) hashcpy(base_oid.hash, base_sha1);
2fa233a554 builtin/pack-objects.c 1513) if 
(!in_same_island(&delta->idx.oid, &base_oid))
2fa233a554 builtin/pack-objects.c 1514) return 0;
28b8a73080 builtin/pack-objects.c 2793) depth++;
108f530385 builtin/pack-objects.c 2797) oe_set_tree_depth(&to_pack, ent, 
depth);
454ea2e4d7 builtin/pack-objects.c 2981) p = get_all_packs(the_repository);

builtin/pack-redundant.c
454ea2e4d7 builtin/pack-redundant.c 580) struct packed_git *p = 
get_all_packs(the_repository);
454ea2e4d7 builtin/pack-redundant.c 595) struct packed_git *p = 
get_all_packs(the_repository);

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
62c23938fa   55) return env;
55071ea248   65) strbuf_trim(&out);
55071ea248   66) ret = !strcmp("true", out.buf);
55071ea248   67) strbuf_release(&out);
002ee2fe68  119) die(_("%s requires an interactive rebase"), option);
f95736288a  152) return error_errno(_("could not read '%s'"), path);
f95736288a  166) return -1;
f95736288a  171) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  182) return -1;
f95736288a  183) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  184) return -1;
f95736288a  186) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  190) return -1;
f95736288a  192) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  200) opts->signoff = 1;
73d51ed0a5  201) opts->flags |= REBASE_FORCE;
ead98c111b  208) return -1;
12026a412c  223) return -1;
ba1905a5fe  231) return -1;
ba1905a5fe  239) return -1;
6defce2b02  259) return error(_("Could not read '%s'"), path);
6defce2b02  277) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  281) return res;
bc24382c2b  379) argv_array_pushf(&child.args,
bc24382c2b  381) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  515) struct strbuf dir = STRBUF_INIT;
6defce2b02  517) apply_autostash(opts);
ac7f467fef  518) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  519) remove_dir_recursively(&dir, 0);
ac7f467fef  520) strbuf_release(&dir);
ac7f467fef  521) die("Nothing to do");
3249c1251e  556) ret = -1;
3249c1251e  557) goto leave_reset_head;
bac2a1e36f  561) ret = error(_("could not determine HEAD revision"));
bac2a1e36f  562) goto leave_reset_head;
3249c1251e  580) ret = error(_("could not read index"));
3249c1251e  581) goto leave_reset_head;
bac2a1e36f  585) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
bac2a1e36f  586) goto leave_reset_head;
3249c1251e  590) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
3249c1251e  591) goto leave_reset_head;
ac7f467fef  603) ret = error(_("could not write index"));
3249c1251e  604) goto leave_reset_head;
ac7f467fef  621) } else if (old_orig)
ac7f467fef  622) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  655) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  689) return 1;
9a48a615b4  705) return 0;
55071ea248  916) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  919) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  920) die_errno(_("could not exec %s"), path);
0eabf4b95c  938) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  975) usage_with_options(builtin_rebase_usage,
f95736288a  995) die(_("Cannot read HEAD"));
f95736288a  999) die(_("could not read index"));
f95736288a 1013) exit(1);
122420c295 1026) die(_("could not discard worktree changes"));
122420c295 1029) exit(1);
5e5d96197c 1040) exit(1);
5e5d96197c 1044) die(_("could not move back to %s"),
5a61494539 1055) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1074) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1075) const char *state_dir_base =
c54dacb50e 1076) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1077) const char *cmd_live_rebase =
c54dacb50e 1079) strbuf_reset(&buf);
c54dacb50e 1080) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1081) die(_("It seems that there is already a %s directory, 
and\n"
3c3588c7d3 1138) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1139) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1161) die(_("--strategy requires --merge or --interactive"));
cda614e489 1179) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1188) options.state_dir = apply_dir();
ac7f467fef 1189) break;
ac7f467fef 1261) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1267) die(_("Could not create new root commit"));
e65123a71d 1317) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1325) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1337) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1350) die(_("could not read index"));
6defce2b02 1377) die(_("Cannot autostash"));
6defce2b02 1380) die(_("Unexpected stash response: '%s'"),
6defce2b02 1386) die(_("Could not create directory for '%s'"),
6defce2b02 1392) die(_("could not reset --hard"));
e65123a71d 1436) ret = !!error(_("could not parse '%s'"),
e65123a71d 1438) goto cleanup;
e65123a71d 1447) ret = !!error(_("could not switch to "
1ed9c14ff2 1457)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1458) puts(_("HEAD is up to date."));
9a48a615b4 1467)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1468) puts(_("HEAD is up to date, rebase forced."));

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 580) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 616) continue;

builtin/remote.c
5025425dff builtin/remote.c  864) return error(_("No such remote: 
'%s'"), name);

builtin/repack.c
16d75fa48d  48) use_delta_islands = git_config_bool(var, value);
16d75fa48d  49) return 0;
2f0c9e9a9b 239) die("repack: Expecting full hex object ID lines only 
from pack-objects.");
2f0c9e9a9b 411) die("repack: Expecting full hex object ID lines only 
from pack-objects.");

builtin/rerere.c
2373b65059 builtin/rerere.c  79) warning(_("'git rerere forget' without 
paths is deprecated"));
2373b65059 builtin/rerere.c 111) die(_("unable to generate diff for 
'%s'"), rerere_path(id, NULL));

builtin/rev-list.c
7c0fe330d5 builtin/rev-list.c 227) die("unexpected missing %s object '%s'",
7c0fe330d5 builtin/rev-list.c 228)     type_name(obj->type), 
oid_to_hex(&obj->oid));

builtin/show-branch.c
9001dc2a74 builtin/show-branch.c 430) if (get_oid(refname + ofs, &tmp) 
|| !oideq(&tmp, oid))
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

builtin/submodule--helper.c
ee69b2a90c 1469) die(_("Invalid update mode '%s' for submodule path '%s'"),
ee69b2a90c 1473) die(_("Invalid update mode '%s' configured for 
submodule path '%s'"),
ee69b2a90c 1476) out->type = sub->update_strategy.type;
ee69b2a90c 1477) out->command = sub->update_strategy.command;
ee69b2a90c 1497) die("submodule--helper update-module-clone expects 
<just-cloned> <path> [<update>]");
e0a862fdaf 1648) url = sub->url;
74d4731da1 2057) die(_("could not get a repository handle for submodule 
'%s'"), path);

builtin/unpack-objects.c
4a7e27e957 builtin/unpack-objects.c 306) if (oideq(&info->base_oid, 
&obj_list[nr].oid) ||

builtin/update-index.c
4a7e27e957 builtin/update-index.c  672) if (oideq(&ce_2->oid, &ce_3->oid) &&

builtin/worktree.c
e5353bef55  60) error_errno(_("failed to delete '%s'"), sb.buf);
e19831c94f 251)     die(_("unable to re-add worktree '%s'"), path);
68a6b3a1bd 793) die(_("cannot move a locked working tree, lock reason: 
%s\nuse 'move -f -f' to override or unlock first"),
f4143101cb 906) die(_("cannot remove a locked working tree, lock reason: 
%s\nuse 'remove -f -f' to override or unlock first"),

bundle.c
2c8ee1f53c 267) error_errno(_("unable to dup bundle descriptor"));
2c8ee1f53c 268) child_process_clear(&pack_objects);
2c8ee1f53c 269) return -1;
2c8ee1f53c 478) rollback_lock_file(&lock);

cache-tree.c
combine-diff.c
0074c9110d  377) state->sline[state->nb-1].p_lno =
0074c9110d  378) xcalloc(state->num_parent, sizeof(unsigned long));

commit-graph.c
20fd6d5799   79) return 0;
6cc017431c  275) return 0;

commit-reach.c
5227c38566 134) return ret;
5227c38566 282) return 1;
5227c38566 314) return ret;
5227c38566 317) return ret;
1d614d41e5 395) return 0;
1d614d41e5 401) return 0;
1d614d41e5 405) return 0;
4fbcca4eff 538) return 1;
b67f6b26e3 559) continue;
b67f6b26e3 570) from->objects[i].item->flags |= assign_flag;
b67f6b26e3 571) continue;
b67f6b26e3 577) result = 0;
b67f6b26e3 578) goto cleanup;

config.c
c780b9cfe8 2303) return val;
c780b9cfe8 2306) if (is_bool)
c780b9cfe8 2307) return val ? 0 : 1;
c780b9cfe8 2309) return val;

date.c
c27cc94fad  904) tm->tm_mon = number-1;
c27cc94fad  908) else if (number > 69 && number < 100)
c27cc94fad  909) tm->tm_year = number;
c27cc94fad  910) else if (number < 38)
c27cc94fad  911) tm->tm_year = 100 + number;
c27cc94fad  952) pending_number(tm, num);

delta-islands.c
c8d521faf7  53) memcpy(b, old, size);
c8d521faf7  73) return 1;
c8d521faf7 118) return 0;
c8d521faf7 130) return 0;
c8d521faf7 187) b->refcount--;
c8d521faf7 188) b = kh_value(island_marks, pos) = island_bitmap_new(b);
c8d521faf7 202) continue;
c8d521faf7 212) obj = ((struct tag *)obj)->tagged;
c8d521faf7 213) if (obj) {
c8d521faf7 214) parse_object(the_repository, &obj->oid);
c8d521faf7 215) marks = create_or_get_island_marks(obj);
c8d521faf7 216) island_bitmap_set(marks, island_counter);
c8d521faf7 248) return;
c8d521faf7 268) progress_state = start_progress(_("Propagating island 
marks"), nr);
c8d521faf7 286) die(_("bad tree object %s"), oid_to_hex(&ent->idx.oid));
c8d521faf7 293) continue;
c8d521faf7 297) continue;
c8d521faf7 321) return config_error_nonbool(k);
c8d521faf7 330) die(_("failed to load island regex for '%s': %s"), k, 
re.buf);
c8d521faf7 386) warning(_("island regex from config has "
c8d521faf7 397) strbuf_addch(&island_name, '-');
c8d521faf7 433) continue;
c8d521faf7 436) list[dst] = list[src];

diff-lib.c
9001dc2a74 diff-lib.c 346)     (!oideq(oid, &old_entry->oid) || 
!oideq(&old_entry->oid, &new_entry->oid))) {

diff.c
b78ea5fc35 4130) add_external_diff_name(o->repo, &argv, other, two);

dir.c
8a2c174677  287) name = to_free = xmemdupz(name, namelen);
c46c406ae1 2282) trace_performance_leave("read directory %.*s", len, path);

entry.c
b878579ae7 402) static void mark_colliding_entries(const struct checkout 
*state,
b878579ae7 405) int i, trust_ino = check_stat;
b878579ae7 411) ce->ce_flags |= CE_MATCHED;
b878579ae7 413) for (i = 0; i < state->istate->cache_nr; i++) {
b878579ae7 414) struct cache_entry *dup = state->istate->cache[i];
b878579ae7 416) if (dup == ce)
b878579ae7 417) break;
b878579ae7 419) if (dup->ce_flags & (CE_MATCHED | CE_VALID | 
CE_SKIP_WORKTREE))
b878579ae7 420) continue;
b878579ae7 422) if ((trust_ino && dup->ce_stat_data.sd_ino == st->st_ino) ||
b878579ae7 423)     (!trust_ino && !fspathcmp(ce->name, dup->name))) {
b878579ae7 424) dup->ce_flags |= CE_MATCHED;
b878579ae7 425) break;
b878579ae7 428) }
b878579ae7 488) mark_colliding_entries(state, ce, &st);

fsck.c
fb8952077d  214) die_errno("Could not read '%s'", path);

git.c
a9a60b94cc 322) fprintf_ln(stderr, _("'%s' is aliased to '%s'"),
c6d75bc17a 735) string_list_clear(&cmd_list, 0);

gpg-interface.c
4de9394dcb 155) break;

help.c
26c7d06783 help.c         500) static int get_alias(const char *var, 
const char *value, void *data)
26c7d06783 help.c         502) struct string_list *list = data;
26c7d06783 help.c         504) if (skip_prefix(var, "alias.", &var))
26c7d06783 help.c         505) string_list_append(list, var)->util = 
xstrdup(value);
26c7d06783 help.c         507) return 0;
26c7d06783 help.c         530) printf("\n%s\n", _("Command aliases"));
26c7d06783 help.c         531) ALLOC_ARRAY(aliases, alias_list.nr + 1);
26c7d06783 help.c         532) for (i = 0; i < alias_list.nr; i++) {
26c7d06783 help.c         533) aliases[i].name = alias_list.items[i].string;
26c7d06783 help.c         534) aliases[i].help = alias_list.items[i].util;
26c7d06783 help.c         535) aliases[i].category = 1;
26c7d06783 help.c         537) aliases[alias_list.nr].name = NULL;
26c7d06783 help.c         538) print_command_list(aliases, 1, longest);
26c7d06783 help.c         539) free(aliases);

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

ident.c
501afcb8b0 172) strbuf_addstr(&git_default_email, email);
501afcb8b0 173) free((char *)email);

list-objects-filter-options.c
bc5975d24f  55) if (errbuf) {
bc5975d24f  56) strbuf_addstr(
bc5975d24f  60) return 1;
cc0b05a4cc  86) if (errbuf)

list-objects-filter.c
list-objects.c
f447a499db 200) ctx->show_object(obj, base->buf, ctx->show_data);

ll-merge.c
d64324cb60 380) marker_size = DEFAULT_CONFLICT_MARKER_SIZE;

log-tree.c
4a7e27e957 477) if (oideq(&parent->item->object.oid, oid))

mailinfo.c
3aa4d81f88  992) len--;
3aa4d81f88  998) handle_filter(mi, prev);
3aa4d81f88  999) strbuf_reset(prev);
3aa4d81f88 1090) handle_filter(mi, &prev);

midx.c
4d80560c54   58) error_errno(_("failed to read %s"), midx_name);
4d80560c54   59) goto cleanup_fail;
4d80560c54   65) error(_("multi-pack-index file %s is too small"), 
midx_name);
4d80560c54   66) goto cleanup_fail;
0d5b3a5ef7  146) die(_("multi-pack-index missing required OID lookup 
chunk"));
662148c435  148) die(_("multi-pack-index missing required object offsets 
chunk"));
4d80560c54  173) munmap(midx_map, midx_size);
4d80560c54  175) close(fd);
1dcd9f2043  184) return;
3715a6335c  266) return 0;
fe1ed56f5e  413) warning(_("failed to open pack-index '%s'"),
fe1ed56f5e  415) close_pack(packs->list[packs->nr]);
fe1ed56f5e  416) FREE_AND_NULL(packs->list[packs->nr]);
fe1ed56f5e  417) return;
a40498a126  490) return 1;
fe1ed56f5e  507) die(_("failed to locate object %d in packfile"), 
cur_object);
fc59e74844  769) die_errno(_("unable to create leading directories of %s"),
525e18c04b  943) die(_("failed to clear multi-pack-index at %s"), midx);
56ee7ff156  969) return 0;
cc6af73c02 1010) midx_report(_("failed to load pack-index for packfile %s"),
cc6af73c02 1011)     e.p->pack_name);
cc6af73c02 1012) break;

name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

oidmap.c
cc00e5ce6b 11) return !oideq(&entry_->oid,

oidset.c
8b2f8cbcb1 29) kh_del_oid(&set->set, pos);
8b2f8cbcb1 30) return 1;

pack-bitmap.c
30cdc33fba 1130) return 0;

pack-objects.c
108f530385 172) REALLOC_ARRAY(pdata->tree_depth, pdata->nr_alloc);
fe0ac2fb7f 175) REALLOC_ARRAY(pdata->layer, pdata->nr_alloc);
108f530385 192) pdata->tree_depth[pdata->nr_objects - 1] = 0;
fe0ac2fb7f 195) pdata->layer[pdata->nr_objects - 1] = 0;

packfile.c
1127a98cce  117) return error("index file %s is too small", path);
1127a98cce  119) return error("empty data");
fe1ed56f5e  211) if (open_pack_index(p))
fe1ed56f5e  212) return 0;
fe1ed56f5e  213) level1_ofs = p->index_data;
17c35c8969  490) break;
17c35c8969  548) return 0;

preload-index.c
ae9af12287  63) struct progress_data *pd = p->progress;
ae9af12287  65) pthread_mutex_lock(&pd->mutex);
ae9af12287  66) pd->n += last_nr - nr;
ae9af12287  67) display_progress(pd->progress, pd->n);
ae9af12287  68) pthread_mutex_unlock(&pd->mutex);
ae9af12287  69) last_nr = nr;
ae9af12287  83) struct progress_data *pd = p->progress;
ae9af12287  85) pthread_mutex_lock(&pd->mutex);
ae9af12287  86) display_progress(pd->progress, pd->n + last_nr);
ae9af12287  87) pthread_mutex_unlock(&pd->mutex);
ae9af12287 118) pd.progress = start_delayed_progress(_("Refreshing 
index"), index->cache_nr);
ae9af12287 119) pthread_mutex_init(&pd.mutex, NULL);
ae9af12287 132) p->progress = &pd;
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
ae9af12287 1490) progress = start_delayed_progress(_("Refresh index"),
ae9af12287 1491)   istate->cache_nr);
ae9af12287 1539) display_progress(progress, i);
ae9af12287 1572) display_progress(progress, istate->cache_nr);
ae9af12287 1573) stop_progress(&progress);
252d079cbd 1784) const unsigned char *cp = (const unsigned char *)name;
252d079cbd 1788) strip_len = decode_varint(&cp);
77ff1127a4 1789) if (previous_ce) {
77ff1127a4 1790) previous_len = previous_ce->ce_namelen;
77ff1127a4 1791) if (previous_len < strip_len)
252d079cbd 1792) die(_("malformed name field in the index, near path '%s'"),
77ff1127a4 1793) previous_ce->name);
77ff1127a4 1794) copy_len = previous_len - strip_len;
252d079cbd 1796) name = (const char *)cp;
252d079cbd 1802) len += copy_len;
252d079cbd 1823) if (copy_len)
252d079cbd 1824) memcpy(ce->name, previous_ce->name, copy_len);
252d079cbd 1825) memcpy(ce->name + copy_len, name, len + 1 - copy_len);
252d079cbd 1826) *ent_size = (name - ((char *)ondisk)) + len + 1 - copy_len;
abb4bb8384 1959) munmap((void *)p->mmap, p->mmap_size);
abb4bb8384 1960) die(_("index file corrupt"));
77ff1127a4 2001) mem_pool_init(&istate->ce_mem_pool,
77ff1127a4 2039) static void *load_cache_entries_thread(void *_data)
77ff1127a4 2041) struct load_cache_entries_thread_data *p = _data;
77ff1127a4 2045) for (i = p->ieot_start; i < p->ieot_start + 
p->ieot_blocks; i++) {
77ff1127a4 2046) p->consumed += load_cache_entry_block(p->istate, 
p->ce_mem_pool,
77ff1127a4 2047) p->offset, p->ieot->entries[i].nr, p->mmap, 
p->ieot->entries[i].offset, NULL);
77ff1127a4 2048) p->offset += p->ieot->entries[i].nr;
77ff1127a4 2050) return NULL;
77ff1127a4 2053) static unsigned long load_cache_entries_threaded(struct 
index_state *istate, const char *mmap, size_t mmap_size,
77ff1127a4 2058) unsigned long consumed = 0;
77ff1127a4 2061) if (istate->name_hash_initialized)
77ff1127a4 2064) mem_pool_init(&istate->ce_mem_pool, 0);
77ff1127a4 2067) if (nr_threads > ieot->nr)
77ff1127a4 2068) nr_threads = ieot->nr;
77ff1127a4 2069) data = xcalloc(nr_threads, sizeof(*data));
77ff1127a4 2071) offset = ieot_start = 0;
77ff1127a4 2072) ieot_blocks = DIV_ROUND_UP(ieot->nr, nr_threads);
77ff1127a4 2073) for (i = 0; i < nr_threads; i++) {
77ff1127a4 2074) struct load_cache_entries_thread_data *p = &data[i];
77ff1127a4 2077) if (ieot_start + ieot_blocks > ieot->nr)
77ff1127a4 2078) ieot_blocks = ieot->nr - ieot_start;
77ff1127a4 2080) p->istate = istate;
77ff1127a4 2081) p->offset = offset;
77ff1127a4 2082) p->mmap = mmap;
77ff1127a4 2083) p->ieot = ieot;
77ff1127a4 2084) p->ieot_start = ieot_start;
77ff1127a4 2085) p->ieot_blocks = ieot_blocks;
77ff1127a4 2088) nr = 0;
77ff1127a4 2089) for (j = p->ieot_start; j < p->ieot_start + 
p->ieot_blocks; j++)
77ff1127a4 2090) nr += p->ieot->entries[j].nr;
77ff1127a4 2091) if (istate->version == 4) {
77ff1127a4 2092) mem_pool_init(&p->ce_mem_pool,
77ff1127a4 2095) mem_pool_init(&p->ce_mem_pool,
77ff1127a4 2099) err = pthread_create(&p->pthread, NULL, 
load_cache_entries_thread, p);
77ff1127a4 2100) if (err)
77ff1127a4 2101) die(_("unable to create load_cache_entries thread: 
%s"), strerror(err));
77ff1127a4 2104) for (j = 0; j < ieot_blocks; j++)
77ff1127a4 2105) offset += ieot->entries[ieot_start + j].nr;
77ff1127a4 2106) ieot_start += ieot_blocks;
77ff1127a4 2109) for (i = 0; i < nr_threads; i++) {
77ff1127a4 2110) struct load_cache_entries_thread_data *p = &data[i];
77ff1127a4 2112) err = pthread_join(p->pthread, NULL);
77ff1127a4 2113) if (err)
77ff1127a4 2114) die(_("unable to join load_cache_entries thread: %s"), 
strerror(err));
77ff1127a4 2115) mem_pool_combine(istate->ce_mem_pool, p->ce_mem_pool);
77ff1127a4 2116) consumed += p->consumed;
77ff1127a4 2119) free(data);
77ff1127a4 2121) return consumed;
abb4bb8384 2193) extension_offset = read_eoie_extension(mmap, mmap_size);
abb4bb8384 2194) if (extension_offset) {
abb4bb8384 2197) p.src_offset = extension_offset;
abb4bb8384 2198) err = pthread_create(&p.pthread, NULL, 
load_index_extensions, &p);
abb4bb8384 2199) if (err)
abb4bb8384 2200) die(_("unable to create load_index_extensions thread: 
%s"), strerror(err));
abb4bb8384 2202) nr_threads--;
77ff1127a4 2211) ieot = read_ieot_extension(mmap, mmap_size, 
extension_offset);
77ff1127a4 2214) src_offset += load_cache_entries_threaded(istate, mmap, 
mmap_size, src_offset, nr_threads, ieot);
77ff1127a4 2215) free(ieot);
abb4bb8384 2225) int ret = pthread_join(p.pthread, NULL);
abb4bb8384 2226) if (ret)
abb4bb8384 2227) die(_("unable to join load_index_extensions thread: 
%s"), strerror(ret));
3255089ada 2769) ieot_blocks = nr_threads;
77ff1127a4 2770) if (ieot_blocks > istate->cache_nr)
77ff1127a4 2771) ieot_blocks = istate->cache_nr;
3255089ada 2779) ieot = xcalloc(1, sizeof(struct index_entry_offset_table)
3255089ada 2780) + (ieot_blocks * sizeof(struct index_entry_offset)));
77ff1127a4 2781) ieot_entries = DIV_ROUND_UP(entries, ieot_blocks);
3255089ada 2787) free(ieot);
3b1d9e045e 2788) return -1;
3255089ada 2814) ieot->entries[ieot->nr].nr = nr;
3255089ada 2815) ieot->entries[ieot->nr].offset = offset;
3255089ada 2816) ieot->nr++;
3255089ada 2822) if (previous_name)
3255089ada 2823) previous_name->buf[0] = 0;
3255089ada 2824) nr = 0;
3255089ada 2825) offset = lseek(newfd, 0, SEEK_CUR);
3255089ada 2826) if (offset < 0) {
3255089ada 2827) free(ieot);
3255089ada 2828) return -1;
3255089ada 2830) offset += write_buffer_len;
3255089ada 2840) ieot->entries[ieot->nr].nr = nr;
3255089ada 2841) ieot->entries[ieot->nr].offset = offset;
3255089ada 2842) ieot->nr++;
3255089ada 2854) free(ieot);
3b1d9e045e 2855) return -1;
3255089ada 2868) struct strbuf sb = STRBUF_INIT;
3255089ada 2870) write_ieot_extension(&sb, ieot);
3255089ada 2871) err = write_index_ext_header(&c, &eoie_c, newfd, 
CACHE_EXT_INDEXENTRYOFFSETTABLE, sb.len) < 0
3255089ada 2872) || ce_write(&c, newfd, sb.buf, sb.len) < 0;
3255089ada 2873) strbuf_release(&sb);
3255089ada 2874) free(ieot);
3255089ada 2875) if (err)
3255089ada 2876) return -1;
3b1d9e045e 3363) static size_t read_eoie_extension(const char *mmap, 
size_t mmap_size)
3b1d9e045e 3381) if (mmap_size < sizeof(struct cache_header) + 
EOIE_SIZE_WITH_HEADER + the_hash_algo->rawsz)
3b1d9e045e 3382) return 0;
3b1d9e045e 3385) index = eoie = mmap + mmap_size - EOIE_SIZE_WITH_HEADER 
- the_hash_algo->rawsz;
3b1d9e045e 3386) if (CACHE_EXT(index) != CACHE_EXT_ENDOFINDEXENTRIES)
3b1d9e045e 3387) return 0;
3b1d9e045e 3388) index += sizeof(uint32_t);
3b1d9e045e 3391) extsize = get_be32(index);
3b1d9e045e 3392) if (extsize != EOIE_SIZE)
3b1d9e045e 3393) return 0;
3b1d9e045e 3394) index += sizeof(uint32_t);
3b1d9e045e 3400) offset = get_be32(index);
3b1d9e045e 3401) if (mmap + offset < mmap + sizeof(struct cache_header))
3b1d9e045e 3402) return 0;
3b1d9e045e 3403) if (mmap + offset >= eoie)
3b1d9e045e 3404) return 0;
3b1d9e045e 3405) index += sizeof(uint32_t);
3b1d9e045e 3416) src_offset = offset;
3b1d9e045e 3417) the_hash_algo->init_fn(&c);
3b1d9e045e 3418) while (src_offset < mmap_size - the_hash_algo->rawsz - 
EOIE_SIZE_WITH_HEADER) {
3b1d9e045e 3426) memcpy(&extsize, mmap + src_offset + 4, 4);
3b1d9e045e 3427) extsize = ntohl(extsize);
3b1d9e045e 3430) if (src_offset + 8 + extsize < src_offset)
3b1d9e045e 3431) return 0;
3b1d9e045e 3433) the_hash_algo->update_fn(&c, mmap + src_offset, 8);
3b1d9e045e 3435) src_offset += 8;
3b1d9e045e 3436) src_offset += extsize;
3b1d9e045e 3438) the_hash_algo->final_fn(hash, &c);
3b1d9e045e 3439) if (!hasheq(hash, (const unsigned char *)index))
3b1d9e045e 3440) return 0;
3b1d9e045e 3443) if (src_offset != mmap_size - the_hash_algo->rawsz - 
EOIE_SIZE_WITH_HEADER)
3b1d9e045e 3444) return 0;
3b1d9e045e 3446) return offset;
3255089ada 3465) static struct index_entry_offset_table 
*read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset)
3255089ada 3467)        const char *index = NULL;
3255089ada 3473)        if (!offset)
3255089ada 3474)        return NULL;
3255089ada 3475)        while (offset <= mmap_size - 
the_hash_algo->rawsz - 8) {
3255089ada 3476)        extsize = get_be32(mmap + offset + 4);
3255089ada 3477)        if (CACHE_EXT((mmap + offset)) == 
CACHE_EXT_INDEXENTRYOFFSETTABLE) {
3255089ada 3478)        index = mmap + offset + 4 + 4;
3255089ada 3479)        break;
3255089ada 3481)        offset += 8;
3255089ada 3482)        offset += extsize;
3255089ada 3484)        if (!index)
3255089ada 3485)        return NULL;
3255089ada 3488)        ext_version = get_be32(index);
3255089ada 3489)        if (ext_version != IEOT_VERSION) {
3255089ada 3490)        error("invalid IEOT version %d", ext_version);
3255089ada 3491)        return NULL;
3255089ada 3493)        index += sizeof(uint32_t);
3255089ada 3496)        nr = (extsize - sizeof(uint32_t)) / 
(sizeof(uint32_t) + sizeof(uint32_t));
3255089ada 3497)        if (!nr) {
3255089ada 3498)        error("invalid number of IEOT entries %d", nr);
3255089ada 3499)        return NULL;
3255089ada 3501)        ieot = xmalloc(sizeof(struct 
index_entry_offset_table)
3255089ada 3502)        + (nr * sizeof(struct index_entry_offset)));
3255089ada 3503)        ieot->nr = nr;
3255089ada 3504)        for (i = 0; i < nr; i++) {
3255089ada 3505)        ieot->entries[i].offset = get_be32(index);
3255089ada 3506)        index += sizeof(uint32_t);
3255089ada 3507)        ieot->entries[i].nr = get_be32(index);
3255089ada 3508)        index += sizeof(uint32_t);
3255089ada 3511)        return ieot;
3255089ada 3514) static void write_ieot_extension(struct strbuf *sb, 
struct index_entry_offset_table *ieot)
3255089ada 3520)        put_be32(&buffer, IEOT_VERSION);
3255089ada 3521)        strbuf_add(sb, &buffer, sizeof(uint32_t));
3255089ada 3524)        for (i = 0; i < ieot->nr; i++) {
3255089ada 3527)        put_be32(&buffer, ieot->entries[i].offset);
3255089ada 3528)        strbuf_add(sb, &buffer, sizeof(uint32_t));
3255089ada 3531)        put_be32(&buffer, ieot->entries[i].nr);
3255089ada 3532)        strbuf_add(sb, &buffer, sizeof(uint32_t));
3255089ada 3534) }

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

ref-filter.c
f0062d3b74 1039) v->s = xstrdup("");
f0062d3b74 1302) free((char *)to_free);
f0062d3b74 1303) return xstrdup("");
f0062d3b74 1340) free((char *)to_free);
f0062d3b74 1341) return xstrdup("");
f0062d3b74 1391) *s = xstrdup("=");
f0062d3b74 1393) *s = xstrdup("<");
f0062d3b74 1518) ref->symref = xstrdup("");
f0062d3b74 1587) v->s = xstrdup("");

refs.c
3a3b9d8cde  661) return 0;
4a6067cda5 1431) return 0;

refs/files-backend.c
refs/packed-backend.c
9001dc2a74 1163) } else if (!oideq(&update->old_oid, iter->oid)) {

refs/ref-cache.c
9001dc2a74 275) if (!oideq(&ref1->u.value.oid, &ref2->u.value.oid))

remote.c
85daa01f6b 1219) continue;
85daa01f6b 1225) continue;

rerere.c
2373b65059  217) die(_("corrupt MERGE_RR"));
2373b65059  226) die(_("corrupt MERGE_RR"));
2373b65059  229) die(_("corrupt MERGE_RR"));
2373b65059  264) die(_("unable to write rerere record"));
2373b65059  269) die(_("unable to write rerere record"));
4af32207bc  376) break;
4af32207bc  380) strbuf_addbuf(&two, &conflict);
c0f16f8e14  384) break;
c0f16f8e14  388) break;
c0f16f8e14  392) break;
2373b65059  480) return error_errno(_("could not open '%s'"), path);
2373b65059  485) error_errno(_("could not write '%s'"), output);
2373b65059  495) error(_("there were errors while writing '%s' (%s)"),
2373b65059  498) io.io.wrerror = error_errno(_("failed to flush '%s'"), 
path);
2373b65059  565) return error(_("index file corrupt"));
2373b65059  599) return error(_("index file corrupt"));
2373b65059  684) warning_errno(_("failed utime() on '%s'"),
2373b65059  690) return error_errno(_("could not open '%s'"), path);
2373b65059  692) error_errno(_("could not write '%s'"), path);
2373b65059  694) return error_errno(_("writing '%s' failed"), path);
2373b65059  720) die(_("unable to write new index file"));
2373b65059  803) die_errno(_("cannot unlink stray '%s'"), path);
2373b65059 1057) error(_("failed to update conflicted state in '%s'"), 
path);
2373b65059 1075) error(_("no remembered resolution for '%s'"), path);
2373b65059 1077) error_errno(_("cannot unlink '%s'"), filename);
2373b65059 1111) return error(_("index file corrupt"));
2373b65059 1199) die_errno(_("unable to open rr-cache directory"));

revision.c
2abf350385 1538) if (ce_path_match(istate, ce, &revs->prune_data, NULL)) {
2abf350385 1544) while ((i+1 < istate->cache_nr) &&
2abf350385 1545)        ce_same_name(ce, istate->cache[i+1]))
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3048) continue;
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;
4a7e27e957 3473)     oideq(&p->item->object.oid, &commit->object.oid))

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));
65850686cf 2329) return;
65850686cf 2426) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3427) return error(_("could not checkout %s"), commit);
4df66c40b0 3441) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3461) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4827) return -1;
b97e187364 4830) return -1;
b97e187364 4836) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4839) todo_list_release(&todo_list);
b97e187364 4840) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4859) todo_list_release(&todo_list);
b97e187364 4860) return -1;
b97e187364 4864) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4868) return error(_("could not transform the todo list"));
b97e187364 4897) return error(_("could not transform the todo list"));
b97e187364 4900) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4906) return -1;

setup.c
58b284a2e9  413) return config_error_nonbool(var);

sha1-file.c
67947c34ae sha1-file.c 2225) if (!hasheq(expected_sha1, real_sha1)) {

sha1-name.c
8aac67a174 sha1-name.c  162) return;

split-index.c
e3d837989e 335) ce->ce_flags |= CE_UPDATE_IN_BASE;

strbuf.c
f95736288a  127) --sb->len;

submodule-config.c
bcbc780d14 739) return CONFIG_INVALID_KEY;
45f5ef3d77 754) warning(_("Could not update .gitmodules entry %s"), key);

trace.c
c46c406ae1 189) now = getnanotime();
c46c406ae1 190) perf_start_times[perf_indent] = now;
c46c406ae1 191) if (perf_indent + 1 < ARRAY_SIZE(perf_start_times))
c46c406ae1 192) perf_indent++;
c46c406ae1 195) return now;
c46c406ae1 211) if (perf_indent >= strlen(space))
c46c406ae1 214) strbuf_addf(&buf, ":%.*s ", perf_indent, space);
c46c406ae1 317) void trace_performance_leave_fl(const char *file, int line,
c46c406ae1 323) if (perf_indent)
c46c406ae1 324) perf_indent--;
c46c406ae1 326) if (!format) /* Allow callers to leave without tracing 
anything */
c46c406ae1 327) return;
c46c406ae1 329) since = perf_start_times[perf_indent];
c46c406ae1 330) va_start(ap, format);
c46c406ae1 331) trace_performance_vprintf_fl(file, line, nanos - since, 
format, ap);
c46c406ae1 332) va_end(ap);
c46c406ae1 477) trace_performance_leave("git command:%s", command_line.buf);
c46c406ae1 485) if (!command_line.len)
c46c406ae1 490) trace_performance_enter();

transport.c
unpack-trees.c
b878579ae7  360) string_list_append(&list, ce->name);
b878579ae7  361) ce->ce_flags &= ~CE_MATCHED;
b878579ae7  368) warning(_("the following paths have collided (e.g. 
case-sensitive paths\n"
b878579ae7  372) for (i = 0; i < list.nr; i++)
b878579ae7  373) fprintf(stderr, "  '%s'\n", list.items[i].string);
f1e11c6510  777) free(tree_ce);
b4da37380b  778) return rc;
b4da37380b  785) printf("Unpacked %d entries from %s to %s using 
cache-tree\n",
b4da37380b  787)        o->src_index->cache[pos]->name,
b4da37380b  788)        o->src_index->cache[pos + nr_entries - 1]->name);

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wt-status.c
f3bd35fa0d  671) s->committable = 1;
73ba5d78b4 1958) if (s->state.rebase_in_progress ||
73ba5d78b4 1959)     s->state.rebase_interactive_in_progress)
73ba5d78b4 1960) branch_name = s->state.onto;
73ba5d78b4 1961) else if (s->state.detached_from)
73ba5d78b4 1962) branch_name = s->state.detached_from;

xdiff-interface.c
xdiff/xutils.c
611e42a598 405) return -1;

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      62c23938f: tests: add a special setup where 
rebase.useBuiltin is off
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Ben Peart      3255089ad: ieot: add Index Entry Offset Table (IEOT) 
extension
Ben Peart      3b1d9e045: eoie: add End of Index Entry (EOIE) extension
Ben Peart      77ff1127a: read-cache: load cache entries on worker threads
Ben Peart      abb4bb838: read-cache: load cache extensions on a worker 
thread
Ben Peart      c780b9cfe: config: add new index.threads config setting
Ben Peart      d1664e73a: add: speed up cmd_add() by utilizing 
read_cache_preload()
Ben Peart      fa655d841: checkout: optimize "git checkout -b <new_branch>"
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
brian m. carlson      2f0c9e9a9: builtin/repack: replace hard-coded 
constants
brian m. carlson      eccb5a5f3: apply: rename new_sha1_prefix and 
old_sha1_prefix
Christian Couder      108f53038: pack-objects: move tree_depth into 
'struct packing_data'
Christian Couder      fe0ac2fb7: pack-objects: move 'layer' into 'struct 
packing_data'
Derrick Stolee      0d5b3a5ef: midx: write object ids in a chunk
Derrick Stolee      17c35c896: packfile: skip loading index if in 
multi-pack-index
Derrick Stolee      1d614d41e: commit-reach: move ref_newer from remote.c
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      20fd6d579: commit-graph: not compatible with grafts
Derrick Stolee      3715a6335: midx: read objects from multi-pack-index
Derrick Stolee      454ea2e4d: treewide: use get_all_packs
Derrick Stolee      4d80560c5: multi-pack-index: load into memory
Derrick Stolee      4fbcca4ef: commit-reach: make can_all_from_reach... 
linear
Derrick Stolee      5227c3856: commit-reach: move walk methods from commit.c
Derrick Stolee      525e18c04: midx: clear midx on repack
Derrick Stolee      56ee7ff15: multi-pack-index: add 'verify' verb
Derrick Stolee      662148c43: midx: write object offsets
Derrick Stolee      66ec0390e: fsck: verify multi-pack-index
Derrick Stolee      6a22d5212: pack-objects: consider packs in 
multi-pack-index
Derrick Stolee      6cc017431: commit-reach: use can_all_from_reach
Derrick Stolee      6d68e6a46: multi-pack-index: provide more helpful 
usage info
Derrick Stolee      85daa01f6: remote: make add_missing_tags() linear
Derrick Stolee      8aac67a17: midx: use midx in abbreviation calculations
Derrick Stolee      a40498a12: midx: use existing midx when writing new one
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      b67f6b26e: commit-reach: properly peel tags
Derrick Stolee      cc6af73c0: multi-pack-index: verify object offsets
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Derrick Stolee      fc59e7484: midx: write header information to lockfile
Derrick Stolee      fe1ed56f5: midx: sort and deduplicate objects from 
packfiles
Duy Nguyen      b878579ae: clone: report duplicate entries on 
case-insensitive filesystems
Eric Sunshine      2e6fd71a5: format-patch: extend --range-diff to 
accept revision range
Eric Sunshine      40ce41604: format-patch: allow --range-diff to apply 
to a lone-patch
Eric Sunshine      68a6b3a1b: worktree: teach 'move' to override lock 
when --force given twice
Eric Sunshine      8631bf1cd: format-patch: add --creation-factor tweak 
for --range-diff
Eric Sunshine      e19831c94: worktree: teach 'add' to respect --force 
for registered but missing path
Eric Sunshine      e5353bef5: worktree: move delete_git_dir() earlier in 
file for upcoming new callers
Eric Sunshine      ee6cbf712: format-patch: allow --interdiff to apply 
to a lone-patch
Eric Sunshine      f4143101c: worktree: teach 'remove' to override lock 
when --force given twice
Jeff King      0074c9110: combine-diff: use an xdiff hunk callback
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      16d75fa48: repack: add delta-islands support
Jeff King      28b8a7308: pack-objects: add delta-islands support
Jeff King      2c8ee1f53: bundle: dup() output descriptor closer to 
point-of-use
Jeff King      2fa233a55: pack-objects: handle island check for 
"external" delta base
Jeff King      30cdc33fb: pack-bitmap: save "have" bitmap from walk
Jeff King      4a7e27e95: convert "oidcmp() == 0" to oideq()
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      611e42a59: xdiff: provide a separate emit callback for hunks
Jeff King      67947c34a: convert "hashcmp() != 0" to "!hasheq()"
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      8a2c17467: pathspec: handle non-terminated strings with 
:(attr)
Jeff King      9001dc2a7: convert "oidcmp() != 0" to "!oideq()"
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Jeff King      c27cc94fa: approxidate: handle pending number for "specials"
Jeff King      c8d521faf: Add delta-islands.{c,h}
Jeff King      cc00e5ce6: convert hashmap comparison functions to oideq()
Jeff King      fce566480: am: handle --no-patch-format option
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      3249c1251: rebase: consolidate clean-up code 
before leaving reset_head()
Johannes Schindelin      501afcb8b: mingw: use domain information for 
default email
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Johannes Schindelin      bac2a1e36: built-in rebase: reinstate `checkout 
-q` behavior where appropriate
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Jonathan Nieder      302997027: gc: do not return error for prior errors 
in daemonized mode
Jonathan Nieder      fec2ed218: gc: exit with status 128 on failure
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Josh Steadmon      1127a98cc: fuzz: add fuzz testing for packfile indices.
Matthew DeVore      7c0fe330d: rev-list: handle missing tree objects 
properly
Matthew DeVore      bc5975d24: list-objects-filter: implement filter tree:0
Matthew DeVore      cc0b05a4c: list-objects-filter-options: do not 
over-strbuf_init
Matthew DeVore      f447a499d: list-objects: store common func args in 
struct
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      252d079cb: read-cache.c: optimize reading 
index format v4
Nguyễn Thái Ngọc Duy      26c7d0678: help -a: improve and make --verbose 
default
Nguyễn Thái Ngọc Duy      2abf35038: revision.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      a470beea3: blame.c: rename "repo" argument to "r"
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      ae9af1228: status: show progress bar if 
refreshing the index takes too long
Nguyễn Thái Ngọc Duy      b29759d89: fsck: check HEAD and reflog from 
other worktrees
Nguyễn Thái Ngọc Duy      b4da37380: unpack-trees: optimize walking same 
trees with cache-tree
Nguyễn Thái Ngọc Duy      b78ea5fc3: diff.c: reduce implicit dependency 
on the_index
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      c46c406ae: trace.h: support nested performance 
tracing
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Nguyễn Thái Ngọc Duy      f1e11c651: unpack-trees: reduce malloc in 
cache-tree walk
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling
Olga Telezhnaya      f0062d3b7: ref-filter: free item->value and 
item->value->s
Phillip Wood      bcd33ec25: add read_author_script() to libgit
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue
Rasmus Villemoes      a9a60b94c: git.c: handle_alias: prepend alias info 
when first argument is -h
Rasmus Villemoes      e6e76baaf: help: redirect to aliased commands for 
"git cmd --help"
René Scharfe      3aa4d81f8: mailinfo: support format=flowed
René Scharfe      8b2f8cbcb: oidset: use khash
René Scharfe      fb8952077: fsck: use strbuf_getline() to read skiplist 
file
Shulhan      5025425df: builtin/remote: quote remote name on error to 
display empty name
Stefan Beller      4a6067cda: refs.c: migrate internal ref iteration to 
pass thru repository argument
Stefan Beller      74d4731da: submodule--helper: replace 
connect-gitdir-workingtree by ensure-core-worktree
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed
Stefan Beller      ee69b2a90: submodule--helper: introduce new 
update-module-mode helper
Stephen P. Smith      73ba5d78b: roll wt_status_state into wt_status and 
populate in the collect phase
Stephen P. Smith      f3bd35fa0: wt-status.c: set the committable flag 
in the collect phase
SZEDER Gábor      e3d837989: split-index: don't compare cached data of 
entries already marked for split index
Thomas Gummerer      2373b6505: rerere: mark strings for translation
Thomas Gummerer      4af32207b: rerere: teach rerere to handle nested 
conflicts
Thomas Gummerer      c0f16f8e1: rerere: factor out handle_conflict function
Tim Schumacher      c6d75bc17: alias: add support for aliases of an alias
Torsten Bögershausen      d64324cb6: Make git_check_attr() a void function


^ permalink raw reply	[relevance 3%]

* Git Test Coverage Report (Sunday, Nov 18th)
@ 2018-11-18 20:01  2% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-18 20:01 UTC (permalink / raw)
  To: git@vger.kernel.org

Here is the test coverage report for today.

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=257&view=logs

---


pu: d02f4432dcda003413023869ebe412f03155f230
jch: af77f5458d76b45843ab70c577a54db24b4ea92f
next: 6e8e63e21ad73680486866b4870b45db87c3d939
master: 26aa9fc81d4c7f6c3b456a29da0b7ec72e5c6595
master@{1}: d166e6afe5f257217836ef24a73764eba390c58d

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

protocol.c
24c10f7473  37) die(_("Unrecognized protocol version"));
24c10f7473  39) die(_("Unrecognized protocol_version"));

remote-curl.c
24c10f7473  403) return 0;

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule.c
e2419f7e30 1376) strbuf_release(&gitdir);
7454fe5cb6 1499) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1503) get_next_submodule_task_release(task);
7454fe5cb6 1530) return 0;
7454fe5cb6 1534) goto out;
7454fe5cb6 1549) return 0;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Josh Steadmon      24c10f747: protocol: advertise multiple supported 
versions
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/pull.c
88eeb24cb1 647) argv_array_push(&args, opt_cleanup);

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

sequencer.c
18e711a162 2387) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Denton Liu      88eeb24cb: merge: add scissors line on merge conflict
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths



Uncovered code in 'next' not in 'master'
--------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 420) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 459) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 583) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 618) fprintf_ln(stderr, _("Checking object 
directory"));
5215bd2f7d builtin/fsck.c 636) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
5215bd2f7d builtin/fsck.c 641) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 670) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 686) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pack-objects.c
ca473cef91 builtin/pack-objects.c 2086) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2087) oid_to_hex(&trg_entry->idx.oid), 
(uintmax_t)sz,
ca473cef91 builtin/pack-objects.c 2113) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2114) oid_to_hex(&src_entry->idx.oid), 
(uintmax_t)sz,

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
5215bd2f7d 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
5215bd2f7d 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
a965bb3116 1821) read_next_command();
ca473cef91 2816) strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2250) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2285) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3071) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3217) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  236) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2353) return error(_("option `%s' is incompatible with 
--no-merged"),

remote-curl.c
afa5d74929  359) die("invalid server response; expected service, got 
flush packet");

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2139) return r;

Commits introducing uncovered code:
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      afa5d7492: remote-curl: refactor smart-http discovery
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Junio C Hamano      5215bd2f7: Merge branch 'nd/i18n' into next
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option
Torsten Bögershausen      ca473cef9: Upcast size_t variables to 
uintmax_t when printing



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

apply.c
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

builtin/am.c
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/cat-file.c
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/grep.c
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/log.c
517fe807d6 builtin/log.c 1196) BUG_ON_OPT_NEG(unset);

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/rebase.c
62c23938fa   55) return env;
3249c1251e  556) ret = -1;
3249c1251e  557) goto leave_reset_head;
bac2a1e36f  561) ret = error(_("could not determine HEAD revision"));
bac2a1e36f  562) goto leave_reset_head;
3249c1251e  580) ret = error(_("could not read index"));
3249c1251e  581) goto leave_reset_head;
bac2a1e36f  585) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
bac2a1e36f  586) goto leave_reset_head;
3249c1251e  590) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
3249c1251e  591) goto leave_reset_head;
3249c1251e  604) goto leave_reset_head;

builtin/show-branch.c
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

bundle.c
2c8ee1f53c 267) error_errno(_("unable to dup bundle descriptor"));
2c8ee1f53c 268) child_process_clear(&pack_objects);
2c8ee1f53c 269) return -1;
2c8ee1f53c 478) rollback_lock_file(&lock);

config.c
midx.c
name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

preload-index.c
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

revision.c
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3048) continue;
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      62c23938f: tests: add a special setup where 
rebase.useBuiltin is off
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      2c8ee1f53: bundle: dup() output descriptor closer to 
point-of-use
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      fce566480: am: handle --no-patch-format option
Johannes Schindelin      3249c1251: rebase: consolidate clean-up code 
before leaving reset_head()
Johannes Schindelin      bac2a1e36: built-in rebase: reinstate `checkout 
-q` behavior where appropriate
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling



^ permalink raw reply	[relevance 2%]

* [ANNOUNCE] Git v2.20.0-rc0
@ 2018-11-18 14:20  2% Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-11-18 14:20 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

An early preview release Git v2.20.0-rc0 is now available for
testing at the usual places.  It is comprised of 887 non-merge
commits since v2.19.0, contributed by 71 people, 23 of which are
new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.20.0-rc0' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.19.0 are as follows.
Welcome to the Git development community!

  Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan
  Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis, David
  Zych, Frederick Eaton, James Knight, Jann Horn, Joshua Watt,
  Loo Rong Jie, Lucas De Marchi, Matthew DeVore, Mihir Mehta,
  Nickolai Belakovski, Roger Strain, Sam McKelvie, Saulius Gurklys,
  Shulhan, Steven Fernandez, Strain, Roger L, and Tim Schumacher.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Ævar Arnfjörð Bjarmason, Alban Gruin, Andreas Gruenbacher,
  Andreas Heiduk, Antonio Ospite, Ben Peart, Brandon Williams,
  brian m. carlson, Christian Couder, Christian Hesse, Denton Liu,
  Derrick Stolee, Elijah Newren, Eric Sunshine, Jeff Hostetler,
  Jeff King, Johannes Schindelin, Johannes Sixt, Jonathan Nieder,
  Jonathan Tan, Josh Steadmon, Junio C Hamano, Karsten Blees,
  Luke Diamand, Martin Ågren, Max Kirillov, Michael Witten,
  Michał Górny, Nguyễn Thái Ngọc Duy, Noam Postavsky,
  Olga Telezhnaya, Phillip Wood, Pratik Karki, Rafael Ascensão,
  Ralf Thielow, Ramsay Jones, Rasmus Villemoes, René Scharfe,
  Sebastian Staudt, Stefan Beller, Stephen P. Smith, Steve Hoelzer,
  SZEDER Gábor, Tao Qingyun, Taylor Blau, Thomas Gummerer,
  Torsten Bögershausen, and Uwe Kleine-König.

----------------------------------------------------------------

Git Release Notes
=========================

Backward Compatibility Notes
----------------------------

 * "git branch -l <foo>" used to be a way to ask a reflog to be
   created while creating a new branch, but that is no longer the
   case.  It is a short-hand for "git branch --list <foo>" now.

 * "git push" into refs/tags/* hierarchy is rejected without getting
   forced, but "git fetch" (misguidedly) used the "fast forwarding"
   rule used for the refs/heads/* hierarchy; this has been corrected,
   which means some fetches of tags that did not fail with older
   version of Git will fail without "--force" with this version.

 * "git help -a" now gives verbose output (same as "git help -av").
   Those who want the old output may say "git help --no-verbose -a"..

 * "git cpn --help", when "cpn" is an alias to, say, "cherry-pick -n",
   reported only the alias expansion of "cpn" in earlier versions of
   Git.  It now runs "git cherry-pick --help" to show the manual page
   of the command, while sending the alias expansion to the standard
   error stream.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by". This is a backward-incompatible
   change.  Adding "--suppress-cc=misc-by" on the command line, or
   setting sendemail.suppresscc configuration variable to "misc-by",
   can be used to disable this behaviour.


Updates since v2.19
-------------------

UI, Workflows & Features

 * Running "git clone" against a project that contain two files with
   pathnames that differ only in cases on a case insensitive
   filesystem would result in one of the files lost because the
   underlying filesystem is incapable of holding both at the same
   time.  An attempt is made to detect such a case and warn.

 * "git checkout -b newbranch [HEAD]" should not have to do as much as
   checking out a commit different from HEAD.  An attempt is made to
   optimize this special case.

 * "git rev-list --stdin </dev/null" used to be an error; it now shows
   no output without an error.  "git rev-list --stdin --default HEAD"
   still falls back to the given default when nothing is given on the
   standard input.

 * Lift code from GitHub to restrict delta computation so that an
   object that exists in one fork is not made into a delta against
   another object that does not appear in the same forked repository.

 * "git format-patch" learned new "--interdiff" and "--range-diff"
   options to explain the difference between this version and the
   previous attempt in the cover letter (or after the three-dashes as
   a comment).

 * "git mailinfo" used in "git am" learned to make a best-effort
   recovery of a patch corrupted by MUA that sends text/plain with
   format=flawed option.
   (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).

 * The rules used by "git push" and "git fetch" to determine if a ref
   can or cannot be updated were inconsistent; specifically, fetching
   to update existing tags were allowed even though tags are supposed
   to be unmoving anchoring points.  "git fetch" was taught to forbid
   updates to existing tags without the "--force" option.

 * "git multi-pack-index" learned to detect corruption in the .midx
   file it uses, and this feature has been integrated into "git fsck".

 * Generation of (experimental) commit-graph files have so far been
   fairly silent, even though it takes noticeable amount of time in a
   meaningfully large repository.  The users will now see progress
   output.

 * The minimum version of Windows supported by Windows port of Git is
   now set to Vista.

 * The completion script (in contrib/) learned to complete a handful of
   options "git stash list" command takes.

 * The completion script (in contrib/) learned that "git fetch
   --multiple" only takes remote names as arguments and no refspecs.

 * "git status" learns to show progress bar when refreshing the index
   takes a long time.
   (merge ae9af12287 nd/status-refresh-progress later to maint).

 * "git help -a" and "git help -av" give different pieces of
   information, and generally the "verbose" version is more friendly
   to the new users.  "git help -a" by default now uses the more
   verbose output (with "--no-verbose", you can go back to the
   original).  Also "git help -av" now lists aliases and external
   commands, which it did not used to.

 * Unlike "grep", "git grep" by default recurses to the whole tree.
   The command learned "git grep --recursive" option, so that "git
   grep --no-recursive" can serve as a synonym to setting the
   max-depth to 0.

 * When pushing into a repository that borrows its objects from an
   alternate object store, "git receive-pack" that responds to the
   push request on the other side lists the tips of refs in the
   alternate to reduce the amount of objects transferred.  This
   sometimes is detrimental when the number of refs in the alternate
   is absurdly large, in which case the bandwidth saved in potentially
   fewer objects transferred is wasted in excessively large ref
   advertisement.  The alternate refs that are advertised are now
   configurable with a pair of configuration variables.

 * "git cmd --help" when "cmd" is aliased used to only say "cmd is
   aliased to ...".  Now it shows that to the standard error stream
   and runs "git $cmd --help" where $cmd is the first word of the
   alias expansion.

 * The documentation of "git gc" has been updated to mention that it
   is no longer limited to "pruning away crufts" but also updates
   ancillary files like commit-graph as a part of repository
   optimization.

 * "git p4 unshelve" improvements.

 * The logic to select the default user name and e-mail on Windows has
   been improved.
   (merge 501afcb8b0 js/mingw-default-ident later to maint).

 * The "rev-list --filter" feature learned to exclude all trees via
   "tree:0" filter.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by"; --suppress-cc=misc-by on the
   command line, or setting sendemail.suppresscc configuration
   variable to "misc-by", can be used to disable this behaviour.

 * Developer builds now uses -Wunused-function compilation option.

 * One of our CI tests to run with "unusual/experimental/random"
   settings now also uses commit-graph and midx.

 * "git mergetool" learned to take the "--[no-]gui" option, just like
   "git difftool" does.

 * "git rebase -i" learned a new insn, 'break', that the user can
   insert in the to-do list.  Upon hitting it, the command returns
   control back to the user.

 * New "--pretty=format:" placeholders %GF and %GP that show the GPG
   key fingerprints have been invented.

 * On platforms with recent cURL library, http.sslBackend configuration
   variable can be used to choose a different SSL backend at runtime.
   The Windows port uses this mechanism to switch between OpenSSL and
   Secure Channel while talking over the HTTPS protocol.

 * "git send-email" learned to disable SMTP authentication via the
   "--smtp-auth=none" option, even when the smtp username is given
   (which turns the authentication on by default).

 * A fourth class of configuration files (in addition to the
   traditional "system wide", "per user in the $HOME directory" and
   "per repository in the $GIT_DIR/config") has been introduced so
   that different worktrees that share the same repository (hence the
   same $GIT_DIR/config file) can use different customization.

 * A pattern with '**' that does not have a slash on either side used
   to be an invalid one, but the code now treats such double-asterisks
   the same way as two normal asterisks that happen to be adjacent to
   each other.
   (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).

 * The "--no-patch" option, which can be used to get a high-level
   overview without the actual line-by-line patch difference shown, of
   the "range-diff" command was earlier broken, which has been
   corrected.

 * The recently merged "rebase in C" has an escape hatch to use the
   scripted version when necessary, but it hasn't been documented,
   which has been corrected.


Performance, Internal Implementation, Development Support etc.

 * When there are too many packfiles in a repository (which is not
   recommended), looking up an object in these would require
   consulting many pack .idx files; a new mechanism to have a single
   file that consolidates all of these .idx files is introduced.

 * "git submodule update" is getting rewritten piece-by-piece into C.

 * The code for computing history reachability has been shuffled,
   obtained a bunch of new tests to cover them, and then being
   improved.

 * The unpack_trees() API used in checking out a branch and merging
   walks one or more trees along with the index.  When the cache-tree
   in the index tells us that we are walking a tree whose flattened
   contents is known (i.e. matches a span in the index), as linearly
   scanning a span in the index is much more efficient than having to
   open tree objects recursively and listing their entries, the walk
   can be optimized, which has been done.

 * When creating a thin pack, which allows objects to be made into a
   delta against another object that is not in the resulting pack but
   is known to be present on the receiving end, the code learned to
   take advantage of the reachability bitmap; this allows the server
   to send a delta against a base beyond the "boundary" commit.

 * spatch transformation to replace boolean uses of !hashcmp() to
   newly introduced oideq() is added, and applied, to regain
   performance lost due to support of multiple hash algorithms.

 * Fix a bug in which the same path could be registered under multiple
   worktree entries if the path was missing (for instance, was removed
   manually).  Also, as a convenience, expand the number of cases in
   which --force is applicable.

 * Split Documentation/config.txt for easier maintenance.
   (merge 6014363f0b nd/config-split later to maint).

 * Test helper binaries clean-up.
   (merge c9a1f4161f nd/test-tool later to maint).

 * Various tests have been updated to make it easier to swap the
   hash function used for object identification.
   (merge ae0c89d41b bc/hash-independent-tests later to maint).

 * Update fsck.skipList implementation and documentation.
   (merge 371a655074 ab/fsck-skiplist later to maint).

 * An alias that expands to another alias has so far been forbidden,
   but now it is allowed to create such an alias.

 * Various test scripts have been updated for style and also correct
   handling of exit status of various commands.

 * "gc --auto" ended up calling exit(-1) upon error, which has been
   corrected to use exit(1).  Also the error reporting behaviour when
   daemonized has been updated to exit with zero status when stopping
   due to a previously discovered error (which implies there is no
   point running gc to improve the situation); we used to exit with
   failure in such a case.

 * Various codepaths in the core-ish part learned to work on an
   arbitrary in-core index structure, not necessarily the default
   instance "the_index".
   (merge b3c7eef9b0 nd/the-index later to maint).

 * Code clean-up in the internal machinery used by "git status" and
   "git commit --dry-run".
   (merge 73ba5d78b4 ss/wt-status-committable later to maint).

 * Some environment variables that control the runtime options of Git
   used during tests are getting renamed for consistency.
   (merge 4231d1ba99 bp/rename-test-env-var later to maint).

 * A new extension to the index file has been introduced, which allows
   the index file to be read in parallel for performance.

 * The oidset API was built on top of the oidmap API which in turn is
   on the hashmap API.  Replace the implementation to build on top of
   the khash API and gain performance.

 * Over some transports, fetching objects with an exact commit object
   name can be done without first seeing the ref advertisements.  The
   code has been optimized to exploit this.

 * In a partial clone that will lazily be hydrated from the
   originating repository, we generally want to avoid "does this
   object exist (locally)?" on objects that we deliberately omitted
   when we created the clone.  The cache-tree codepath (which is used
   to write a tree object out of the index) however insisted that the
   object exists, even for paths that are outside of the partial
   checkout area.  The code has been updated to avoid such a check.

 * To help developers, an EditorConfig file that attempts to follow
   the project convention has been added.
   (merge b548d698a0 bc/editorconfig later to maint).

 * The result of coverage test can be combined with "git blame" to
   check the test coverage of code introduced recently with a new
   'coverage-diff' tool (in contrib/).
   (merge 783faedd65 ds/coverage-diff later to maint).

 * An experiment to fuzz test a few areas, hopefully we can gain more
   coverage to various areas.

 * More codepaths are moving away from hardcoded hash sizes.

 * The way the Windows port figures out the current directory has been
   improved.

 * The way DLLs are loaded on the Windows port has been improved.

 * Some tests have been reorganized and renamed; "ls t/" now gives a
   better overview of what is tested for these scripts than before.

 * "git rebase" and "git rebase -i" have been reimplemented in C.

 * Windows port learned to use nano-second resolution file timestamps.

 * The overly large Documentation/config.txt file have been split into
   million little pieces.  This potentially allows each individual piece
   included into the manual page of the command it affects more easily.

 * Replace three string-list instances used as look-up tables in "git
   fetch" with hashmaps.

 * Unify code to read the author-script used in "git am" and the
   commands that use the sequencer machinery, e.g. "git rebase -i".

 * In preparation to the day when we can deprecate and remove the
   "rebase -p", make sure we can skip and later remove tests for
   it.

 * The history traversal used to implement the tag-following has been
   optimized by introducing a new helper.

 * The helper function to refresh the cached stat information in the
   in-core index has learned to perform the lstat() part of the
   operation in parallel on multi-core platforms.

 * The code to traverse objects for reachability, used to decide what
   objects are unreferenced and expendable, have been taught to also
   consider per-worktree refs of other worktrees as starting points to
   prevent data loss.

 * "git add" needs to internally run "diff-files" equivalent, and the
   codepath learned the same optimization as "diff-files" has to run
   lstat(2) in parallel to find which paths have been updated in the
   working tree.

 * The procedure to install dependencies before testing at Travis CI
   is getting revamped for both simplicity and flexibility, taking
   advantage of the recent move to the vm-based environment.

 * The support for format-patch (and send-email) by the command-line
   completion script (in contrib/) has been simplified a bit.

 * The revision walker machinery learned to take advantage of the
   commit generation numbers stored in the commit-graph file.

 * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".

 * The way -lcurl library gets linked has been simplified by taking
   advantage of the fact that we can just ask curl-config command how.

 * Various functions have been audited for "-Wunused-parameter" warnings
   and bugs in them got fixed.

 * A sanity check for start-up sequence has been added in the config
   API codepath.

 * The build procedure to link for fuzzing test has been made
   customizable with a new Makefile variable.

 * The way "git rebase" parses and forwards the command line options
   meant for underlying "git am" has been revamped, which fixed for
   options with parameters that were not passed correctly.


Fixes since v2.19
-----------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.
   (merge 66e83d9b41 jk/trailer-fixes later to maint).

 * Malformed or crafted data in packstream can make our code attempt
   to read or write past the allocated buffer and abort, instead of
   reporting an error, which has been fixed.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.
   (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.
   (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.
   (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).

 * Further fix for O_APPEND emulation on Windows
   (merge eeaf7ddac7 js/mingw-o-append later to maint).

 * A corner case bugfix in "git rerere" code.
   (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.
   (merge 84d938b732 nd/attr-pathspec-fix later to maint).

 * Recent update broke the reachability algorithm when refs (e.g.
   tags) that point at objects that are not commit were involved,
   which has been fixed.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.
   (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.
   (merge e68302011c jt/lazy-object-fetch-fix later to maint).

 * Update error messages given by "git remote" and make them consistent.
   (merge 5025425dff ms/remote-error-message-update later to maint).

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.
   (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.
   (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.
   (merge 829a321569 ds/commit-graph-with-grafts later to maint).

 * The mailmap file update.
   (merge 255eb03edf jn/mailmap-update later to maint).

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.
   (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).

 * "git fetch $repo $object" in a partial clone did not correctly
   fetch the asked-for object that is referenced by an object in
   promisor packfile, which has been fixed.

 * A corner-case bugfix.
   (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).

 * Various fixes to "diff --color-moved-ws".

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.
   (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.
   (merge 4c490f3d32 sg/split-index-racefix later to maint).

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.
   (merge 04005834ed np/log-graph-octopus-fix later to maint).

 * "git range-diff" did not work well when the compared ranges had
   changes in submodules and the "--submodule=log" was used.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.
   (merge f67b980771 jk/run-command-notdot later to maint).

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.
   (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.
   (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.
   (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).

 * The logic to determine the archive type "git archive" uses did not
   correctly kick in for "git archive --remote", which has been
   corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.
   (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).

 * Some codepaths failed to form a proper URL when .gitmodules record
   the URL to a submodule repository as relative to the repository of
   superproject, which has been corrected.
   (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).

 * "git fetch" over protocol v2 into a shallow repository failed to
   fetch full history behind a new tip of history that was diverged
   before the cut-off point of the history that was previously fetched
   shallowly.

 * The command line completion machinery (in contrib/) has been
   updated to allow the completion script to tweak the list of options
   that are reported by the parse-options machinery correctly.
   (merge 276b49ff34 nd/completion-negation later to maint).

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.
   (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.
   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.
   (merge a5f52c6dab sg/test-verbose-log later to maint).

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.
   (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).

 * "git ls-remote $there foo" was broken by recent update for the
   protocol v2 and stopped showing refs that match 'foo' that are not
   refs/{heads,tags}/foo, which has been fixed.
   (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).

 * Additional comment on a tricky piece of code to help developers.
   (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).

 * A couple of tests used to leave the repository in a state that is
   deliberately corrupt, which have been corrected.
   (merge aa984dbe5e ab/pack-tests-cleanup later to maint).

 * The submodule support has been updated to read from the blob at
   HEAD:.gitmodules when the .gitmodules file is missing from the
   working tree.
   (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).

 * "git fetch" was a bit loose in parsing responses from the other side
   when talking over the protocol v2.

 * "git rev-parse --exclude=* --branches --branches"  (i.e. first
   saying "add only things that do not match '*' out of all branches"
   and then adding all branches, without any exclusion this time")
   worked as expected, but "--exclude=* --all --all" did not work the
   same way, which has been fixed.
   (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).

 * "git send-email --transfer-encoding=..." in recent versions of Git
   sometimes produced an empty "Content-Transfer-Encoding:" header,
   which has been corrected.
   (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).

 * The interface into "xdiff" library used to discover the offset and
   size of a generated patch hunk by first formatting it into the
   textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
   out.  A new interface has been introduced to allow callers a more
   direct access to them.
   (merge 5eade0746e jk/xdiff-interface later to maint).

 * Pathspec matching against a tree object were buggy when negative
   pathspec elements were involved, which has been fixed.
   (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).

 * "git merge" and "git pull" that merges into an unborn branch used
   to completely ignore "--verify-signatures", which has been
   corrected.
   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).

 * "git rebase --autostash" did not correctly re-attach the HEAD at times.

 * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
   quite work, which has been corrected.
   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).

 * When editing a patch in a "git add -i" session, a hunk could be
   made to no-op.  The "git apply" program used to reject a patch with
   such a no-op hunk to catch user mistakes, but it is now updated to
   explicitly allow a no-op hunk in an edited patch.
   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).

 * The URL to an MSDN page in a comment has been updated.
   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).

 * "git ls-remote --sort=<thing>" can feed an object that is not yet
   available into the comparison machinery and segfault, which has
   been corrected to check such a request upfront and reject it.

 * When "git bundle" aborts due to an empty commit ranges
   (i.e. resulting in an empty pack), it left a file descriptor to an
   lockfile open, which resulted in leftover lockfile on Windows where
   you cannot remove a file with an open file descriptor.  This has
   been corrected.
   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).

 * Code cleanup, docfix, build fix, etc.
   (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
   (merge b9b07efdb2 tg/conflict-marker-size later to maint).
   (merge fa0aeea770 sg/doc-trace-appends later to maint).
   (merge d64324cb60 tb/void-check-attr later to maint).
   (merge c3b9bc94b9 en/double-semicolon-fix later to maint).
   (merge 79336116f5 sg/t3701-tighten-trace later to maint).
   (merge 801fa63a90 jk/dev-build-format-security later to maint).
   (merge 0597dd62ba sb/string-list-remove-unused later to maint).
   (merge db2d36fad8 bw/protocol-v2 later to maint).
   (merge 456d7cd3a9 sg/split-index-test later to maint).
   (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).
   (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).
   (merge 55f6bce2c9 fe/doc-updates later to maint).
   (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).
   (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).
   (merge 4c399442f7 ma/commit-graph-docs later to maint).
   (merge fc0503b04e ma/t1400-undebug-test later to maint).
   (merge e56b53553a nd/packobjectshook-doc-fix later to maint).
   (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).
   (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).
   (merge ad0b8f9575 mw/doc-typofixes later to maint).
   (merge d9f079ad1a jc/how-to-document-api later to maint).
   (merge b1492bf315 ma/t7005-bash-workaround later to maint).
   (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).
   (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).
   (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).
   (merge 61018fe9e0 du/cherry-is-plumbing later to maint).
   (merge c7e5fe79b9 sb/strbuf-h-update later to maint).
   (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).
   (merge 2e3c894f4b tq/branch-style-fix later to maint).
   (merge c5d844af9c sg/doc-show-branch-typofix later to maint).
   (merge 081d91618b ah/doc-updates later to maint).
   (merge b84c783882 jc/cocci-preincr later to maint).
   (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).
   (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).
   (merge 3063477445 tb/char-may-be-unsigned later to maint).
   (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
   (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).

----------------------------------------------------------------

Changes since v2.19.0 are as follows:

Aaron Lindsay (1):
      send-email: avoid empty transfer encoding header

Alban Gruin (21):
      sequencer: make three functions and an enum from sequencer.c public
      rebase -i: rewrite append_todo_help() in C
      editor: add a function to launch the sequence editor
      rebase -i: rewrite the edit-todo functionality in C
      sequencer: add a new function to silence a command, except if it fails
      rebase -i: rewrite setup_reflog_action() in C
      rebase -i: rewrite checkout_onto() in C
      sequencer: refactor append_todo_help() to write its message to a buffer
      sequencer: change the way skip_unnecessary_picks() returns its result
      t3404: todo list with commented-out commands only aborts
      rebase -i: rewrite complete_action() in C
      rebase -i: remove unused modes and functions
      rebase -i: implement the logic to initialize $revisions in C
      rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C
      rebase -i: rewrite write_basic_state() in C
      rebase -i: rewrite init_basic_state() in C
      rebase -i: implement the main part of interactive rebase as a builtin
      rebase--interactive2: rewrite the submodes of interactive rebase in C
      rebase -i: remove git-rebase--interactive.sh
      rebase -i: move rebase--helper modes to rebase--interactive
      p3400: replace calls to `git checkout -b' by `git checkout -B'

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Andreas Gruenbacher (1):
      rev-parse: clear --exclude list after 'git rev-parse --all'

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Anton Serbulov (1):
      mingw: fix getcwd when the parent directory cannot be queried

Antonio Ospite (10):
      submodule: add a print_config_from_gitmodules() helper
      submodule: factor out a config_set_in_gitmodules_file_gently function
      t7411: merge tests 5 and 6
      t7411: be nicer to future tests and really clean things up
      submodule--helper: add a new 'config' subcommand
      submodule: use the 'submodule--helper config' command
      t7506: clean up .gitmodules properly before setting up new scenario
      submodule: add a helper to check if it is safe to write to .gitmodules
      submodule: support reading .gitmodules when it's not in the working tree
      t/helper: add test-submodule-nested-repo-config

Ben Peart (19):
      checkout: optimize "git checkout -b <new_branch>"
      git-mv: allow submodules and fsmonitor to work together
      t/README: correct spelling of "uncommon"
      preload-index: use git_env_bool() not getenv() for customization
      fsmonitor: update GIT_TEST_FSMONITOR support
      read-cache: update TEST_GIT_INDEX_VERSION support
      preload-index: update GIT_FORCE_PRELOAD_TEST support
      read-cache: clean up casting and byte decoding
      eoie: add End of Index Entry (EOIE) extension
      config: add new index.threads config setting
      read-cache: load cache extensions on a worker thread
      ieot: add Index Entry Offset Table (IEOT) extension
      read-cache: load cache entries on worker threads
      reset: don't compute unstaged changes after reset when --quiet
      reset: add new reset.quiet config setting
      reset: warn when refresh_index() takes more than 2 seconds
      speed up refresh_index() by utilizing preload_index()
      add: speed up cmd_add() by utilizing read_cache_preload()
      refresh_index: remove unnecessary calls to preload_index()

Brandon Williams (1):
      config: document value 2 for protocol.version

Brendan Forster (1):
      http: add support for disabling SSL revocation checks in cURL

Carlo Marcelo Arenas Belón (8):
      unpack-trees: avoid dead store for struct progress
      multi-pack-index: avoid dead store for struct progress
      read-cache: use of memory after it is freed
      commit-slabs: move MAYBE_UNUSED out
      khash: silence -Wunused-function for delta-islands
      compat: make sure git_mmap is not expected to write
      sequencer: cleanup for gcc warning in non developer mode
      builtin/notes: remove unnecessary free

Christian Couder (3):
      pack-objects: refactor code into compute_layer_order()
      pack-objects: move tree_depth into 'struct packing_data'
      pack-objects: move 'layer' into 'struct packing_data'

Christian Hesse (2):
      subtree: add build targets 'man' and 'html'
      subtree: make install targets depend on build targets

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Denton Liu (3):
      mergetool: accept -g/--[no-]gui as arguments
      completion: support `git mergetool --[no-]gui`
      doc: document diff/merge.guitool config keys

Derrick Stolee (92):
      multi-pack-index: add design document
      multi-pack-index: add format details
      multi-pack-index: add builtin
      multi-pack-index: add 'write' verb
      midx: write header information to lockfile
      multi-pack-index: load into memory
      t5319: expand test data
      packfile: generalize pack directory list
      multi-pack-index: read packfile list
      multi-pack-index: write pack names in chunk
      midx: read pack names into array
      midx: sort and deduplicate objects from packfiles
      midx: write object ids in a chunk
      midx: write object id fanout chunk
      midx: write object offsets
      config: create core.multiPackIndex setting
      midx: read objects from multi-pack-index
      midx: use midx in abbreviation calculations
      midx: use existing midx when writing new one
      midx: use midx in approximate_object_count
      midx: prevent duplicate packfile loads
      packfile: skip loading index if in multi-pack-index
      midx: clear midx on repack
      commit-reach: move walk methods from commit.c
      commit.h: remove method declarations
      commit-reach: move ref_newer from remote.c
      commit-reach: move commit_contains from ref-filter
      upload-pack: make reachable() more generic
      upload-pack: refactor ok_to_give_up()
      upload-pack: generalize commit date cutoff
      commit-reach: move can_all_from_reach_with_flags
      test-reach: create new test tool for ref_newer
      test-reach: test in_merge_bases
      test-reach: test is_descendant_of
      test-reach: test get_merge_bases_many
      test-reach: test reduce_heads
      test-reach: test can_all_from_reach_with_flags
      test-reach: test commit_contains
      commit-reach: replace ref_newer logic
      commit-reach: make can_all_from_reach... linear
      commit-reach: use can_all_from_reach
      multi-pack-index: provide more helpful usage info
      multi-pack-index: store local property
      midx: mark bad packed objects
      midx: stop reporting garbage
      midx: fix bug that skips midx with alternates
      packfile: add all_packs list
      treewide: use get_all_packs
      midx: test a few commands that use get_all_packs
      pack-objects: consider packs in multi-pack-index
      commit-graph: update design document
      test-repository: properly init repo
      commit-graph: not compatible with replace objects
      commit-graph: not compatible with grafts
      commit-graph: not compatible with uninitialized repo
      commit-graph: close_commit_graph before shallow walk
      commit-graph: define GIT_TEST_COMMIT_GRAPH
      t3206-range-diff.sh: cover single-patch case
      t5318: use test_oid for HASH_LEN
      multi-pack-index: add 'verify' verb
      multi-pack-index: verify bad header
      multi-pack-index: verify corrupt chunk lookup table
      multi-pack-index: verify packname order
      multi-pack-index: verify missing pack
      multi-pack-index: verify oid fanout order
      multi-pack-index: verify oid lookup order
      multi-pack-index: fix 32-bit vs 64-bit size check
      multi-pack-index: verify object offsets
      multi-pack-index: report progress during 'verify'
      fsck: verify multi-pack-index
      commit-reach: properly peel tags
      commit-reach: fix memory and flag leaks
      commit-reach: cleanups in can_all_from_reach...
      commit-graph: clean up leaked memory during write
      commit-graph: reduce initial oid allocation
      midx: fix broken free() in close_midx()
      contrib: add coverage-diff script
      ci: add optional test variables
      commit-reach: fix first-parent heuristic
      midx: close multi-pack-index on repack
      multi-pack-index: define GIT_TEST_MULTI_PACK_INDEX
      packfile: close multi-pack-index in close_all_packs
      prio-queue: add 'peek' operation
      test-reach: add run_three_modes method
      test-reach: add rev-list tests
      revision.c: begin refactoring --topo-order logic
      commit/revisions: bookkeeping before refactoring
      revision.c: generation-based topo-order algorithm
      t6012: make rev-list tests more interesting
      commit-reach: implement get_reachable_subset
      test-reach: test get_reachable_subset
      remote: make add_missing_tags() linear

Elijah Newren (14):
      Remove superfluous trailing semicolons
      t4200: demonstrate rerere segfault on specially crafted merge
      rerere: avoid buffer overrun
      update-ref: fix type of update_flags variable to match its usage
      update-ref: allow --no-deref with --stdin
      sequencer: fix --allow-empty-message behavior, make it smarter
      merge-recursive: set paths correctly when three-way merging content
      merge-recursive: avoid wrapper function when unnecessary and wasteful
      merge-recursive: remove final remaining caller of merge_file_one()
      merge-recursive: rename merge_file_1() and merge_content()
      commit: fix erroneous BUG, 'multiple renames on the same target? how?'
      merge-recursive: improve auto-merging messages with path collisions
      merge-recursive: avoid showing conflicts with merge branch before HEAD
      fsck: move fsck_head_link() to get_default_heads() to avoid some globals

Eric Sunshine (26):
      format-patch: allow additional generated content in make_cover_letter()
      format-patch: add --interdiff option to embed diff in cover letter
      format-patch: teach --interdiff to respect -v/--reroll-count
      interdiff: teach show_interdiff() to indent interdiff
      log-tree: show_log: make commentary block delimiting reusable
      format-patch: allow --interdiff to apply to a lone-patch
      range-diff: respect diff_option.file rather than assuming 'stdout'
      range-diff: publish default creation factor
      range-diff: relieve callers of low-level configuration burden
      format-patch: add --range-diff option to embed diff in cover letter
      format-patch: extend --range-diff to accept revision range
      format-patch: teach --range-diff to respect -v/--reroll-count
      format-patch: add --creation-factor tweak for --range-diff
      format-patch: allow --range-diff to apply to a lone-patch
      worktree: don't die() in library function find_worktree()
      worktree: move delete_git_dir() earlier in file for upcoming new callers
      worktree: generalize delete_git_dir() to reduce code duplication
      worktree: prepare for more checks of whether path can become worktree
      worktree: disallow adding same path multiple times
      worktree: teach 'add' to respect --force for registered but missing path
      worktree: teach 'move' to override lock when --force given twice
      worktree: teach 'remove' to override lock when --force given twice
      worktree: delete .git/worktrees if empty after 'remove'
      doc-diff: fix non-portable 'man' invocation
      doc-diff: add --clean mode to remove temporary working gunk
      doc/Makefile: drop doc-diff worktree and temporary files on "make clean"

Frederick Eaton (3):
      git-archimport.1: specify what kind of Arch we're talking about
      git-column.1: clarify initial description, provide examples
      git-describe.1: clarify that "human readable" is also git-readable

James Knight (1):
      build: link with curl-defined linker flags

Jann Horn (2):
      patch-delta: fix oob read
      patch-delta: consistently report corruption

Jeff Hostetler (2):
      t0051: test GIT_TRACE to a windows named pipe
      mingw: fix mingw_open_append to work with named pipes

Jeff King (94):
      branch: make "-l" a synonym for "--list"
      Add delta-islands.{c,h}
      pack-objects: add delta-islands support
      repack: add delta-islands support
      t5320: tests for delta islands
      t/perf: factor boilerplate out of test_perf
      t/perf: factor out percent calculations
      t/perf: add infrastructure for measuring sizes
      t/perf: add perf tests for fetches from a bitmapped server
      pack-bitmap: save "have" bitmap from walk
      pack-objects: reuse on-disk deltas for thin "have" objects
      SubmittingPatches: mention doc-diff
      rev-list: make empty --stdin not an error
      trailer: use size_t for string offsets
      trailer: use size_t for iterating trailer list
      trailer: pass process_trailer_opts to trailer_info_get()
      interpret-trailers: tighten check for "---" patch boundary
      interpret-trailers: allow suppressing "---" divider
      pretty, ref-filter: format %(trailers) with no_divider option
      sequencer: ignore "---" divider when parsing trailers
      append_signoff: use size_t for string offsets
      coccinelle: use <...> for function exclusion
      introduce hasheq() and oideq()
      convert "oidcmp() == 0" to oideq()
      convert "hashcmp() == 0" to hasheq()
      convert "oidcmp() != 0" to "!oideq()"
      convert "hashcmp() != 0" to "!hasheq()"
      convert hashmap comparison functions to oideq()
      read-cache: use oideq() in ce_compare functions
      show_dirstat: simplify same-content check
      doc-diff: always use oids inside worktree
      test-delta: read input into a heap buffer
      t5303: test some corrupt deltas
      patch-delta: handle truncated copy parameters
      t5303: use printf to generate delta bases
      doc/git-branch: remove obsolete "-l" references
      bitmap_has_sha1_in_uninteresting(): drop BUG check
      t5310: test delta reuse with bitmaps
      traverse_bitmap_commit_list(): don't free result
      pack-bitmap: drop "loaded" flag
      reopen_tempfile(): truncate opened file
      doc-diff: force worktree add
      config.mak.dev: add -Wformat-security
      pack-objects: handle island check for "external" delta base
      receive-pack: update comment with check_everything_connected
      submodule--helper: use "--" to signal end of clone options
      submodule-config: ban submodule urls that start with dash
      submodule-config: ban submodule paths that start with a dash
      fsck: detect submodule urls starting with dash
      fsck: detect submodule paths starting with dash
      more oideq/hasheq conversions
      transport: drop refnames from for_each_alternate_ref
      test-tool: show tool list on error
      config.mak.dev: enable -Wunused-function
      run-command: mark path lookup errors with ENOENT
      t5410: use longer path for sample script
      upload-pack: fix broken if/else chain in config callback
      t1450: check large blob in trailing-garbage test
      check_stream_sha1(): handle input underflow
      cat-file: handle streaming failures consistently
      ls-remote: do not send ref prefixes for patterns
      ls-remote: pass heads/tags prefixes to transport
      read_istream_pack_non_delta(): document input handling
      xdiff: provide a separate emit callback for hunks
      xdiff-interface: provide a separate consume callback for hunks
      rev-list: handle flags for --indexed-objects
      approxidate: handle pending number for "specials"
      pathspec: handle non-terminated strings with :(attr)
      diff: avoid generating unused hunk header lines
      diff: discard hunk headers for patch-ids earlier
      diff: use hunk callback for word-diff
      combine-diff: use an xdiff hunk callback
      diff: convert --check to use a hunk callback
      range-diff: use a hunk callback
      xdiff-interface: drop parse_hunk_header()
      apply: mark include/exclude options as NONEG
      am: handle --no-patch-format option
      ls-files: mark exclude options as NONEG
      pack-objects: mark index-version option as NONEG
      cat-file: mark batch options with NONEG
      status: mark --find-renames option with NONEG
      format-patch: mark "--no-numbered" option with NONEG
      show-branch: mark --reflog option as NONEG
      tag: mark "--message" option with NONEG
      cat-file: report an error on multiple --batch options
      apply: return -1 from option callback instead of calling exit(1)
      parse-options: drop OPT_DATE()
      assert NOARG/NONEG behavior of parse-options callbacks
      midx: double-check large object write loop
      merge: extract verify_merge_signature() helper
      merge: handle --verify-signatures for unborn branch
      pull: handle --verify-signatures for unborn branch
      approxidate: fix NULL dereference in date_time()
      bundle: dup() output descriptor closer to point-of-use

Johannes Schindelin (55):
      rebase -i --autosquash: demonstrate a problem skipping the last squash
      rebase -i: be careful to wrap up fixup/squash chains
      compat/poll: prepare for targeting Windows Vista
      mingw: set _WIN32_WINNT explicitly for Git for Windows
      mingw: bump the minimum Windows version to Vista
      builtin rebase: prepare for builtin rebase -i
      rebase -i: clarify what happens on a failed `exec`
      rebase -i: introduce the 'break' command
      getpwuid(mingw): initialize the structure only once
      getpwuid(mingw): provide a better default for the user name
      mingw: use domain information for default email
      http: add support for selecting SSL backends at runtime
      pack-objects: fix typo 'detla' -> 'delta'
      pack-objects (mingw): demonstrate a segmentation fault with large deltas
      pack-objects (mingw): initialize `packing_data` mutex in the correct spot
      rebase (autostash): avoid duplicate call to state_dir_path()
      rebase (autostash): store the full OID in <state-dir>/autostash
      rebase (autostash): use an explicit OID to apply the stash
      mingw: factor out code to set stat() data
      rebase --autostash: demonstrate a problem with dirty submodules
      rebase --autostash: fix issue with dirty submodules
      mingw: load system libraries the recommended way
      mingw: ensure `getcwd()` reports the correct case
      repack: point out a bug handling stale shallow info
      shallow: offer to prune only non-existing entries
      repack -ad: prune the list of shallow commits
      http: when using Secure Channel, ignore sslCAInfo by default
      t7800: fix quoting
      mingw: reencode environment variables on the fly (UTF-16 <-> UTF-8)
      config: rename `dummy` parameter to `cb` in git_default_config()
      config: allow for platform-specific core.* config settings
      config: move Windows-specific config settings into compat/mingw.c
      mingw: unset PERL5LIB by default
      mingw: fix isatty() after dup2()
      t3404: decouple some test cases from outcomes of previous test cases
      t3418: decouple test cases from a previous `rebase -p` test case
      tests: optionally skip `git rebase -p` tests
      Windows: force-recompile git.res for differing architectures
      built-in rebase: demonstrate regression with --autostash
      built-in rebase --autostash: leave the current branch alone if possible
      Update .mailmap
      rebase -r: demonstrate bug with conflicting merges
      rebase -r: do not write MERGE_HEAD unless needed
      rebase -i: include MERGE_HEAD into files to clean up
      built-in rebase --skip/--abort: clean up stale .git/<name> files
      status: rebase and merge can be in progress at the same time
      apply --recount: allow "no-op hunks"
      rebase: consolidate clean-up code before leaving reset_head()
      rebase: prepare reset_head() for more flags
      built-in rebase: reinstate `checkout -q` behavior where appropriate
      mingw: use `CreateHardLink()` directly
      rebase: really just passthru the `git am` options
      rebase: validate -C<n> and --whitespace=<mode> parameters early
      config: report a bug if git_dir exists without commondir
      mingw: replace an obsolete link with the superseding one

Johannes Sixt (3):
      diff: don't attempt to strip prefix from absolute Windows paths
      rebase -i: recognize short commands without arguments
      t3404-rebase-interactive: test abbreviated commands

Jonathan Nieder (6):
      gc: improve handling of errors reading gc.log
      gc: exit with status 128 on failure
      gc: do not return error for prior errors in daemonized mode
      commit-reach: correct accidental #include of C file
      mailmap: consistently normalize brian m. carlson's name
      git doc: direct bug reporters to mailing list archive

Jonathan Tan (15):
      fetch-object: unify fetch_object[s] functions
      fetch-object: set exact_oid when fetching
      connected: document connectivity in partial clones
      fetch: in partial clone, check presence of targets
      fetch-pack: avoid object flags if no_dependents
      fetch-pack: exclude blobs when lazy-fetching trees
      transport: allow skipping of ref listing
      transport: do not list refs if possible
      transport: list refs before fetch if necessary
      fetch: do not list refs if fetching only hashes
      cache-tree: skip some blob checks in partial clone
      upload-pack: make have_obj not global
      upload-pack: make want_obj not global
      upload-pack: clear flags before each v2 request
      fetch-pack: be more precise in parsing v2 response

Josh Steadmon (4):
      fuzz: add basic fuzz testing target.
      fuzz: add fuzz testing for packfile indices.
      archive: initialize archivers earlier
      Makefile: use FUZZ_CXXFLAGS for linking fuzzers

Joshua Watt (1):
      send-email: explicitly disable authentication

Junio C Hamano (29):
      Revert "doc/Makefile: drop doc-diff worktree and temporary files on "make clean""
      Initial batch post 2.19
      Second batch post 2.19
      Git 2.14.5
      Git 2.15.3
      Git 2.16.5
      Git 2.17.2
      Git 2.18.1
      Git 2.19.1
      t0000: do not get self-test disrupted by environment warnings
      CodingGuidelines: document the API in *.h files
      Declare that the next one will be named 2.20
      Third batch for 2.20
      rebase: fix typoes in error messages
      Fourth batch for 2.20
      Revert "subtree: make install targets depend on build targets"
      Fifth batch for 2.20
      receive: denyCurrentBranch=updateinstead should not blindly update
      cocci: simplify "if (++u > 1)" to "if (u++)"
      fsck: s/++i > 1/i++/
      http: give curl version warnings consistently
      Sixth batch for 2.20
      Seventh batch for 2.20
      fetch: replace string-list used as a look-up table with a hashmap
      rebase: apply cocci patch
      Eighth batch for 2.20
      Ninth batch for 2.20
      Tenth batch for 2.20
      Git 2.20-rc0

Karsten Blees (2):
      mingw: replace MSVCRT's fstat() with a Win32-based implementation
      mingw: implement nanosecond-precision file times

Loo Rong Jie (1):
      win32: replace pthread_cond_*() with much simpler code

Lucas De Marchi (1):
      range-diff: allow to diff files regardless of submodule config

Luke Diamand (3):
      git-p4: do not fail in verbose mode for missing 'fileSize' key
      git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved
      git-p4: fully support unshelving changelists

Martin Ågren (9):
      Doc: use `--type=bool` instead of `--bool`
      git-config.txt: fix 'see: above' note
      git-commit-graph.txt: fix bullet lists
      git-commit-graph.txt: typeset more in monospace
      git-commit-graph.txt: refer to "*commit*-graph file"
      Doc: refer to the "commit-graph file" with dash
      t1400: drop debug `echo` to actually execute `test`
      builtin/commit-graph.c: UNLEAK variables
      sequencer: break out of loop explicitly

Matthew DeVore (19):
      list-objects: store common func args in struct
      list-objects: refactor to process_tree_contents
      list-objects: always parse trees gently
      t/README: reformat Do, Don't, Keep in mind lists
      Documentation: add shell guidelines
      tests: standardize pipe placement
      t/*: fix ordering of expected/observed arguments
      tests: don't swallow Git errors upstream of pipes
      t9109: don't swallow Git errors upstream of pipes
      tests: order arguments to git-rev-list properly
      rev-list: handle missing tree objects properly
      revision: mark non-user-given objects instead
      list-objects-filter: use BUG rather than die
      list-objects-filter-options: do not over-strbuf_init
      list-objects-filter: implement filter tree:0
      filter-trees: code clean-up of tests
      list-objects: support for skipping tree traversal
      Documentation/git-log.txt: do not show --exclude-promisor-objects
      exclude-promisor-objects: declare when option is allowed

Max Kirillov (1):
      http-backend test: make empty CONTENT_LENGTH test more realistic

Michael Witten (3):
      docs: typo: s/go/to/
      docs: graph: remove unnecessary `graph_update()' call
      docs: typo: s/isimilar/similar/

Michał Górny (6):
      gpg-interface.c: detect and reject multiple signatures on commits
      gpg-interface.c: use flags to determine key/signer info presence
      gpg-interface.c: support getting key fingerprint via %GF format
      gpg-interface.c: obtain primary key fingerprint as well
      t/t7510-signed-commit.sh: Add %GP to custom format checks
      t/t7510-signed-commit.sh: add signing subkey to Eris Discordia key

Mihir Mehta (1):
      doc: fix a typo and clarify a sentence

Nguyễn Thái Ngọc Duy (166):
      clone: report duplicate entries on case-insensitive filesystems
      trace.h: support nested performance tracing
      unpack-trees: add performance tracing
      unpack-trees: optimize walking same trees with cache-tree
      unpack-trees: reduce malloc in cache-tree walk
      unpack-trees: reuse (still valid) cache-tree from src_index
      unpack-trees: add missing cache invalidation
      cache-tree: verify valid cache-tree in the test suite
      Document update for nd/unpack-trees-with-cache-tree
      bisect.c: make show_list() build again
      t/helper: keep test-tool command list sorted
      t/helper: merge test-dump-untracked-cache into test-tool
      t/helper: merge test-pkt-line into test-tool
      t/helper: merge test-parse-options into test-tool
      t/helper: merge test-dump-fsmonitor into test-tool
      Makefile: add a hint about TEST_BUILTINS_OBJS
      config.txt: follow camelCase naming
      config.txt: move fetch part out to a separate file
      config.txt: move format part out to a separate file
      config.txt: move gitcvs part out to a separate file
      config.txt: move gui part out to a separate file
      config.txt: move pull part out to a separate file
      config.txt: move push part out to a separate file
      config.txt: move receive part out to a separate file
      config.txt: move sendemail part out to a separate file
      config.txt: move sequence.editor out of "core" part
      config.txt: move submodule part out to a separate file
      archive.c: remove implicit dependency the_repository
      status: show progress bar if refreshing the index takes too long
      add: do not accept pathspec magic 'attr'
      completion: support "git fetch --multiple"
      read-cache.c: remove 'const' from index_has_changes()
      diff.c: reduce implicit dependency on the_index
      combine-diff.c: remove implicit dependency on the_index
      blame.c: rename "repo" argument to "r"
      diff.c: remove the_index dependency in textconv() functions
      grep.c: remove implicit dependency on the_index
      diff.c: remove implicit dependency on the_index
      read-cache.c: remove implicit dependency on the_index
      diff-lib.c: remove implicit dependency on the_index
      ll-merge.c: remove implicit dependency on the_index
      merge-blobs.c: remove implicit dependency on the_index
      merge.c: remove implicit dependency on the_index
      patch-ids.c: remove implicit dependency on the_index
      sha1-file.c: remove implicit dependency on the_index
      rerere.c: remove implicit dependency on the_index
      userdiff.c: remove implicit dependency on the_index
      line-range.c: remove implicit dependency on the_index
      submodule.c: remove implicit dependency on the_index
      tree-diff.c: remove implicit dependency on the_index
      ws.c: remove implicit dependency on the_index
      revision.c: remove implicit dependency on the_index
      revision.c: reduce implicit dependency the_repository
      read-cache.c: optimize reading index format v4
      config.txt: correct the note about uploadpack.packObjectsHook
      help -a: improve and make --verbose default
      refs.c: indent with tabs, not spaces
      Add a place for (not) sharing stuff between worktrees
      submodule.c: remove some of the_repository references
      completion: fix __gitcomp_builtin no longer consider extra options
      t1300: extract and use test_cmp_config()
      worktree: add per-worktree config files
      refs: new ref types to make per-worktree refs visible to all worktrees
      revision.c: correct a parameter name
      revision.c: better error reporting on ref from different worktrees
      fsck: check HEAD and reflog from other worktrees
      reflog expire: cover reflog from all worktrees
      Update makefile in preparation for Documentation/config/*.txt
      config.txt: move advice.* to a separate file
      config.txt: move core.* to a separate file
      config.txt: move add.* to a separate file
      config.txt: move alias.* to a separate file
      config.txt: move am.* to a separate file
      config.txt: move apply.* to a separate file
      config.txt: move blame.* to a separate file
      config.txt: move branch.* to a separate file
      config.txt: move browser.* to a separate file
      config.txt: move checkout.* to a separate file
      config.txt: move clean.* to a separate file
      config.txt: move color.* to a separate file
      config.txt: move column.* to a separate file
      config.txt: move commit.* to a separate file
      config.txt: move credential.* to a separate file
      config.txt: move completion.* to a separate file
      config.txt: move diff-config.txt to config/
      config.txt: move difftool.* to a separate file
      config.txt: move fastimport.* to a separate file
      config.txt: move fetch-config.txt to config/
      config.txt: move filter.* to a separate file
      config.txt: move format-config.txt to config/
      config.txt: move fmt-merge-msg-config.txt to config/
      config.txt: move fsck.* to a separate file
      config.txt: move gc.* to a separate file
      config.txt: move gitcvs-config.txt to config/
      config.txt: move gitweb.* to a separate file
      config.txt: move grep.* to a separate file
      config.txt: move gpg.* to a separate file
      config.txt: move gui-config.txt to config/
      config.txt: move guitool.* to a separate file
      config.txt: move help.* to a separate file
      config.txt: move ssh.* to a separate file
      config.txt: move http.* to a separate file
      config.txt: move i18n.* to a separate file
      git-imap-send.txt: move imap.* to a separate file
      config.txt: move index.* to a separate file
      config.txt: move init.* to a separate file
      config.txt: move instaweb.* to a separate file
      config.txt: move interactive.* to a separate file
      config.txt: move log.* to a separate file
      config.txt: move mailinfo.* to a separate file
      config.txt: move mailmap.* to a separate file
      config.txt: move man.* to a separate file
      config.txt: move merge-config.txt to config/
      config.txt: move mergetool.* to a separate file
      config.txt: move notes.* to a separate file
      config.txt: move pack.* to a separate file
      config.txt: move pager.* to a separate file
      config.txt: move pretty.* to a separate file
      config.txt: move protocol.* to a separate file
      config.txt: move pull-config.txt to config/
      config.txt: move push-config.txt to config/
      config.txt: move rebase-config.txt to config/
      config.txt: move receive-config.txt to config/
      config.txt: move remote.* to a separate file
      config.txt: move remotes.* to a separate file
      config.txt: move repack.* to a separate file
      config.txt: move rerere.* to a separate file
      config.txt: move reset.* to a separate file
      config.txt: move sendemail-config.txt to config/
      config.txt: move sequencer.* to a separate file
      config.txt: move showBranch.* to a separate file
      config.txt: move splitIndex.* to a separate file
      config.txt: move status.* to a separate file
      config.txt: move stash.* to a separate file
      config.txt: move submodule.* to a separate file
      config.txt: move tag.* to a separate file
      config.txt: move transfer.* to a separate file
      config.txt: move uploadarchive.* to a separate file
      config.txt: move uploadpack.* to a separate file
      config.txt: move url.* to a separate file
      config.txt: move user.* to a separate file
      config.txt: move versionsort.* to a separate file
      config.txt: move web.* to a separate file
      config.txt: move worktree.* to a separate file
      config.txt: remove config/dummy.txt
      thread-utils: macros to unconditionally compile pthreads API
      wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode
      git-worktree.txt: correct linkgit command name
      sequencer.c: remove a stray semicolon
      tree-walk.c: fix overoptimistic inclusion in :(exclude) matching
      run-command.h: include thread-utils.h instead of pthread.h
      send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c
      index-pack: remove #ifdef NO_PTHREADS
      name-hash.c: remove #ifdef NO_PTHREADS
      attr.c: remove #ifdef NO_PTHREADS
      grep: remove #ifdef NO_PTHREADS
      grep: clean up num_threads handling
      preload-index.c: remove #ifdef NO_PTHREADS
      pack-objects: remove #ifdef NO_PTHREADS
      read-cache.c: remove #ifdef NO_PTHREADS
      read-cache.c: reduce branching based on HAVE_THREADS
      read-cache.c: initialize copy_len to shut up gcc 8
      Clean up pthread_create() error handling
      completion: use __gitcomp_builtin for format-patch
      build: fix broken command-list.h generation with core.autocrlf
      doc: move extensions.worktreeConfig to the right place

Nickolai Belakovski (2):
      worktree: update documentation for lock_reason and lock_reason_valid
      worktree: rename is_worktree_locked to worktree_lock_reason

Noam Postavsky (1):
      log: fix coloring of certain octopus merge shapes

Olga Telezhnaya (3):
      ref-filter: free memory from used_atom
      ls-remote: release memory instead of UNLEAK
      ref-filter: free item->value and item->value->s

Phillip Wood (11):
      diff: fix --color-moved-ws=allow-indentation-change
      diff --color-moved-ws: fix double free crash
      diff --color-moved-ws: fix out of bounds string access
      diff --color-moved-ws: fix a memory leak
      diff --color-moved-ws: fix another memory leak
      diff --color-moved: fix a memory leak
      am: don't die in read_author_script()
      am: improve author-script error reporting
      am: rename read_author_script()
      add read_author_script() to libgit
      sequencer: use read_author_script()

Pratik Karki (46):
      rebase: start implementing it as a builtin
      rebase: refactor common shell functions into their own file
      builtin/rebase: support running "git rebase <upstream>"
      builtin rebase: support --onto
      builtin rebase: support `git rebase --onto A...B`
      builtin rebase: handle the pre-rebase hook and --no-verify
      builtin rebase: support --quiet
      builtin rebase: support the `verbose` and `diffstat` options
      builtin rebase: require a clean worktree
      builtin rebase: try to fast forward when possible
      builtin rebase: support --force-rebase
      builtin rebase: start a new rebase only if none is in progress
      builtin rebase: only store fully-qualified refs in `options.head_name`
      builtin rebase: support `git rebase <upstream> <switch-to>`
      builtin rebase: support --continue
      builtin rebase: support --skip
      builtin rebase: support --abort
      builtin rebase: support --quit
      builtin rebase: support --edit-todo and --show-current-patch
      builtin rebase: actions require a rebase in progress
      builtin rebase: stop if `git am` is in progress
      builtin rebase: allow selecting the rebase "backend"
      builtin rebase: support --signoff
      builtin rebase: support --rerere-autoupdate
      builtin rebase: support --committer-date-is-author-date
      builtin rebase: support `ignore-whitespace` option
      builtin rebase: support `ignore-date` option
      builtin rebase: support `keep-empty` option
      builtin rebase: support `--autosquash`
      builtin rebase: support `--gpg-sign` option
      builtin rebase: support `-C` and `--whitespace=<type>`
      builtin rebase: support `--autostash` option
      builtin rebase: support `--exec`
      builtin rebase: support `--allow-empty-message` option
      builtin rebase: support --rebase-merges[=[no-]rebase-cousins]
      merge-base --fork-point: extract libified function
      builtin rebase: support `fork-point` option
      builtin rebase: add support for custom merge strategies
      builtin rebase: support --root
      builtin rebase: optionally auto-detect the upstream
      builtin rebase: optionally pass custom reflogs to reset_head()
      builtin rebase: fast-forward to onto if it is a proper descendant
      builtin rebase: show progress when connected to a terminal
      builtin rebase: use no-op editor when interactive is "implied"
      builtin rebase: error out on incompatible option/mode combinations
      rebase: default to using the builtin rebase

Rafael Ascensão (2):
      refs: show --exclude failure with --branches/tags/remotes=glob
      refs: fix some exclude patterns being ignored

Ralf Thielow (1):
      git-rebase.sh: fix typos in error messages

Ramsay Jones (12):
      Makefile: add a hdr-check target
      json-writer.h: add missing include (hdr-check)
      ewah/ewok_rlw.h: add missing include (hdr-check)
      refs/ref-cache.h: add missing declarations (hdr-check)
      refs/packed-backend.h: add missing declaration (hdr-check)
      refs/refs-internal.h: add missing declarations (hdr-check)
      midx.h: add missing forward declarations (hdr-check)
      delta-islands.h: add missing forward declarations (hdr-check)
      headers: normalize the spelling of some header guards
      fetch-object.h: add missing declaration (hdr-check)
      ewok_rlw.h: add missing 'inline' to function definition
      commit-reach.h: add missing declarations (hdr-check)

Rasmus Villemoes (6):
      help: redirect to aliased commands for "git cmd --help"
      git.c: handle_alias: prepend alias info when first argument is -h
      git-help.txt: document "git help cmd" vs "git cmd --help" for aliases
      Documentation/git-send-email.txt: style fixes
      send-email: only consider lines containing @ or <> for automatic Cc'ing
      send-email: also pick up cc addresses from -by trailers

René Scharfe (12):
      mailinfo: support format=flowed
      fsck: add a performance test for skipList
      fsck: use strbuf_getline() to read skiplist file
      fsck: use oidset instead of oid_array for skipList
      sequencer: use return value of oidset_insert()
      grep: add -r/--[no-]recursive
      fetch-pack: factor out is_unmatched_ref()
      fetch-pack: load tip_oids eagerly iff needed
      khash: factor out kh_release_*
      oidset: use khash
      oidset: uninline oidset_init()
      commit-reach: fix cast in compare_commits_by_gen()

Roger Strain (1):
      subtree: performance improvement for finding unexpected parent commits

SZEDER Gábor (16):
      t1404: increase core.packedRefsTimeout to avoid occasional test failure
      Documentation/git.txt: clarify that GIT_TRACE=/path appends
      t3701-add-interactive: tighten the check of trace output
      t1700-split-index: drop unnecessary 'grep'
      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
      t1700-split-index: document why FSMONITOR is disabled in this test script
      split-index: add tests to demonstrate the racy split index problem
      t1700-split-index: date back files to avoid racy situations
      split-index: count the number of deleted entries
      split-index: don't compare cached data of entries already marked for split index
      split-index: smudge and add racily clean cache entries to split index
      split-index: BUG() when cache entry refers to non-existing shared entry
      object_id.cocci: match only expressions of type 'struct object_id'
      test-lib: introduce the '-V' short option for '--verbose-log'
      travis-ci: install packages in 'ci/install-dependencies.sh'
      ref-filter: don't look for objects when outside of a repository

Sam McKelvie (1):
      rev-parse: --show-superproject-working-tree should work during a merge

Saulius Gurklys (1):
      doc: fix small typo in git show-branch

Sebastian Staudt (1):
      travis-ci: no longer use containers

Shulhan (1):
      builtin/remote: quote remote name on error to display empty name

Stefan Beller (25):
      git-submodule.sh: align error reporting for update mode to use path
      git-submodule.sh: rename unused variables
      builtin/submodule--helper: factor out submodule updating
      builtin/submodule--helper: store update_clone information in a struct
      builtin/submodule--helper: factor out method to update a single submodule
      submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
      submodule--helper: introduce new update-module-mode helper
      test_decode_color: understand FAINT and ITALIC
      t3206: add color test for range-diff --dual-color
      diff.c: simplify caller of emit_line_0
      diff.c: reorder arguments for emit_line_ws_markup
      diff.c: add set_sign to emit_line_0
      diff: use emit_line_0 once per line
      diff.c: omit check for line prefix in emit_line_0
      diff.c: rewrite emit_line_0 more understandably
      diff.c: add --output-indicator-{new, old, context}
      range-diff: make use of different output indicators
      range-diff: indent special lines as context
      refs.c: migrate internal ref iteration to pass thru repository argument
      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
      string-list: remove unused function print_string_list
      strbuf.h: format according to coding guidelines
      diff.c: pass sign_index to emit_line_ws_markup
      submodule helper: convert relative URL to absolute URL if needed
      builtin/submodule--helper: remove debugging leftover tracing

Stephen P. Smith (10):
      wt-status.c: move has_unmerged earlier in the file
      wt-status: rename commitable to committable
      t7501: add test of "commit --dry-run --short"
      wt-status.c: set the committable flag in the collect phase
      roll wt_status_state into wt_status and populate in the collect phase
      t2000: rename and combine checkout clash tests
      t7509: cleanup description and filename
      t7502: rename commit test script to comply with naming convention
      t7500: rename commit tests script to comply with naming convention
      t7501: rename commit test to comply with naming convention

Steve Hoelzer (1):
      poll: use GetTickCount64() to avoid wrap-around issues

Steven Fernandez (1):
      git-completion.bash: add completion for stash list

Strain, Roger L (4):
      subtree: refactor split of a commit into standalone method
      subtree: make --ignore-joins pay attention to adds
      subtree: use commits before rejoins for splits
      subtree: improve decision on merges kept in split

Tao Qingyun (3):
      refs: docstring typo
      builtin/branch.c: remove useless branch_get
      branch: trivial style fix

Taylor Blau (4):
      transport.c: extract 'fill_alternate_refs_command'
      transport.c: introduce core.alternateRefsCommand
      transport.c: introduce core.alternateRefsPrefixes
      Documentation/config.txt: fix typo in core.alternateRefsCommand

Thomas Gummerer (17):
      rerere: unify error messages when read_cache fails
      rerere: lowercase error messages
      rerere: wrap paths in output in sq
      rerere: mark strings for translation
      rerere: add documentation for conflict normalization
      rerere: fix crash with files rerere can't handle
      rerere: only return whether a path has conflicts or not
      rerere: factor out handle_conflict function
      rerere: return strbuf from handle path
      rerere: teach rerere to handle nested conflicts
      rerere: recalculate conflict ID when unresolved conflict is committed
      rerere: mention caveat about unmatched conflict markers
      rerere: add note about files with existing conflict markers
      .gitattributes: add conflict-marker-size for relevant files
      linear-assignment: fix potential out of bounds memory access
      t5551: move setup code inside test_expect blocks
      t5551: compare sorted cookies files

Tim Schumacher (4):
      Documentation/Makefile: make manpage-base-url.xsl generation quieter
      alias: add support for aliases of an alias
      alias: show the call history when an alias is looping
      t0014: introduce an alias testing suite

Torsten Bögershausen (2):
      Make git_check_attr() a void function
      path.c: char is not (always) signed

Uwe Kleine-König (1):
      howto/using-merge-subtree: mention --allow-unrelated-histories

brian m. carlson (26):
      t: add test functions to translate hash-related values
      t0000: use hash translation table
      t0000: update tests for SHA-256
      t0002: abstract away SHA-1 specific constants
      t0064: make hash size independent
      t1006: make hash size independent
      t1400: switch hard-coded object ID to variable
      t1405: make hash size independent
      t1406: make hash-size independent
      t1407: make hash size independent
      editorconfig: provide editor settings for Git developers
      editorconfig: indicate settings should be kept in sync
      pack-bitmap-write: use GIT_MAX_RAWSZ for allocation
      builtin/repack: replace hard-coded constants
      builtin/mktree: remove hard-coded constant
      builtin/fetch-pack: remove constants with parse_oid_hex
      pack-revindex: express constants in terms of the_hash_algo
      packfile: express constants in terms of the_hash_algo
      refs/packed-backend: express constants using the_hash_algo
      upload-pack: express constants in terms of the_hash_algo
      transport: use parse_oid_hex instead of a constant
      tag: express constant in terms of the_hash_algo
      apply: replace hard-coded constants
      apply: rename new_sha1_prefix and old_sha1_prefix
      submodule: make zero-oid comparison hash function agnostic
      rerere: convert to use the_hash_algo

Ævar Arnfjörð Bjarmason (31):
      fetch: change "branch" to "reference" in --force -h output
      push tests: make use of unused $1 in test description
      push tests: use spaces in interpolated string
      fetch tests: add a test for clobbering tag behavior
      push doc: remove confusing mention of remote merger
      push doc: move mention of "tag <tag>" later in the prose
      push doc: correct lies about how push refspecs work
      fetch: document local ref updates with/without --force
      fetch: stop clobbering existing tags without --force
      fsck tests: setup of bogus commit object
      fsck tests: add a test for no skipList input
      fsck: document and test sorted skipList input
      fsck: document and test commented & empty line skipList input
      fsck: document that skipList input must be unabbreviated
      fsck: add a performance test
      fsck: support comments & empty lines in skipList
      commit-graph write: add progress output
      commit-graph verify: add progress output
      config doc: add missing list separator for checkout.optimizeNewBranch
      push doc: add spacing between two words
      fetch doc: correct grammar in --force docs
      gc: fix regression in 7b0f229222 impacting --quiet
      gc doc: mention the commit-graph in the intro
      pack-objects test: modernize style
      pack-objects tests: don't leave test .git corrupt at end
      index-pack tests: don't leave test repo dirty at end
      range-diff doc: add a section about output stability
      range-diff: fix regression in passing along diff options
      range-diff: make diff option behavior (e.g. --stat) consistent
      rebase doc: document rebase.useBuiltin
      tests: add a special setup where rebase.useBuiltin is off


^ permalink raw reply	[relevance 2%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15 22:23  7%             ` Stefan Beller
@ 2018-11-16  0:31  6%               ` Michael Forney
  2018-11-27  0:03  4%                 ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Michael Forney @ 2018-11-16  0:31 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On 2018-11-15, Stefan Beller <sbeller@google.com> wrote:
> On Thu, Nov 15, 2018 at 1:33 PM Michael Forney <mforney@mforney.org> wrote:
>> Well, currently the submodule config can be disabled in diff_flags by
>> setting override_submodule_config=1. However, I'm thinking it may be
>> simpler to selectively *enable* the submodule config in diff_flags
>> where it is needed instead of disabling it everywhere else (i.e.
>> use_submodule_config instead of override_submodule_config).
>
> This sounds like undoing the good(?) part of the series that introduced
> this regression, as before that we selectively loaded the submodule
> config, which lead to confusion when you forgot it. Selectively *enabling*
> the submodule config sounds like that state before?
>
> Or do we *only* talk about enabling the ignore flag, while loading the
> rest of the submodule config automatic?

Yes, that is what I meant. I believe the automatic loading of
submodule config is the right thing to do, it just uncovered cases
where the current handling of override_submodule_config is not quite
sufficient.

My suggestion of replacing override_submodule_config with
use_submodule_config is because it seems like there are fewer places
where we want to apply the ignore config than not. I think it should
only apply in diffs against the working tree and when staging changes
to the index (unless specified explicitly). The documentation just
mentions the "diff family", but all but one of the possible values for
submodule.<name>.ignore ("all") don't make sense unless comparing with
the working tree. This is also how show/log -p behaved in git <2.15.
So I think that clarifying that it is about modifications *to the
working tree* would be a good idea.

>> I'm also starting to see why this is tricky. The only difference that
>> diff.c:run_diff_files sees between `git add inner` and `git add --all`
>> is whether the index entry matched the pathspec exactly or not.
>
> Unrelated to the trickiness, I think we'd need to document the behavior
> of the -a flag in git-add and git-commit better as adding the diff below
> will depart from the "all" rule again, which I thought was a strong
> motivator for Brandons series (IIRC).

Can you explain what you mean by the "all" rule?

>> Here is a work-in-progress diff that seems to have the correct
>> behavior in all cases I tried. Can you think of any cases that it
>> breaks? I'm not quite sure of the consequences of having diff_change
>> and diff_addremove always ignore the submodule config; git-diff and
>> git-status still seem to work correctly.
>>
>> diff --git a/builtin/add.c b/builtin/add.c
>> index f65c17229..9902f7742 100644
>> --- a/builtin/add.c
>> +++ b/builtin/add.c
>> @@ -117,7 +117,6 @@ int add_files_to_cache(const char *prefix,
>>         rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
>>         rev.diffopt.format_callback = update_callback;
>>         rev.diffopt.format_callback_data = &data;
>> -       rev.diffopt.flags.override_submodule_config = 1;
>
> This line partially reverts 5556808, taking 02f2f56bc377c28
> into account.

Correct. The problem with 55568086 is that add_files_to_cache is used
by both git-add and git-commit, regardless of whether --all was
specified. So, while it made it possible to stage ignored submodules,
it also made it so the submodule ignore config was overridden in all
uses of git-add and git-commit.

So, this diff attempts to make it so the ignore config is only applied
when the pathspec matches exactly rather than just always overriding
the ignore config.

>> diff --git a/diff-lib.c b/diff-lib.c
>> index 83fce5151..fbb048cca 100644
>> --- a/diff-lib.c
>> +++ b/diff-lib.c
>> @@ -68,12 +68,13 @@ static int check_removed(const struct cache_entry
>> *ce, struct stat *st)
>>  static int match_stat_with_submodule(struct diff_options *diffopt,
>>                                      const struct cache_entry *ce,
>>                                      struct stat *st, unsigned ce_option,
>> -                                    unsigned *dirty_submodule)
>> +                                    unsigned *dirty_submodule,
>> +                                    int exact)
>> [...];
>
> This is an interesting take so far as it is all about *detecting* change
> here via stat information and not like the previous (before the regression)
> where it was about correcting output.
>
> match_stat_with_submodule would grow its documentation to be
> slightly more complicated as a result.

Yes, this is one part I'm not quite happy with. I wonder if instead
match_stat_with_submodule could be made simpler by moving the
ie_match_stat call up to the two call sites, and then it could be
selectively called by run_diff_files depending on the value of
matched.

>> diff --git a/diff.c b/diff.c
>> index e38d1ecaf..73dc75286 100644
>> --- a/diff.c
>> +++ b/diff.c
>> [...]
>> -static int is_submodule_ignored(const char *path, struct diff_options
>> *options)
>> -{
>> [...]
>> -       if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath,
>> options))
>> +       if (S_ISGITLINK(mode) && options->flags.ignore_submodules)
>>                 return;
>
> This basically inlines the function is_submodule_ignored,
> except for the part:
>
>     if (!options->flags.override_submodule_config)
>         set_diffopt_flags_from_submodule_config(options, path);
>
> but that was taken care off in match_stat_with_submodule in diff-lib?

Yeah, since run_diff_files already skips ignored submodules (except if
given by name), and we still want the changes to be applied to the
index. Like I said, I'm not really sure if there are any other uses of
diff_change and diff_addremove where we actually do want the .ignore
config applied.

But, maybe if I instead left
`rev.diffopt.flags.override_submodule_config = 1` in builtin/add.c and
changed the condition in match_stat_with_submodule from `&& !exact` to
`|| !exact`, these functions would not need to be changed. In other
words, we relax the behavior when override_submodule_config is
specified, rather than making it stricter when it is not specified.

Testing this out, it looks like it fixes the behavior with add/commit
--all, but still omits ignored submodules in diffs between commits
(which is not the behavior I expect, see above). So, without the
changes to diff_change/diff_addremove we probably would need to add
override_submodule_config=1 to even more places.

Too many negatives are making this difficult to reason about.

> This WIP looks really promising, thanks for looking into this!

Thanks for taking the time to help me!

^ permalink raw reply	[relevance 6%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15 21:33  9%           ` Michael Forney
@ 2018-11-15 22:23  7%             ` Stefan Beller
  2018-11-16  0:31  6%               ` Michael Forney
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-15 22:23 UTC (permalink / raw)
  To: Michael Forney; +Cc: git

On Thu, Nov 15, 2018 at 1:33 PM Michael Forney <mforney@mforney.org> wrote:
>
> On 2018-11-15, Stefan Beller <sbeller@google.com> wrote:
> > On Wed, Nov 14, 2018 at 10:05 PM Michael Forney <mforney@mforney.org>
> > wrote:
> >> Looking at ff6f1f564c, I don't really see anything that might be
> >> related to git-add, git-reset, or git-diff, so I'm guessing that this
> >> only worked before because the submodule config wasn't getting loaded
> >> during `git add` or `git reset`. Now that the config is loaded
> >> automatically, submodule.<name>.ignore started taking effect where it
> >> shouldn't.
> >>
> >> Unfortunately, this doesn't really get me much closer to finding a fix.
> >
> > Maybe selectively unloading or overwriting the config?
> >
> > Or we can change is_submodule_ignored() in diff.c
> > to be only applied selectively whether we are running the
> > right command? For this approach we'd have to figure out the
> > set of commands to which the ignore config should apply or
> > not (and come up with a more concise documentation then)
> >
> > This approach sounds appealing to me as it would cover
> > new commands as well and we'd only have a central point
> > where the decision for ignoring is made.
>
> Well, currently the submodule config can be disabled in diff_flags by
> setting override_submodule_config=1. However, I'm thinking it may be
> simpler to selectively *enable* the submodule config in diff_flags
> where it is needed instead of disabling it everywhere else (i.e.
> use_submodule_config instead of override_submodule_config).

This sounds like undoing the good(?) part of the series that introduced
this regression, as before that we selectively loaded the submodule
config, which lead to confusion when you forgot it. Selectively *enabling*
the submodule config sounds like that state before?

Or do we *only* talk about enabling the ignore flag, while loading the
rest of the submodule config automatic?

> I'm also starting to see why this is tricky. The only difference that
> diff.c:run_diff_files sees between `git add inner` and `git add --all`
> is whether the index entry matched the pathspec exactly or not.

Unrelated to the trickiness, I think we'd need to document the behavior
of the -a flag in git-add and git-commit better as adding the diff below
will depart from the "all" rule again, which I thought was a strong
motivator for Brandons series (IIRC).

> Here is a work-in-progress diff that seems to have the correct
> behavior in all cases I tried. Can you think of any cases that it
> breaks? I'm not quite sure of the consequences of having diff_change
> and diff_addremove always ignore the submodule config; git-diff and
> git-status still seem to work correctly.
>
> diff --git a/builtin/add.c b/builtin/add.c
> index f65c17229..9902f7742 100644
> --- a/builtin/add.c
> +++ b/builtin/add.c
> @@ -117,7 +117,6 @@ int add_files_to_cache(const char *prefix,
>         rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
>         rev.diffopt.format_callback = update_callback;
>         rev.diffopt.format_callback_data = &data;
> -       rev.diffopt.flags.override_submodule_config = 1;

This line partially reverts 5556808, taking 02f2f56bc377c28
into account.

> diff --git a/diff-lib.c b/diff-lib.c
> index 83fce5151..fbb048cca 100644
> --- a/diff-lib.c
> +++ b/diff-lib.c
> @@ -68,12 +68,13 @@ static int check_removed(const struct cache_entry
> *ce, struct stat *st)
>  static int match_stat_with_submodule(struct diff_options *diffopt,
>                                      const struct cache_entry *ce,
>                                      struct stat *st, unsigned ce_option,
> -                                    unsigned *dirty_submodule)
> +                                    unsigned *dirty_submodule,
> +                                    int exact)
> [...];

This is an interesting take so far as it is all about *detecting* change
here via stat information and not like the previous (before the regression)
where it was about correcting output.

match_stat_with_submodule would grow its documentation to be
slightly more complicated as a result.

> diff --git a/diff.c b/diff.c
> index e38d1ecaf..73dc75286 100644
> --- a/diff.c
> +++ b/diff.c
> [...]
> -static int is_submodule_ignored(const char *path, struct diff_options *options)
> -{
> [...]
> -       if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath, options))
> +       if (S_ISGITLINK(mode) && options->flags.ignore_submodules)
>                 return;

This basically inlines the function is_submodule_ignored,
except for the part:

    if (!options->flags.override_submodule_config)
        set_diffopt_flags_from_submodule_config(options, path);

but that was taken care off in match_stat_with_submodule in diff-lib?

This WIP looks really promising, thanks for looking into this!
Stefan

^ permalink raw reply	[relevance 7%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15 20:03  4%         ` Stefan Beller
@ 2018-11-15 21:33  9%           ` Michael Forney
  2018-11-15 22:23  7%             ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Michael Forney @ 2018-11-15 21:33 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On 2018-11-15, Stefan Beller <sbeller@google.com> wrote:
> On Wed, Nov 14, 2018 at 10:05 PM Michael Forney <mforney@mforney.org>
> wrote:
>> Looking at ff6f1f564c, I don't really see anything that might be
>> related to git-add, git-reset, or git-diff, so I'm guessing that this
>> only worked before because the submodule config wasn't getting loaded
>> during `git add` or `git reset`. Now that the config is loaded
>> automatically, submodule.<name>.ignore started taking effect where it
>> shouldn't.
>>
>> Unfortunately, this doesn't really get me much closer to finding a fix.
>
> Maybe selectively unloading or overwriting the config?
>
> Or we can change is_submodule_ignored() in diff.c
> to be only applied selectively whether we are running the
> right command? For this approach we'd have to figure out the
> set of commands to which the ignore config should apply or
> not (and come up with a more concise documentation then)
>
> This approach sounds appealing to me as it would cover
> new commands as well and we'd only have a central point
> where the decision for ignoring is made.

Well, currently the submodule config can be disabled in diff_flags by
setting override_submodule_config=1. However, I'm thinking it may be
simpler to selectively *enable* the submodule config in diff_flags
where it is needed instead of disabling it everywhere else (i.e.
use_submodule_config instead of override_submodule_config).

I'm also starting to see why this is tricky. The only difference that
diff.c:run_diff_files sees between `git add inner` and `git add --all`
is whether the index entry matched the pathspec exactly or not.

Here is a work-in-progress diff that seems to have the correct
behavior in all cases I tried. Can you think of any cases that it
breaks? I'm not quite sure of the consequences of having diff_change
and diff_addremove always ignore the submodule config; git-diff and
git-status still seem to work correctly.

diff --git a/builtin/add.c b/builtin/add.c
index f65c17229..9902f7742 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -117,7 +117,6 @@ int add_files_to_cache(const char *prefix,
 	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
 	rev.diffopt.format_callback = update_callback;
 	rev.diffopt.format_callback_data = &data;
-	rev.diffopt.flags.override_submodule_config = 1;
 	rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
 	run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
 	clear_pathspec(&rev.prune_data);
diff --git a/diff-lib.c b/diff-lib.c
index 83fce5151..fbb048cca 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -68,12 +68,13 @@ static int check_removed(const struct cache_entry
*ce, struct stat *st)
 static int match_stat_with_submodule(struct diff_options *diffopt,
 				     const struct cache_entry *ce,
 				     struct stat *st, unsigned ce_option,
-				     unsigned *dirty_submodule)
+				     unsigned *dirty_submodule,
+				     int exact)
 {
 	int changed = ie_match_stat(diffopt->repo->index, ce, st, ce_option);
 	if (S_ISGITLINK(ce->ce_mode)) {
 		struct diff_flags orig_flags = diffopt->flags;
-		if (!diffopt->flags.override_submodule_config)
+		if (!diffopt->flags.override_submodule_config && !exact)
 			set_diffopt_flags_from_submodule_config(diffopt, ce->name);
 		if (diffopt->flags.ignore_submodules)
 			changed = 0;
@@ -88,7 +89,7 @@ static int match_stat_with_submodule(struct
diff_options *diffopt,

 int run_diff_files(struct rev_info *revs, unsigned int option)
 {
-	int entries, i;
+	int entries, i, matched;
 	int diff_unmerged_stage = revs->max_count;
 	unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
 			      ? CE_MATCH_RACY_IS_DIRTY : 0);
@@ -110,7 +111,8 @@ int run_diff_files(struct rev_info *revs, unsigned
int option)
 		if (diff_can_quit_early(&revs->diffopt))
 			break;

-		if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
+		matched = ce_path_match(istate, ce, &revs->prune_data, NULL);
+		if (!matched)
 			continue;

 		if (ce_stage(ce)) {
@@ -226,7 +228,8 @@ int run_diff_files(struct rev_info *revs, unsigned
int option)
 			}

 			changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
-							    ce_option, &dirty_submodule);
+							    ce_option, &dirty_submodule,
+							    matched == MATCHED_EXACTLY);
 			newmode = ce_mode_from_stat(ce, st.st_mode);
 		}

@@ -292,7 +295,7 @@ static int get_stat_data(const struct cache_entry *ce,
 			return -1;
 		}
 		changed = match_stat_with_submodule(diffopt, ce, &st,
-						    0, dirty_submodule);
+						    0, dirty_submodule, 0);
 		if (changed) {
 			mode = ce_mode_from_stat(ce, st.st_mode);
 			oid = &null_oid;
diff --git a/diff.c b/diff.c
index e38d1ecaf..73dc75286 100644
--- a/diff.c
+++ b/diff.c
@@ -6209,24 +6209,6 @@ int diff_can_quit_early(struct diff_options *opt)
 		opt->flags.has_changes);
 }

-/*
- * Shall changes to this submodule be ignored?
- *
- * Submodule changes can be configured to be ignored separately for each path,
- * but that configuration can be overridden from the command line.
- */
-static int is_submodule_ignored(const char *path, struct diff_options *options)
-{
-	int ignored = 0;
-	struct diff_flags orig_flags = options->flags;
-	if (!options->flags.override_submodule_config)
-		set_diffopt_flags_from_submodule_config(options, path);
-	if (options->flags.ignore_submodules)
-		ignored = 1;
-	options->flags = orig_flags;
-	return ignored;
-}
-
 void diff_addremove(struct diff_options *options,
 		    int addremove, unsigned mode,
 		    const struct object_id *oid,
@@ -6235,7 +6217,7 @@ void diff_addremove(struct diff_options *options,
 {
 	struct diff_filespec *one, *two;

-	if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath, options))
+	if (S_ISGITLINK(mode) && options->flags.ignore_submodules)
 		return;

 	/* This may look odd, but it is a preparation for
@@ -6285,7 +6267,7 @@ void diff_change(struct diff_options *options,
 	struct diff_filepair *p;

 	if (S_ISGITLINK(old_mode) && S_ISGITLINK(new_mode) &&
-	    is_submodule_ignored(concatpath, options))
+	    options->flags.ignore_submodules)
 		return;

 	if (options->flags.reverse_diff) {

^ permalink raw reply related	[relevance 9%]

* Re: [PATCH 18/23] submodule: use submodule repos for object lookup
  @ 2018-11-15 20:36  7%     ` Stefan Beller
  2018-12-12 20:22 24%       ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-15 20:36 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: Junio C Hamano, git

On Thu, Nov 15, 2018 at 11:54 AM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > +/*
> > + * Initialize 'out' based on the provided submodule path.
> > + *
> > + * Unlike repo_submodule_init, this tolerates submodules not present
> > + * in .gitmodules. This function exists only to preserve historical behavior,
> > + *
> > + * Returns 0 on success, -1 when the submodule is not present.
> >   */
> > -static void show_submodule_header(struct diff_options *o, const char *path,
> > +static struct repository *open_submodule(const char *path)
>
> The function documentation needs to be reworded - there's no "out", and
> the return value is now a possibly NULL pointer to struct repository.

Noted.

>
> > +{
> > +     struct strbuf sb = STRBUF_INIT;
> > +     struct repository *out = xmalloc(sizeof(*out));
> > +
> > +     if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> > +             strbuf_release(&sb);
> > +             free(out);
> > +             return NULL;
> > +     }
> > +
> > +     out->submodule_prefix = xstrdup(path);
>
> I've discussed this submodule_prefix line before [1] - do we really need
> this? Tests pass even if I remove this line.

We might not need it yet as the tests indicate, but it's the right thing to do:
/*
 * Path from the root of the top-level superproject down to this
 * repository.  This is only non-NULL if the repository is initialized
 * as a submodule of another repository.
 */

We're not (yet) using this string in our error reporting, but
I anticipate that we'll do eventually.

> Other than that, this patch looks good.

Thanks,
Stefan

^ permalink raw reply	[relevance 7%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15  6:05  5%       ` Michael Forney
@ 2018-11-15 20:03  4%         ` Stefan Beller
  2018-11-15 21:33  9%           ` Michael Forney
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-15 20:03 UTC (permalink / raw)
  To: Michael Forney; +Cc: git, Brandon Williams

On Wed, Nov 14, 2018 at 10:05 PM Michael Forney <mforney@mforney.org> wrote:
>
> +bmwill
>
> On 2018-11-14, Michael Forney <mforney@mforney.org> wrote:
> > On 2018-10-25, Stefan Beller <sbeller@google.com> wrote:
> >> I guess reverting that commit is not a good idea now, as
> >> I would expect something to break.
> >>
> >> Maybe looking through the series 614ea03a71
> >> (Merge branch 'bw/submodule-config-cleanup', 2017-08-26)
> >> to understand why it happened in the context would be a good start.
> >
> > Thanks, that's a good idea. I'll take a look through that series.
>
> Interesting. If I build git from master after reverting 55568086, I do
> indeed observe the issue it claims to fix (unable to add ignored
> submodules). However, if I build from 9ef23f91fc (the immediate parent
> of 55568086), I do not see the issue.
>
> Investigating this further, it seems that 55568086 addresses an issue
> that does not appear until later on in the series in ff6f1f564c
> (submodule-config: lazy-load a repository's .gitmodules file). Perhaps
> this was a result of reordering commits during a rebase. In other
> words, I get correct behavior until 55568086, and in
> 55568086..ff6f1f564c^ if I revert 55568086.
>
> Looking at ff6f1f564c, I don't really see anything that might be
> related to git-add, git-reset, or git-diff, so I'm guessing that this
> only worked before because the submodule config wasn't getting loaded
> during `git add` or `git reset`. Now that the config is loaded
> automatically, submodule.<name>.ignore started taking effect where it
> shouldn't.
>
> Unfortunately, this doesn't really get me much closer to finding a fix.

Maybe selectively unloading or overwriting the config?

Or we can change is_submodule_ignored() in diff.c
to be only applied selectively whether we are running the
right command? For this approach we'd have to figure out the
set of commands to which the ignore config should apply or
not (and come up with a more concise documentation then)

This approach sounds appealing to me as it would cover
new commands as well and we'd only have a central point
where the decision for ignoring is made.

Stefan

^ permalink raw reply	[relevance 4%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15  5:12  7%     ` Michael Forney
  2018-11-15  6:05  5%       ` Michael Forney
@ 2018-11-15 19:39  7%       ` Stefan Beller
  1 sibling, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-15 19:39 UTC (permalink / raw)
  To: Michael Forney; +Cc: git

> I have a git repository which contains a number of submodules that
> refer to external repositories. Some of these repositories need to
> patched in some way, so patches are stored alongside the submodules,
> and are applied when building. This mostly works fine, but causes
> submodules to show up as modified in `git status` and get updated with
> `git commit -a`. To resolve this, I've added `ignore = all` to
> .gitmodules for all the submodules that need patches applied. This
> way, I can explicitly `git add` the submodule when I want to update
> the base commit, but otherwise pretend that they are clean. This has
> worked pretty well for me, but less so since git 2.15 when this issue
> was introduced.

> > This is really bad. git-status and git-commit share some code,
> > and we'll populate the commit message with a status output.
> > So it seems reasonable to expect the status and the commit to match,
> > i.e. if status tells me there is no change, then commit should not record
> > the submodule update.
>
> I just checked and if I don't specify a message on the command-line,
> the status output in the message template *does* mention that `inner`
> is getting updated.

That's good.

> >> > There have been a couple occasions where I accidentally pushed local
> >> > changes to ignored submodules because of this. Since they don't show
> >> > up in the log output, it is difficult to figure out what actually has
> >> > gone wrong.
> >
> > How was it prevented before? Just by git commit -a not picking up the
> > submodule change?
>
> Yes. Previously, `git commit -a` would not pick up the change (unless
> I added it explicitly with `git add`), and `git log` would still show
> changes to ignored submodules (which is the behavior I want).

and both are broken currently (commit -a will commit a submodule if
it is changed, and it will also not show that in log, but it did show that
it is committing it in the commit message template)

> I just came across someone else affected by this issue:
> https://github.com/git/git/commit/55568086#commitcomment-27137460

Point taken.

^ permalink raw reply	[relevance 7%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15  5:12  7%     ` Michael Forney
@ 2018-11-15  6:05  5%       ` Michael Forney
  2018-11-15 20:03  4%         ` Stefan Beller
  2018-11-15 19:39  7%       ` Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Michael Forney @ 2018-11-15  6:05 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, bmwill

+bmwill

On 2018-11-14, Michael Forney <mforney@mforney.org> wrote:
> On 2018-10-25, Stefan Beller <sbeller@google.com> wrote:
>> I guess reverting that commit is not a good idea now, as
>> I would expect something to break.
>>
>> Maybe looking through the series 614ea03a71
>> (Merge branch 'bw/submodule-config-cleanup', 2017-08-26)
>> to understand why it happened in the context would be a good start.
>
> Thanks, that's a good idea. I'll take a look through that series.

Interesting. If I build git from master after reverting 55568086, I do
indeed observe the issue it claims to fix (unable to add ignored
submodules). However, if I build from 9ef23f91fc (the immediate parent
of 55568086), I do not see the issue.

Investigating this further, it seems that 55568086 addresses an issue
that does not appear until later on in the series in ff6f1f564c
(submodule-config: lazy-load a repository's .gitmodules file). Perhaps
this was a result of reordering commits during a rebase. In other
words, I get correct behavior until 55568086, and in
55568086..ff6f1f564c^ if I revert 55568086.

Looking at ff6f1f564c, I don't really see anything that might be
related to git-add, git-reset, or git-diff, so I'm guessing that this
only worked before because the submodule config wasn't getting loaded
during `git add` or `git reset`. Now that the config is loaded
automatically, submodule.<name>.ignore started taking effect where it
shouldn't.

Unfortunately, this doesn't really get me much closer to finding a fix.

^ permalink raw reply	[relevance 5%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  @ 2018-11-15  5:12  7%     ` Michael Forney
  2018-11-15  6:05  5%       ` Michael Forney
  2018-11-15 19:39  7%       ` Stefan Beller
  0 siblings, 2 replies; 200+ results
From: Michael Forney @ 2018-11-15  5:12 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On 2018-10-25, Stefan Beller <sbeller@google.com> wrote:
> On Thu, Oct 25, 2018 at 11:03 AM Michael Forney <mforney@mforney.org>
> wrote:
>>
>> On 2018-03-16, Michael Forney <mforney@mforney.org> wrote:
>> > Hi,
>> >
>> > In the past few months have noticed some confusing behavior with
>> > ignored submodules. I finally got around to bisecting this to commit
>> > 5556808690ea245708fb80383be5c1afee2fb3eb (add, reset: ensure
>> > submodules can be added or reset).
>
> Uh. :(
>
> See the discussion starting at
> https://public-inbox.org/git/20170725213928.125998-4-bmwill@google.com/
> specifically
> https://public-inbox.org/git/xmqqinieq49v.fsf@gitster.mtv.corp.google.com/

Thanks for the links. Let me explain how I'm using
submodule.<name>.ignore. Maybe there's a better mechanism in git to
deal with this (if .ignore is a misfeature).

I have a git repository which contains a number of submodules that
refer to external repositories. Some of these repositories need to
patched in some way, so patches are stored alongside the submodules,
and are applied when building. This mostly works fine, but causes
submodules to show up as modified in `git status` and get updated with
`git commit -a`. To resolve this, I've added `ignore = all` to
.gitmodules for all the submodules that need patches applied. This
way, I can explicitly `git add` the submodule when I want to update
the base commit, but otherwise pretend that they are clean. This has
worked pretty well for me, but less so since git 2.15 when this issue
was introduced.

Of course, I could maintain and publish forks of those repositories
and use those as the remote for the submodules. However in many cases
these patches are just temporary until they get applied upstream and a
new release is made, and I don't really want to keep mirrors
unnecessarily, or keep switching the submodule URL between upstream
and my fork.

>> > However, if I go to update `foo.txt` and
>> > commit with `git commit -a`, changes to inner get recorded
>> > unexpectedly. What's worse is the shortstat output of `git commit -a`,
>> > and the diff output of `git show` give no indication that the
>> > submodule was changed.
>
> This is really bad. git-status and git-commit share some code,
> and we'll populate the commit message with a status output.
> So it seems reasonable to expect the status and the commit to match,
> i.e. if status tells me there is no change, then commit should not record
> the submodule update.

I just checked and if I don't specify a message on the command-line,
the status output in the message template *does* mention that `inner`
is getting updated.

>> > There have been a couple occasions where I accidentally pushed local
>> > changes to ignored submodules because of this. Since they don't show
>> > up in the log output, it is difficult to figure out what actually has
>> > gone wrong.
>
> How was it prevented before? Just by git commit -a not picking up the
> submodule change?

Yes. Previously, `git commit -a` would not pick up the change (unless
I added it explicitly with `git add`), and `git log` would still show
changes to ignored submodules (which is the behavior I want).

> I guess reverting that commit is not a good idea now, as
> I would expect something to break.
>
> Maybe looking through the series 614ea03a71
> (Merge branch 'bw/submodule-config-cleanup', 2017-08-26)
> to understand why it happened in the context would be a good start.

Thanks, that's a good idea. I'll take a look through that series.

>> I accidentally pushed local changes to ignored submodules again due to
>> this.
>>
>> Can anyone confirm whether this is the intended behavior of ignore? If
>> it is, then at least the documentation needs an update saying that
>> `commit -a` will commit all submodule changes, even if they are
>> ignored.
>
> The docs say "(but it will nonetheless show up in the output of
> status and commit when it has been staged)" as well, so that commit
> sounds like a regression?

I just came across someone else affected by this issue:
https://github.com/git/git/commit/55568086#commitcomment-27137460

^ permalink raw reply	[relevance 7%]

* [PATCH 19/23] submodule: don't add submodule as odb for push
  2018-11-14  0:12  7% [PATCHv3 00/23] Bring more repository handles into our code base Stefan Beller
  2018-11-14  0:13 20% ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-11-14  0:13 14% ` Stefan Beller
  1 sibling, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-14  0:13 UTC (permalink / raw)
  To: gitster, jonathantanmy; +Cc: git, Stefan Beller

In push_submodule(), because we do not actually need access to objects
in the submodule, do not invoke add_submodule_odb().
(for_each_remote_ref_submodule() does not require access to those
objects, and the actual push is done by spawning another process,
which handles object access by itself.)

This code of push_submodule() is exercised in t5531 and continues
to work, showing that the submodule odbc is not needed.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index 262f03f118..5818088df2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1021,9 +1021,6 @@ static int push_submodule(const char *path,
 			  const struct string_list *push_options,
 			  int dry_run)
 {
-	if (add_submodule_odb(path))
-		return 1;
-
 	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
 		struct child_process cp = CHILD_PROCESS_INIT;
 		argv_array_push(&cp.args, "push");
-- 
2.19.1.1215.g8438c0b245-goog


^ permalink raw reply related	[relevance 14%]

* [PATCH 18/23] submodule: use submodule repos for object lookup
  2018-11-14  0:12  7% [PATCHv3 00/23] Bring more repository handles into our code base Stefan Beller
@ 2018-11-14  0:13 20% ` Stefan Beller
    2018-11-14  0:13 14% ` [PATCH 19/23] submodule: don't add submodule as odb for push Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-14  0:13 UTC (permalink / raw)
  To: gitster, jonathantanmy; +Cc: git, Stefan Beller

This converts the 'show_submodule_header' function to use
the repository API properly, such that the submodule objects
are not added to the main object store.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 73 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 58 insertions(+), 15 deletions(-)

diff --git a/submodule.c b/submodule.c
index d9d3046689..262f03f118 100644
--- a/submodule.c
+++ b/submodule.c
@@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
 	return prepare_revision_walk(rev);
 }
 
-static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
+static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
 {
 	static const char format[] = "  %m %s";
 	struct strbuf sb = STRBUF_INIT;
@@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
 		ctx.date_mode = rev->date_mode;
 		ctx.output_encoding = get_log_output_encoding();
 		strbuf_setlen(&sb, 0);
-		format_commit_message(commit, format, &sb, &ctx);
+		repo_format_commit_message(r, commit, format, &sb,
+				      &ctx);
 		strbuf_addch(&sb, '\n');
 		if (commit->object.flags & SYMMETRIC_LEFT)
 			diff_emit_submodule_del(o, sb.buf);
@@ -481,14 +482,44 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
-/* Helper function to display the submodule header line prior to the full
- * summary output. If it can locate the submodule objects directory it will
- * attempt to lookup both the left and right commits and put them into the
- * left and right pointers.
+/*
+ * Initialize 'out' based on the provided submodule path.
+ *
+ * Unlike repo_submodule_init, this tolerates submodules not present
+ * in .gitmodules. This function exists only to preserve historical behavior,
+ *
+ * Returns 0 on success, -1 when the submodule is not present.
  */
-static void show_submodule_header(struct diff_options *o, const char *path,
+static struct repository *open_submodule(const char *path)
+{
+	struct strbuf sb = STRBUF_INIT;
+	struct repository *out = xmalloc(sizeof(*out));
+
+	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
+		strbuf_release(&sb);
+		free(out);
+		return NULL;
+	}
+
+	out->submodule_prefix = xstrdup(path);
+
+	strbuf_release(&sb);
+	return out;
+}
+
+/*
+ * Helper function to display the submodule header line prior to the full
+ * summary output.
+ *
+ * If it can locate the submodule git directory it will create a repository
+ * handle for the submodule and lookup both the left and right commits and
+ * put them into the left and right pointers.
+ */
+static void show_submodule_header(struct diff_options *o,
+		const char *path,
 		struct object_id *one, struct object_id *two,
 		unsigned dirty_submodule,
+		struct repository *sub,
 		struct commit **left, struct commit **right,
 		struct commit_list **merge_bases)
 {
@@ -507,7 +538,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	else if (is_null_oid(two))
 		message = "(submodule deleted)";
 
-	if (add_submodule_odb(path)) {
+	if (!sub) {
 		if (!message)
 			message = "(commits not present)";
 		goto output_header;
@@ -517,8 +548,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	 * Attempt to lookup the commit references, and determine if this is
 	 * a fast forward or fast backwards update.
 	 */
-	*left = lookup_commit_reference(the_repository, one);
-	*right = lookup_commit_reference(the_repository, two);
+	*left = lookup_commit_reference(sub, one);
+	*right = lookup_commit_reference(sub, two);
 
 	/*
 	 * Warn about missing commits in the submodule project, but only if
@@ -528,7 +559,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	     (!is_null_oid(two) && !*right))
 		message = "(commits not present)";
 
-	*merge_bases = get_merge_bases(*left, *right);
+	*merge_bases = repo_get_merge_bases(sub, *left, *right);
 	if (*merge_bases) {
 		if ((*merge_bases)->item == *left)
 			fast_forward = 1;
@@ -562,16 +593,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 	struct rev_info rev;
 	struct commit *left = NULL, *right = NULL;
 	struct commit_list *merge_bases = NULL;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/*
 	 * If we don't have both a left and a right pointer, there is no
 	 * reason to try and display a summary. The header line should contain
 	 * all the information the user needs.
 	 */
-	if (!left || !right)
+	if (!left || !right || !sub)
 		goto out;
 
 	/* Treat revision walker failure the same as missing commits */
@@ -580,13 +613,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 		goto out;
 	}
 
-	print_submodule_summary(&rev, o);
+	print_submodule_summary(sub, &rev, o);
 
 out:
 	if (merge_bases)
 		free_commit_list(merge_bases);
 	clear_commit_marks(left, ~0);
 	clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 void show_submodule_inline_diff(struct diff_options *o, const char *path,
@@ -598,9 +635,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 	struct commit_list *merge_bases = NULL;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strbuf sb = STRBUF_INIT;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/* We need a valid left and right commit to display a difference */
 	if (!(left || is_null_oid(one)) ||
@@ -661,6 +700,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 		clear_commit_marks(left, ~0);
 	if (right)
 		clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 int should_update_submodules(void)
-- 
2.19.1.1215.g8438c0b245-goog


^ permalink raw reply related	[relevance 20%]

* [PATCHv3 00/23] Bring more repository handles into our code base
@ 2018-11-14  0:12  7% Stefan Beller
  2018-11-14  0:13 20% ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
  2018-11-14  0:13 14% ` [PATCH 19/23] submodule: don't add submodule as odb for push Stefan Beller
  0 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-11-14  0:12 UTC (permalink / raw)
  To: gitster, jonathantanmy; +Cc: git, Stefan Beller

This resends origin/sb/more-repo-in-api.

Unlike the previous resend (v2), this is not rebased to a newer base.
This doesn't contain the patch for pending semantic changes, as that
seems to go in its own topic branch.

Please have a look at the last 4 patches specifically as they were new in
the last iteration (but did not receive any comment), as they demonstrate
and fix a problem that is only exposed when using GIT_TEST_COMMIT_GRAPH=1
for the test suite.

Previous discussion at
https://public-inbox.org/git/20181030220817.61691-1-sbeller@google.com/

Thanks,
Stefan

Stefan Beller (23):
  sha1_file: allow read_object to read objects in arbitrary repositories
  packfile: allow has_packed_and_bad to handle arbitrary repositories
  object-store: allow read_object_file_extended to read from any repo
  object-store: prepare read_object_file to deal with any repo
  object-store: prepare has_{sha1, object}_file to handle any repo
  object: parse_object to honor its repository argument
  commit: allow parse_commit* to handle any repo
  commit-reach.c: allow paint_down_to_common to handle any repo
  commit-reach.c: allow merge_bases_many to handle any repo
  commit-reach.c: allow remove_redundant to handle any repo
  commit-reach.c: allow get_merge_bases_many_0 to handle any repo
  commit-reach: prepare get_merge_bases to handle any repo
  commit-reach: prepare in_merge_bases[_many] to handle any repo
  commit: prepare get_commit_buffer to handle any repo
  commit: prepare repo_unuse_commit_buffer to handle any repo
  commit: prepare logmsg_reencode to handle arbitrary repositories
  pretty: prepare format_commit_message to handle arbitrary repositories
  submodule: use submodule repos for object lookup
  submodule: don't add submodule as odb for push
  commit-graph: convert remaining functions to handle any repo
  commit: prepare free_commit_buffer and release_commit_memory for any
    repo
  path.h: make REPO_GIT_PATH_FUNC repository agnostic
  t/helper/test-repository: celebrate independence from the_repository

 builtin/fsck.c                                |   3 +-
 builtin/log.c                                 |   6 +-
 builtin/rev-list.c                            |   3 +-
 cache.h                                       |   2 +
 commit-graph.c                                |  40 +++--
 commit-reach.c                                |  73 +++++----
 commit-reach.h                                |  38 +++--
 commit.c                                      |  41 ++---
 commit.h                                      |  43 +++++-
 .../coccinelle/the_repository.pending.cocci   | 144 ++++++++++++++++++
 object-store.h                                |  35 ++++-
 object.c                                      |   8 +-
 packfile.c                                    |   5 +-
 packfile.h                                    |   2 +-
 path.h                                        |   2 +-
 pretty.c                                      |  28 ++--
 pretty.h                                      |   7 +-
 sha1-file.c                                   |  34 +++--
 streaming.c                                   |   2 +-
 submodule.c                                   |  76 ++++++---
 t/helper/test-repository.c                    |  10 ++
 21 files changed, 452 insertions(+), 150 deletions(-)
 create mode 100644 contrib/coccinelle/the_repository.pending.cocci

Range-diff:
 1:  1b9b5c695e =  1:  ca9fece80e sha1_file: allow read_object to read objects in arbitrary repositories
 2:  33b94066f2 =  2:  8eac25fe32 packfile: allow has_packed_and_bad to handle arbitrary repositories
 3:  5217b6b1e1 !  3:  06e5f83b66 object-store: allow read_object_file_extended to read from arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    object-store: allow read_object_file_extended to read from arbitrary repositories
    +    object-store: allow read_object_file_extended to read from any repo
     
         read_object_file_extended is not widely used, so migrate it all at once.
     
 4:  2b7239b55b !  4:  6167722608 object-store: prepare read_object_file to deal with arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    object-store: prepare read_object_file to deal with arbitrary repositories
    +    object-store: prepare read_object_file to deal with any repo
     
         As read_object_file is a widely used function (which is also regularly used
         in new code in flight between master..pu), changing its signature is painful
    @@ -13,16 +13,14 @@
         e675765235 (diff.c: remove implicit dependency on the_index, 2018-09-21)
     
         Add a coccinelle patch to convert existing callers, but do not apply
    -    the resulting patch from 'make coccicheck' to keep the diff of this
    -    patch small.
    +    the resulting patch to keep the diff of this patch small.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
      new file mode 100644
      --- /dev/null
    - +++ b/contrib/coccinelle/the_repository.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
     +// This file is used for the ongoing refactoring of
     +// bringing the index or repository struct in all of
 5:  24291f4d84 !  5:  2a88a868bb object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
    @@ -1,13 +1,12 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
    +    object-store: prepare has_{sha1, object}_file to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - read_object_file(
      + repo_read_object_file(the_repository,
 6:  6aa209978e =  6:  fd4a151e07 object: parse_object to honor its repository argument
 7:  9b2d6aa7c3 !  7:  5484abc785 commit: allow parse_commit* to handle arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: allow parse_commit* to handle arbitrary repositories
    +    commit: allow parse_commit* to handle any repo
     
         Just like the previous commit, parse_commit and friends are used a lot
         and are found in new patches, so we cannot change their signature easily.
    @@ -9,7 +9,6 @@
         argument and keep the original as a shallow macro.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -93,9 +92,9 @@
      
      struct buffer_slab;
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - has_object_file_with_flags(
      + repo_has_object_file_with_flags(the_repository,
 8:  0e7e681118 !  8:  8cc3054b31 commit-reach.c: allow paint_down_to_common to handle arbitrary repositories
    @@ -1,11 +1,10 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach.c: allow paint_down_to_common to handle arbitrary repositories
    +    commit-reach.c: allow paint_down_to_common to handle any repo
     
         As the function is file local and not widely used, migrate it all at once.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
 9:  e83b26f5b3 !  9:  45e67ba283 commit-reach.c: allow merge_bases_many to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach.c: allow merge_bases_many to handle arbitrary repositories
    +    commit-reach.c: allow merge_bases_many to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
10:  d80b9de832 ! 10:  917d8cbaee commit-reach.c: allow remove_redundant to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach.c: allow remove_redundant to handle arbitrary repositories
    +    commit-reach.c: allow remove_redundant to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
11:  3ec21ad503 ! 11:  a008e62fea commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
    +    commit-reach.c: allow get_merge_bases_many_0 to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
12:  3f21279f50 ! 12:  a50a7f52b0 commit-reach: prepare get_merge_bases to handle arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach: prepare get_merge_bases to handle arbitrary repositories
    +    commit-reach: prepare get_merge_bases to handle any repo
     
         Similarly to previous patches, the get_merge_base functions are used
         often in the code base, which makes migrating them hard.
    @@ -9,7 +9,6 @@
         functions behind a wrapper macro.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
    @@ -91,9 +90,9 @@
      int is_descendant_of(struct commit *commit, struct commit_list *with_commit);
      int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - parse_commit(
      + repo_parse_commit(the_repository,
13:  4decc3acc1 ! 13:  d82074d34b commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
    +    commit-reach: prepare in_merge_bases[_many] to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
    @@ -76,9 +75,9 @@
      /*
       * Takes a list of commits and returns a new list where those
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - get_merge_bases_many_dirty(
      + repo_get_merge_bases_many_dirty(the_repository,
14:  141b86ea89 ! 14:  6035c18ca1 commit: prepare get_commit_buffer to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: prepare get_commit_buffer to handle arbitrary repositories
    +    commit: prepare get_commit_buffer to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -46,9 +45,9 @@
      /*
       * Tell the commit subsytem that we are done with a particular commit buffer.
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - in_merge_bases_many(
      + repo_in_merge_bases_many(the_repository,
15:  2cc415c1db ! 15:  85dcc6f806 commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
    +    commit: prepare repo_unuse_commit_buffer to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -42,9 +41,9 @@
      /*
       * Free any cached object buffer associated with the commit.
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - get_commit_buffer(
      + repo_get_commit_buffer(the_repository,
16:  554daa8cfc ! 16:  0e1b98701f commit: prepare logmsg_reencode to handle arbitrary repositories
    @@ -24,9 +24,9 @@
      
      /** Removes the first commit from a list sorted by date, and adds all
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - unuse_commit_buffer(
      + repo_unuse_commit_buffer(the_repository,
17:  bd8737176b ! 17:  da611e902b pretty: prepare format_commit_message to handle arbitrary repositories
    @@ -5,9 +5,9 @@
         Signed-off-by: Stefan Beller <sbeller@google.com>
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - logmsg_reencode(
      + repo_logmsg_reencode(the_repository,
18:  b303ef65e7 ! 18:  a98112634e submodule: use submodule repos for object lookup
    @@ -7,7 +7,6 @@
         are not added to the main object store.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
    @@ -46,24 +45,23 @@
     + * in .gitmodules. This function exists only to preserve historical behavior,
     + *
     + * Returns 0 on success, -1 when the submodule is not present.
    -+ */
    -+static int open_submodule(struct repository *out, const char *path)
    +  */
    +-static void show_submodule_header(struct diff_options *o, const char *path,
    ++static struct repository *open_submodule(const char *path)
     +{
     +	struct strbuf sb = STRBUF_INIT;
    ++	struct repository *out = xmalloc(sizeof(*out));
     +
     +	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
     +		strbuf_release(&sb);
    -+		return -1;
    ++		free(out);
    ++		return NULL;
     +	}
     +
     +	out->submodule_prefix = xstrdup(path);
    -+	out->submodule_prefix = xstrfmt("%s%s/",
    -+					the_repository->submodule_prefix ?
    -+					the_repository->submodule_prefix :
    -+					"", path);
     +
     +	strbuf_release(&sb);
    -+	return 0;
    ++	return out;
     +}
     +
     +/*
    @@ -73,8 +71,7 @@
     + * If it can locate the submodule git directory it will create a repository
     + * handle for the submodule and lookup both the left and right commits and
     + * put them into the left and right pointers.
    -  */
    --static void show_submodule_header(struct diff_options *o, const char *path,
    ++ */
     +static void show_submodule_header(struct diff_options *o,
     +		const char *path,
      		struct object_id *one, struct object_id *two,
    @@ -116,11 +113,9 @@
      	struct rev_info rev;
      	struct commit *left = NULL, *right = NULL;
      	struct commit_list *merge_bases = NULL;
    -+	struct repository subrepo, *sub = &subrepo;
    -+
    -+	if (open_submodule(&subrepo, path) < 0)
    -+		sub = NULL;
    ++	struct repository *sub;
      
    ++	sub = open_submodule(path);
      	show_submodule_header(o, path, one, two, dirty_submodule,
     -			      &left, &right, &merge_bases);
     +			      sub, &left, &right, &merge_bases);
    @@ -147,8 +142,10 @@
      		free_commit_list(merge_bases);
      	clear_commit_marks(left, ~0);
      	clear_commit_marks(right, ~0);
    -+	if (sub)
    ++	if (sub) {
     +		repo_clear(sub);
    ++		free(sub);
    ++	}
      }
      
      void show_submodule_inline_diff(struct diff_options *o, const char *path,
    @@ -156,11 +153,9 @@
      	struct commit_list *merge_bases = NULL;
      	struct child_process cp = CHILD_PROCESS_INIT;
      	struct strbuf sb = STRBUF_INIT;
    -+	struct repository subrepo, *sub = &subrepo;
    -+
    -+	if (open_submodule(&subrepo, path) < 0)
    -+		sub = NULL;
    ++	struct repository *sub;
      
    ++	sub = open_submodule(path);
      	show_submodule_header(o, path, one, two, dirty_submodule,
     -			      &left, &right, &merge_bases);
     +			      sub, &left, &right, &merge_bases);
    @@ -171,8 +166,10 @@
      		clear_commit_marks(left, ~0);
      	if (right)
      		clear_commit_marks(right, ~0);
    -+	if (sub)
    ++	if (sub) {
     +		repo_clear(sub);
    ++		free(sub);
    ++	}
      }
      
      int should_update_submodules(void)
19:  dbb0dd9322 ! 19:  6aad29a006 submodule: don't add submodule as odb for push
    @@ -8,8 +8,10 @@
         objects, and the actual push is done by spawning another process,
         which handles object access by itself.)
     
    +    This code of push_submodule() is exercised in t5531 and continues
    +    to work, showing that the submodule odbc is not needed.
    +
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
 -:  ---------- > 20:  1687e96586 commit-graph: convert remaining functions to handle any repo
 -:  ---------- > 21:  d348185ca9 commit: prepare free_commit_buffer and release_commit_memory for any repo
 -:  ---------- > 22:  19f62807cc path.h: make REPO_GIT_PATH_FUNC repository agnostic
 -:  ---------- > 23:  61da0c2812 t/helper/test-repository: celebrate independence from the_repository
-- 
2.19.1.1215.g8438c0b245-goog


^ permalink raw reply	[relevance 7%]

* Git Test Coverage Report (Tuesday, Nov 13)
@ 2018-11-13 18:05  3% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-13 18:05 UTC (permalink / raw)
  To: Git List

Here is the test coverage report for today.

Thanks,
-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=256&view=logs

---

pu: a849d4c48bb308cdf3f9d7dc84251d92b4d7ff03
jch: e3cb78b4131db2f98330ff110525db31c6abff16
next: 17fedb746fde9e40924a6ce11c0976a097eb126b
master: d166e6afe5f257217836ef24a73764eba390c58d
master@{1}: 8858448bb49332d353febc078ce4a3abcc962efe

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
a849d4c48b builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/describe.c
a849d4c48b builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/pack-objects.c
a849d4c48b builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

diff.c
b613de67c4  316) ret |= COLOR_MOVED_WS_ERROR;
b613de67c4  348) unsigned cm = parse_color_moved_ws(value);
b613de67c4  349) if (cm & COLOR_MOVED_WS_ERROR)

fast-import.c
a849d4c48b 2935) buf = repo_read_object_file(the_repository, oid, &type, 
&size);
a849d4c48b 3041) buf = repo_read_object_file(the_repository, oid, &unused,

fsck.c
a849d4c48b  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
a849d4c48b  878) repo_read_object_file(the_repository,
a849d4c48b  879)       &tag->object.oid, &type, &size);

http-push.c
a849d4c48b 1635) if (!repo_has_object_file(the_repository, &head_oid))
a849d4c48b 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

negotiator/default.c
a849d4c48b  71) if (repo_parse_commit(the_repository, commit))

remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
a849d4c48b  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
a849d4c48b 1643) repo_unuse_commit_buffer(the_repository, head_commit,
a849d4c48b 3914) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
e2419f7e30 1378) strbuf_release(&gitdir);
7454fe5cb6 1501) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1505) get_next_submodule_task_release(task);
7454fe5cb6 1532) return 0;
7454fe5cb6 1536) goto out;
7454fe5cb6 1551) return 0;

tree.c
a849d4c48b 108) if (repo_parse_commit(the_repository, commit))

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Junio C Hamano      a849d4c48: merge-fix/dl/remote-save-to-push
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup
Stefan Beller      b613de67c: diff: differentiate error handling in 
parse_color_moved_ws
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 420) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 459) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 583) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 618) fprintf_ln(stderr, _("Checking object 
directory"));
287d68a44b builtin/fsck.c 636) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
287d68a44b builtin/fsck.c 641) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 670) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 686) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pack-objects.c
ca473cef91 builtin/pack-objects.c 2086) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2087) oid_to_hex(&trg_entry->idx.oid), 
(uintmax_t)sz,
ca473cef91 builtin/pack-objects.c 2113) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2114) oid_to_hex(&src_entry->idx.oid), 
(uintmax_t)sz,

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/rebase.c
3249c1251e  544) ret = -1;
3249c1251e  545) goto leave_reset_head;
bac2a1e36f  549) ret = error(_("could not determine HEAD revision"));
bac2a1e36f  550) goto leave_reset_head;
3249c1251e  568) ret = error(_("could not read index"));
3249c1251e  569) goto leave_reset_head;
bac2a1e36f  573) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
bac2a1e36f  574) goto leave_reset_head;
3249c1251e  578) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
3249c1251e  579) goto leave_reset_head;
3249c1251e  592) goto leave_reset_head;

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
287d68a44b 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
287d68a44b 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

bundle.c
74ae4b638d 380) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
ca473cef91 2958) strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 658) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

protocol.c
c95f252809  37) die(_("Unrecognized protocol version"));
c95f252809  39) die(_("Unrecognized protocol_version"));

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2250) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2285) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3071) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3217) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  238) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  247) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  255) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2380) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
0b9c3afdbf  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  417) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  683) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  693) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1066) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1785) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1798) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1893) die(_("revision walk setup failed"));
0b9c3afdbf 2166) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
18e711a162 2387) opts->quiet = 1;
f11c958054 3977) res = error_dirty_index(r->index, opts);

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;
f0eaf63819 sha1-file.c 2207) return r;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Johannes Schindelin      3249c1251: rebase: consolidate clean-up code 
before leaving reset_head()
Johannes Schindelin      bac2a1e36: built-in rebase: reinstate `checkout 
-q` behavior where appropriate
Josh Steadmon      c95f25280: protocol: advertise multiple supported 
versions
Junio C Hamano      287d68a44: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Torsten Bögershausen      ca473cef9: Upcast size_t variables to 
uintmax_t when printing



Uncovered code in 'next' not in 'master'
--------------------------------------------

apply.c
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

builtin/am.c
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/cat-file.c
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/grep.c
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/log.c
517fe807d6 builtin/log.c 1196) BUG_ON_OPT_NEG(unset);

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/show-branch.c
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

midx.c
name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

preload-index.c
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

revision.c
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3048) continue;
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

Commits introducing uncovered code:
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      fce566480: am: handle --no-patch-format option
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/add.c
d1664e73ad builtin/add.c 458) die(_("index file corrupt"));

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));

builtin/fetch.c
builtin/fsck.c
b29759d89a builtin/fsck.c 613) fprintf(stderr, "Checking %s link\n", 
head_ref_name);
b29759d89a builtin/fsck.c 618) return error("Invalid %s", head_ref_name);

builtin/grep.c
76e9bdc437 builtin/grep.c  439) grep_read_unlock();

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 580) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 616) continue;

combine-diff.c
0074c9110d  377) state->sline[state->nb-1].p_lno =
0074c9110d  378) xcalloc(state->num_parent, sizeof(unsigned long));

date.c
c27cc94fad  904) tm->tm_mon = number-1;
c27cc94fad  908) else if (number > 69 && number < 100)
c27cc94fad  909) tm->tm_year = number;
c27cc94fad  910) else if (number < 38)
c27cc94fad  911) tm->tm_year = 100 + number;
c27cc94fad  952) pending_number(tm, num);

dir.c
8a2c174677  287) name = to_free = xmemdupz(name, namelen);

midx.c
1dcd9f2043  184) return;

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
85daa01f6b 1219) continue;
85daa01f6b 1225) continue;

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));

setup.c
58b284a2e9  413) return config_error_nonbool(var);

submodule-config.c
bcbc780d14 739) return CONFIG_INVALID_KEY;
45f5ef3d77 754) warning(_("Could not update .gitmodules entry %s"), key);

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

xdiff-interface.c
xdiff/xutils.c
611e42a598 405) return -1;

Commits introducing uncovered code:
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Ben Peart      d1664e73a: add: speed up cmd_add() by utilizing 
read_cache_preload()
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      85daa01f6: remote: make add_missing_tags() linear
Jeff King      0074c9110: combine-diff: use an xdiff hunk callback
Jeff King      611e42a59: xdiff: provide a separate emit callback for hunks
Jeff King      8a2c17467: pathspec: handle non-terminated strings with 
:(attr)
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Jeff King      c27cc94fa: approxidate: handle pending number for "specials"
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      b29759d89: fsck: check HEAD and reflog from 
other worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Phillip Wood      bcd33ec25: add read_author_script() to libgit


^ permalink raw reply	[relevance 3%]

* Re: [PATCH 2/9] submodule--helper: prefer strip_suffix() to ends_with()
  @ 2018-11-12 18:23  7%   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-12 18:23 UTC (permalink / raw)
  To: Jeff King
  Cc: gerardu, Ævar Arnfjörð Bjarmason, Junio C Hamano,
	git, René Scharfe, tikuta

On Mon, Nov 12, 2018 at 6:47 AM Jeff King <peff@peff.net> wrote:
>
> Using strip_suffix() lets us avoid repeating ourselves. It also makes
> the handling of "/" a bit less subtle (we strip one less character than
> we matched in order to leave it in place, but we can just as easily
> include the "/" when we add more path components).
>
> Signed-off-by: Jeff King <peff@peff.net>

This makes sense. Thanks!

(This patch caught my attention as it's a submodule thing,
but now looking at the rest of the series)

^ permalink raw reply	[relevance 7%]

* Git Test Coverage Report (Wednesday, Nov 7)
@ 2018-11-07 14:37  4% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-07 14:37 UTC (permalink / raw)
  To: Git List

Here is the coverage report for today.

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=251&view=logs

---

pu: 381b31f0006e46fe041e7fc6e5f7b19da5ccd889
jch: ab76604d6537afa18c9d8588c08f699c1f539659
next: 8438c0b2453a7207c9c45756f5e37dfe283db602
master: 8858448bb49332d353febc078ce4a3abcc962efe
master@{1}: d582ea202b626dcc6c3b01e1e11a296d9badd730

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
381b31f000 builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/describe.c
381b31f000 builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/pack-objects.c
381b31f000 builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

diff.c
b613de67c4  316) ret |= COLOR_MOVED_WS_ERROR;
b613de67c4  348) unsigned cm = parse_color_moved_ws(value);
b613de67c4  349) if (cm & COLOR_MOVED_WS_ERROR)

fast-import.c
381b31f000 2935) buf = repo_read_object_file(the_repository, oid, &type, 
&size);
381b31f000 3041) buf = repo_read_object_file(the_repository, oid, &unused,

fsck.c
381b31f000  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
381b31f000  878) repo_read_object_file(the_repository,
381b31f000  879)       &tag->object.oid, &type, &size);

http-push.c
381b31f000 1635) if (!repo_has_object_file(the_repository, &head_oid))
381b31f000 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

negotiator/default.c
381b31f000  71) if (repo_parse_commit(the_repository, commit))

remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
381b31f000  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
381b31f000 1624) repo_unuse_commit_buffer(the_repository, head_commit,
381b31f000 3868) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
e2419f7e30 1378) strbuf_release(&gitdir);
7454fe5cb6 1501) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1505) get_next_submodule_task_release(task);
7454fe5cb6 1532) return 0;
7454fe5cb6 1536) goto out;
7454fe5cb6 1551) return 0;

tree.c
381b31f000 108) if (repo_parse_commit(the_repository, commit))

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Junio C Hamano      381b31f00: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup
Stefan Beller      b613de67c: diff: differentiate error handling in 
parse_color_moved_ws
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

archive.c
8a705c4638 399) die(_("not a valid object name: %s"), name);
8a705c4638 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
8a705c4638 422) die(_("current working directory is untracked"));

attr.c
aa4fa3fa79  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

builtin/am.c
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/cat-file.c
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/fsck.c
0a995c2567 builtin/fsck.c  87) ret = _("unknown");
0a995c2567 builtin/fsck.c 164) objerror(parent, _("wrong object type in 
link"));
0a995c2567 builtin/fsck.c 275) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
0a995c2567 builtin/fsck.c 303) error(_("could not create lost-found"));
0a995c2567 builtin/fsck.c 310) die_errno(_("could not write '%s'"), 
filename);
0a995c2567 builtin/fsck.c 314) die_errno(_("could not finish '%s'"),
0a995c2567 builtin/fsck.c 331) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
0a995c2567 builtin/fsck.c 349) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
0a995c2567 builtin/fsck.c 368) fprintf_ln(stderr, _("Checking %s %s"),
0a995c2567 builtin/fsck.c 381) printf_ln(_("root %s"),
0a995c2567 builtin/fsck.c 417) return error(_("%s: object corrupt or 
missing"),
0a995c2567 builtin/fsck.c 456) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
0a995c2567 builtin/fsck.c 580) error(_("%s: object could not be parsed: 
%s"),
0a995c2567 builtin/fsck.c 615) fprintf_ln(stderr, _("Checking object 
directory"));
e4d034baf2 builtin/fsck.c 633) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
e4d034baf2 builtin/fsck.c 638) return error(_("invalid %s"), head_ref_name);
0a995c2567 builtin/fsck.c 667) fprintf_ln(stderr, _("Checking cache tree"));
0a995c2567 builtin/fsck.c 683) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/grep.c
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/log.c
517fe807d6 builtin/log.c 1196) BUG_ON_OPT_NEG(unset);

builtin/merge.c
23c0ab7312 builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/read-tree.c
517fe807d6 builtin/read-tree.c  47) BUG_ON_OPT_NEG(unset);

builtin/reflog.c
977e72ca96 builtin/reflog.c 592) usage(_(reflog_expire_usage));
977e72ca96 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
977e72ca96 builtin/reflog.c 689) usage(_(reflog_delete_usage));
977e72ca96 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
977e72ca96 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
977e72ca96 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
977e72ca96 builtin/reflog.c 744) usage(_(reflog_exists_usage));
977e72ca96 builtin/reflog.c 752) usage(_(reflog_exists_usage));
977e72ca96 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
0e1a23ceca 200) die(_("could not start pack-objects to repack promisor 
objects"));
e4d034baf2 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
0e1a23ceca 250) die_errno(_("unable to create '%s'"), promisor_name);
e4d034baf2 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/show-branch.c
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

git.c
4a4f8ae763 341) die_errno(_("while expanding alias '%s': '%s'"),
4a4f8ae763 350) die(_("alias '%s' changes environment variables.\n"
4a4f8ae763 358) die(_("empty alias for %s"), alias_command);
4a4f8ae763 361) die(_("recursive alias: %s"), alias_command);
4a4f8ae763 412) die(_("%s doesn't support --super-prefix"), p->cmd);
4a4f8ae763 436) die_errno(_("write failure on standard output"));
4a4f8ae763 438) die(_("unknown write failure on standard output"));
4a4f8ae763 440) die_errno(_("close failed on standard output"));
4a4f8ae763 658) die(_("%s doesn't support --super-prefix"), argv[0]);
4a4f8ae763 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

merge-recursive.c
55ea0bf4c1 1584) return -1;
55ea0bf4c1 1587) return -1;
55ea0bf4c1 1593) return -1;
55ea0bf4c1 1596) return -1;
55ea0bf4c1 1663) return -1;
55ea0bf4c1 1666) return -1;
55ea0bf4c1 1669) return -1;
143dc79002 1702) return -1;
f10ffbb2ff 1737) return -1;
f10ffbb2ff 1785) return -1;
f10ffbb2ff 1801) return -1;
f10ffbb2ff 1804) return -1;
f10ffbb2ff 1814) return -1;
f10ffbb2ff 1830) return -1;
f10ffbb2ff 1833) return -1;

midx.c
name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

parse-options-cb.c
23c0ab7312  21) return error(_("option `%s' expects a numerical value"),
23c0ab7312  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
23c0ab7312  88) return error(_("%s takes no value"), optname(opt, flags));
23c0ab7312  90) return error(_("%s isn't available"), optname(opt, flags));
23c0ab7312  92) return error(_("%s takes no value"), optname(opt, flags));
23c0ab7312 178) return error(_("%s expects a numerical value"),
23c0ab7312 194) return error(_("%s expects a non-negative integer value"
e7dd7bc3fd 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
e7dd7bc3fd 651) error(_("unknown non-ascii option in string: `%s'"),
23c0ab7312 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

preload-index.c
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
567e20ae23  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
567e20ae23  676)     ce->name, alias->name);
567e20ae23  691) die(_("cannot create an empty blob in the object 
database"));
567e20ae23  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
567e20ae23  786) return error(_("unable to add '%s' to index"), path);
567e20ae23  822) error(_("invalid path '%s'"), path);
567e20ae23  848) error(_("invalid path '%s'"), path);
567e20ae23 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
567e20ae23 1689) return error(_("bad index version %d"), hdr_version);
567e20ae23 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
567e20ae23 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
567e20ae23 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
567e20ae23 1848) die(_("unordered stage entries in index"));
567e20ae23 1851) die(_("multiple stage entries for merged file '%s'"),
567e20ae23 1854) die(_("unordered stage entries for '%s'"),
567e20ae23 2148) die_errno(_("%s: index file open failed"), path);
567e20ae23 2152) die_errno(_("%s: cannot stat the open index"), path);
567e20ae23 2156) die(_("%s: index file smaller than expected"), path);
567e20ae23 2160) die_errno(_("%s: unable to map index file"), path);
567e20ae23 2250) warning(_("could not freshen shared index '%s'"), 
shared_index);
567e20ae23 2285) die(_("broken index, expect %s in %s, got %s"),
567e20ae23 3071) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
567e20ae23 3217) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
23c0ab7312 2326) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
eafdc91bbc  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
eafdc91bbc  417) error(_("more than one uploadpack given, using the 
first"));
eafdc91bbc  683) die(_("key '%s' of pattern had no '*'"), key);
eafdc91bbc  693) die(_("value '%s' of pattern has no '*'"), value);
eafdc91bbc 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
eafdc91bbc 1066) return error(_("dst ref %s receives from more than one 
src"),
eafdc91bbc 1785) die(_("couldn't find remote ref %s"), name);
eafdc91bbc 1798) error(_("* Ignoring funny ref '%s' locally"),
eafdc91bbc 1893) die(_("revision walk setup failed"));
eafdc91bbc 2166) return error(_("cannot parse expected object name '%s'"),

revision.c
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3048) continue;
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Elijah Newren      143dc7900: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      55ea0bf4c: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      f10ffbb2f: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      fce566480: am: handle --no-patch-format option
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Junio C Hamano      e4d034baf: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      0a995c256: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      0e1a23cec: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      23c0ab731: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      4a4f8ae76: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      567e20ae2: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      8a705c463: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      977e72ca9: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      aa4fa3fa7: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      e7dd7bc3f: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      eafdc91bb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/add.c
d1664e73ad builtin/add.c 458) die(_("index file corrupt"));

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));

builtin/fetch.c
builtin/fsck.c
b29759d89a builtin/fsck.c 613) fprintf(stderr, "Checking %s link\n", 
head_ref_name);
b29759d89a builtin/fsck.c 618) return error("Invalid %s", head_ref_name);

builtin/grep.c
76e9bdc437 builtin/grep.c  439) grep_read_unlock();

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 580) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 616) continue;

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

combine-diff.c
0074c9110d  377) state->sline[state->nb-1].p_lno =
0074c9110d  378) xcalloc(state->num_parent, sizeof(unsigned long));

date.c
c27cc94fad  904) tm->tm_mon = number-1;
c27cc94fad  908) else if (number > 69 && number < 100)
c27cc94fad  909) tm->tm_year = number;
c27cc94fad  910) else if (number < 38)
c27cc94fad  911) tm->tm_year = 100 + number;
c27cc94fad  952) pending_number(tm, num);

dir.c
8a2c174677  287) name = to_free = xmemdupz(name, namelen);

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

midx.c
1dcd9f2043  184) return;

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
85daa01f6b 1219) continue;
85daa01f6b 1225) continue;

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));

setup.c
58b284a2e9  413) return config_error_nonbool(var);

submodule-config.c
bcbc780d14 739) return CONFIG_INVALID_KEY;
45f5ef3d77 754) warning(_("Could not update .gitmodules entry %s"), key);

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

xdiff-interface.c
xdiff/xutils.c
611e42a598 405) return -1;

Commits introducing uncovered code:
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Ben Peart      d1664e73a: add: speed up cmd_add() by utilizing 
read_cache_preload()
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      85daa01f6: remote: make add_missing_tags() linear
Jeff King      0074c9110: combine-diff: use an xdiff hunk callback
Jeff King      611e42a59: xdiff: provide a separate emit callback for hunks
Jeff King      8a2c17467: pathspec: handle non-terminated strings with 
:(attr)
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Jeff King      c27cc94fa: approxidate: handle pending number for "specials"
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      b29759d89: fsck: check HEAD and reflog from 
other worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Phillip Wood      bcd33ec25: add read_author_script() to libgit



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

gpg-interface.c
4de9394dcb 155) break;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed




^ permalink raw reply	[relevance 4%]

* Re: [PATCH] gitk: don't highlight submodule diff lines outside submodule diffs
  2018-11-06 20:06  5% ` Stefan Beller
@ 2018-11-06 21:56  7%   ` Роман Донченко
  0 siblings, 0 replies; 200+ results
From: Роман Донченко @ 2018-11-06 21:56 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, Paul Mackerras

06.11.2018 23:06, Stefan Beller пишет:
> On Tue, Nov 6, 2018 at 12:03 PM Роман Донченко <dpb@corrigendum.ru> wrote:
>>
>> A line that starts with "  <" or "  >" is not necessarily a submodule
>> diff line. It might just be a context line in a normal diff, representing
>> a line starting with " <" or " >" respectively.
>>
>> Use the currdiffsubmod variable to track whether we are currently
>> inside a submodule diff and only highlight these lines if we are.
> 
> This explanation makes sense, some prior art is at
> https://public-inbox.org/git/20181021163401.4458-1-dummy@example.com/
> which was not taken AFAICT.

Didn't see that patch. That said, I think it's incorrect, since it never 
resets currdiffsubmod back to the empty string, so if a normal diff 
follows a submodule diff, the same issue will occur.

(The `set $currdiffsubmod ""` lines that are already there are 
effectively useless because they set the variable whose name is the 
contents of currdiffsubmod, rather than currdiffsubmod itself. I assume
it was a typo.)

-Roman

> 
> Thanks,
> Stefan
> 
>>
>> Signed-off-by: Роман Донченко <dpb@corrigendum.ru>
>> ---
>>   gitk | 8 ++++----
>>   1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/gitk b/gitk
>> index a14d7a1..6bb6dc6 100755
>> --- a/gitk
>> +++ b/gitk
>> @@ -8109,6 +8109,8 @@ proc parseblobdiffline {ids line} {
>>          }
>>          # start of a new file
>>          set diffinhdr 1
>> +       set currdiffsubmod ""
>> +
>>          $ctext insert end "\n"
>>          set curdiffstart [$ctext index "end - 1c"]
>>          lappend ctext_file_names ""
>> @@ -8191,12 +8193,10 @@ proc parseblobdiffline {ids line} {
>>          } else {
>>              $ctext insert end "$line\n" filesep
>>          }
>> -    } elseif {![string compare -length 3 "  >" $line]} {
>> -       set $currdiffsubmod ""
>> +    } elseif {$currdiffsubmod ne "" && ![string compare -length 3 "  >" $line]} {
>>          set line [encoding convertfrom $diffencoding $line]
>>          $ctext insert end "$line\n" dresult
>> -    } elseif {![string compare -length 3 "  <" $line]} {
>> -       set $currdiffsubmod ""
>> +    } elseif {$currdiffsubmod ne "" && ![string compare -length 3 "  <" $line]} {
>>          set line [encoding convertfrom $diffencoding $line]
>>          $ctext insert end "$line\n" d0
>>       } elseif {$diffinhdr} {
>> --
>> 2.19.1.windows.1
>>

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] gitk: don't highlight submodule diff lines outside submodule diffs
  @ 2018-11-06 20:06  5% ` Stefan Beller
  2018-11-06 21:56  7%   ` Роман Донченко
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-06 20:06 UTC (permalink / raw)
  To: dpb; +Cc: git, Paul Mackerras

On Tue, Nov 6, 2018 at 12:03 PM Роман Донченко <dpb@corrigendum.ru> wrote:
>
> A line that starts with "  <" or "  >" is not necessarily a submodule
> diff line. It might just be a context line in a normal diff, representing
> a line starting with " <" or " >" respectively.
>
> Use the currdiffsubmod variable to track whether we are currently
> inside a submodule diff and only highlight these lines if we are.

This explanation makes sense, some prior art is at
https://public-inbox.org/git/20181021163401.4458-1-dummy@example.com/
which was not taken AFAICT.

Thanks,
Stefan

>
> Signed-off-by: Роман Донченко <dpb@corrigendum.ru>
> ---
>  gitk | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/gitk b/gitk
> index a14d7a1..6bb6dc6 100755
> --- a/gitk
> +++ b/gitk
> @@ -8109,6 +8109,8 @@ proc parseblobdiffline {ids line} {
>         }
>         # start of a new file
>         set diffinhdr 1
> +       set currdiffsubmod ""
> +
>         $ctext insert end "\n"
>         set curdiffstart [$ctext index "end - 1c"]
>         lappend ctext_file_names ""
> @@ -8191,12 +8193,10 @@ proc parseblobdiffline {ids line} {
>         } else {
>             $ctext insert end "$line\n" filesep
>         }
> -    } elseif {![string compare -length 3 "  >" $line]} {
> -       set $currdiffsubmod ""
> +    } elseif {$currdiffsubmod ne "" && ![string compare -length 3 "  >" $line]} {
>         set line [encoding convertfrom $diffencoding $line]
>         $ctext insert end "$line\n" dresult
> -    } elseif {![string compare -length 3 "  <" $line]} {
> -       set $currdiffsubmod ""
> +    } elseif {$currdiffsubmod ne "" && ![string compare -length 3 "  <" $line]} {
>         set line [encoding convertfrom $diffencoding $line]
>         $ctext insert end "$line\n" d0
>      } elseif {$diffinhdr} {
> --
> 2.19.1.windows.1
>

^ permalink raw reply	[relevance 5%]

* Git Test Coverage Report (Friday, Nov 2)
@ 2018-11-03  2:16  3% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-03  2:16 UTC (permalink / raw)
  To: git@vger.kernel.org

Here is the coverage report for today. Some builds were timing out, so I 
removed the tests with number 9000 or more from the build [1]. Hopefully 
this is a temporary measure.

Thanks,

-Stolee

[1] 
https://dev.azure.com/git/git/_build/results?buildId=250&_a=summary&view=logs

---

pu: 44234e885f450a57812806cefe0d4aa3f43f2800
jch: 35594a3ecc09908facb9790ba3817ad08d2af8e1
next: 96ac06677ac950c97d331f0ef4892125027eff39
master: d582ea202b626dcc6c3b01e1e11a296d9badd730
master@{1}: 4ede3d42dfb57f9a41ac96a1f216c62eb7566cc2

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
44234e885f builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    924) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    925) break;

builtin/describe.c
44234e885f builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/fsck.c
255a564e58 builtin/fsck.c 622) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
255a564e58 builtin/fsck.c 627) return error(_("invalid %s"), head_ref_name);

builtin/grep.c
76e9bdc437 builtin/grep.c  429) grep_read_unlock();

builtin/pack-objects.c
44234e885f builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 585) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 621) continue;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fast-import.c
44234e885f 2935) buf = repo_read_object_file(the_repository, oid, &type, 
&size);
44234e885f 3041) buf = repo_read_object_file(the_repository, oid, &unused,

fsck.c
44234e885f  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
44234e885f  878) repo_read_object_file(the_repository,
44234e885f  879)       &tag->object.oid, &type, &size);

http-push.c
44234e885f 1635) if (!repo_has_object_file(the_repository, &head_oid))
44234e885f 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

merge-recursive.c
4cdc48e412 1585) return -1;
4cdc48e412 1588) return -1;
4cdc48e412 1594) return -1;
4cdc48e412 1596) if (update_file(o, 1, b_oid, b_mode, collide_path))
4cdc48e412 1597) return -1;
4cdc48e412 1664) return -1;
4cdc48e412 1667) return -1;
4cdc48e412 1670) return -1;
b58ae691c0 1703) return -1;
387361a6a7 1738) return -1;
387361a6a7 1786) return -1;
387361a6a7 1795) new_path = unique_path(o, a->path, ci->branch1);
387361a6a7 1796) output(o, 1, _("Refusing to lose untracked file"
387361a6a7 1802) return -1;
387361a6a7 1805) return -1;
387361a6a7 1815) return -1;
387361a6a7 1831) return -1;
387361a6a7 1834) return -1;

negotiator/default.c
44234e885f  71) if (repo_parse_commit(the_repository, commit))

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
44234e885f  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
44234e885f 1624) repo_unuse_commit_buffer(the_repository, head_commit,
44234e885f 3868) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule-config.c
bcbc780d14 740) return CONFIG_INVALID_KEY;
45f5ef3d77 755) warning(_("Could not update .gitmodules entry %s"), key);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
e2419f7e30 1378) strbuf_release(&gitdir);
7454fe5cb6 1501) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1505) get_next_submodule_task_release(task);
7454fe5cb6 1532) return 0;
7454fe5cb6 1536) goto out;
7454fe5cb6 1551) return 0;

tree.c
44234e885f 108) if (repo_parse_commit(the_repository, commit))

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Elijah Newren      387361a6a: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      4cdc48e41: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      b58ae691c: merge-recursive: fix rename/add conflict 
handling
Junio C Hamano      255a564e5: Merge branch 
'nd/per-worktree-ref-iteration' into pu
Junio C Hamano      44234e885: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

archive.c
48a40549d5 399) die(_("'%s' is not a valid object name"), name);
48a40549d5 412) die(_("%s is not a tree object"), oid_to_hex(&oid));
48a40549d5 422) die(_("current working directory is untracked"));

attr.c
847aa0ff7a  369) fprintf(stderr, _("%s not allowed: %s:%d\n"),

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));

builtin/fetch.c
builtin/fsck.c
09120ea781 builtin/fsck.c 154) objerror(parent, _("wrong object type in 
link"));
09120ea781 builtin/fsck.c 265) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
09120ea781 builtin/fsck.c 293) error(_("could not create lost-found"));
09120ea781 builtin/fsck.c 300) die_errno(_("could not write '%s'"), 
filename);
09120ea781 builtin/fsck.c 304) die_errno(_("could not finish '%s'"),
09120ea781 builtin/fsck.c 321) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
09120ea781 builtin/fsck.c 339) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
09120ea781 builtin/fsck.c 358) fprintf_ln(stderr, _("Checking %s %s"),
09120ea781 builtin/fsck.c 371) printf_ln(_("root %s"),
09120ea781 builtin/fsck.c 407) return error(_("%s: object corrupt or 
missing"),
09120ea781 builtin/fsck.c 446) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
09120ea781 builtin/fsck.c 545) error(_("%s: object could not be parsed: 
%s"),
09120ea781 builtin/fsck.c 580) fprintf_ln(stderr, _("Checking object 
directory"));
09120ea781 builtin/fsck.c 596) fprintf_ln(stderr, _("Checking HEAD link"));
09120ea781 builtin/fsck.c 601) return error(_("invalid HEAD"));
09120ea781 builtin/fsck.c 628) fprintf_ln(stderr, _("Checking cache tree"));
09120ea781 builtin/fsck.c 644) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/grep.c
389f2f2d79 builtin/grep.c 1034) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/merge.c
35408df41e builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/reflog.c
b9c4009cca builtin/reflog.c 563) usage(_(reflog_expire_usage));
b9c4009cca builtin/reflog.c 605) status |= error(_("%s points 
nowhere!"), argv[i]);
b9c4009cca builtin/reflog.c 651) usage(_(reflog_delete_usage));
b9c4009cca builtin/reflog.c 657) return error(_("nothing to delete?"));
b9c4009cca builtin/reflog.c 666) status |= error(_("not a reflog: %s"), 
argv[i]);
b9c4009cca builtin/reflog.c 671) status |= error(_("no reflog for 
'%s'"), argv[i]);
b9c4009cca builtin/reflog.c 706) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 714) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 717) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
eb6c5a15dc 200) die(_("could not start pack-objects to repack promisor 
objects"));
55b48d6630 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
eb6c5a15dc 250) die_errno(("unable to create '%s'"), promisor_name);
55b48d6630 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

combine-diff.c
3bf45e7f67  377) state->sline[state->nb-1].p_lno =
3bf45e7f67  378) xcalloc(state->num_parent, sizeof(unsigned long));

date.c
c27cc94fad  904) tm->tm_mon = number-1;
c27cc94fad  908) else if (number > 69 && number < 100)
c27cc94fad  909) tm->tm_year = number;
c27cc94fad  910) else if (number < 38)
c27cc94fad  911) tm->tm_year = 100 + number;
c27cc94fad  952) pending_number(tm, num);

dir.c
8a2c174677  287) name = to_free = xmemdupz(name, namelen);

git.c
b63c352c11 341) die_errno(_("while expanding alias '%s': '%s'"),
b63c352c11 350) die(_("alias '%s' changes environment variables.\n"
b63c352c11 358) die(_("empty alias for %s"), alias_command);
b63c352c11 361) die(_("recursive alias: %s"), alias_command);
b63c352c11 436) die_errno(_("write failure on standard output"));
b63c352c11 438) die(_("unknown write failure on standard output"));
b63c352c11 440) die_errno(_("close failed on standard output"));
b63c352c11 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

midx.c
1dcd9f2043  184) return;

name-hash.c
31bfd155d8 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
31bfd155d8 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
31bfd155d8 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

parse-options-cb.c
35408df41e  21) return error(_("option `%s' expects a numerical value"),
35408df41e  58) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
35408df41e  88) return error(_("%s takes no value"), optname(opt, flags));
35408df41e  90) return error(_("%s isn't available"), optname(opt, flags));
35408df41e  92) return error(_("%s takes no value"), optname(opt, flags));
35408df41e 178) return error(_("%s expects a numerical value"),
35408df41e 194) return error(_("%s expects a non-negative integer value"
e0948db833 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
e0948db833 651) error(_("unknown non-ascii option in string: `%s'"),
35408df41e 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

preload-index.c
31bfd155d8 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
5257b0625a  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
5257b0625a  676)     ce->name, alias->name);
5257b0625a  691) die(_("cannot create an empty blob in the object 
database"));
5257b0625a  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
5257b0625a  786) return error(_("unable to add '%s' to index"), path);
5257b0625a  822) error(_("invalid path '%s'"), path);
5257b0625a  848) error(_("invalid path '%s'"), path);
5257b0625a 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
5257b0625a 1689) return error(_("bad index version %d"), hdr_version);
5257b0625a 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
5257b0625a 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
5257b0625a 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
5257b0625a 1848) die(_("unordered stage entries in index"));
5257b0625a 1851) die(_("multiple stage entries for merged file '%s'"),
5257b0625a 1854) die(_("unordered stage entries for '%s'"),
5257b0625a 2148) die_errno(_("%s: index file open failed"), path);
5257b0625a 2152) die_errno(_("%s: cannot stat the open index"), path);
5257b0625a 2156) die(_("%s: index file smaller than expected"), path);
5257b0625a 2160) die_errno(_("%s: unable to map index file"), path);
5257b0625a 2252) warning(_("could not freshen shared index '%s'"), 
shared_index);
5257b0625a 2287) die(_("broken index, expect %s in %s, got %s"),
5257b0625a 3073) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
5257b0625a 3219) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
35408df41e 2324) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
a454d6a26b  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
a454d6a26b  417) error(_("more than one uploadpack given, using the 
first"));
a454d6a26b  683) die(_("key '%s' of pattern had no '*'"), key);
a454d6a26b  693) die(_("value '%s' of pattern has no '*'"), value);
a454d6a26b 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
a454d6a26b 1066) return error(_("dst ref %s receives from more than one 
src"),
a454d6a26b 1753) die(_("couldn't find remote ref %s"), name);
a454d6a26b 1766) error(_("* Ignoring funny ref '%s' locally"),
a454d6a26b 1861) die(_("revision walk setup failed"));
a454d6a26b 2134) return error(_("cannot parse expected object name '%s'"),

revision.c
b45424181e 2936) return;
b45424181e 2939) return;
b45424181e 2945) c->object.flags |= UNINTERESTING;
b45424181e 2948) return;
b45424181e 2951) mark_parents_uninteresting(c);
b45424181e 2974) return;
b45424181e 2977) return;
b45424181e 3042) continue;
f0d9cc4196 3091) if (!revs->ignore_missing_links)
f0d9cc4196 3092) die("Failed to traverse parents of commit %s",
f0d9cc4196 3093)     oid_to_hex(&commit->object.oid));
b45424181e 3101) continue;

run-command.c
31bfd155d8 1229) error(_("cannot create async thread: %s"), strerror(err));

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

xdiff-interface.c
xdiff/xutils.c
611e42a598 405) return -1;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Jeff King      3bf45e7f6: combine-diff: use an xdiff hunk callback
Jeff King      611e42a59: xdiff: provide a separate emit callback for hunks
Jeff King      8a2c17467: pathspec: handle non-terminated strings with 
:(attr)
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Jeff King      c27cc94fa: approxidate: handle pending number for "specials"
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Junio C Hamano      55b48d663: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      09120ea78: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      31bfd155d: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      35408df41: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      389f2f2d7: grep: remove #ifdef NO_PTHREADS
Nguyễn Thái Ngọc Duy      48a40549d: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      5257b0625: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      847aa0ff7: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      a454d6a26: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      b63c352c1: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      b9c4009cc: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      e0948db83: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      eb6c5a15d: repack: mark more strings for 
translation
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Phillip Wood      bcd33ec25: add read_author_script() to libgit



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

gpg-interface.c
4de9394dcb 155) break;

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

setup.c
58b284a2e9  413) return config_error_nonbool(var);

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
55071ea248   61) strbuf_trim(&out);
55071ea248   62) ret = !strcmp("true", out.buf);
55071ea248   63) strbuf_release(&out);
002ee2fe68  115) die(_("%s requires an interactive rebase"), option);
f95736288a  148) return error_errno(_("could not read '%s'"), path);
f95736288a  162) return -1;
f95736288a  167) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  178) return -1;
f95736288a  179) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  180) return -1;
f95736288a  182) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  186) return -1;
f95736288a  188) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  196) opts->signoff = 1;
73d51ed0a5  197) opts->flags |= REBASE_FORCE;
ead98c111b  204) return -1;
12026a412c  219) return -1;
ba1905a5fe  227) return -1;
ba1905a5fe  235) return -1;
6defce2b02  255) return error(_("Could not read '%s'"), path);
6defce2b02  273) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  277) return res;
bc24382c2b  375) argv_array_pushf(&child.args,
bc24382c2b  377) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  509) struct strbuf dir = STRBUF_INIT;
6defce2b02  511) apply_autostash(opts);
ac7f467fef  512) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  513) remove_dir_recursively(&dir, 0);
ac7f467fef  514) strbuf_release(&dir);
ac7f467fef  515) die("Nothing to do");
ac7f467fef  545) return -1;
ac7f467fef  549) rollback_lock_file(&lock);
ac7f467fef  550) return error(_("could not determine HEAD revision"));
ac7f467fef  567) rollback_lock_file(&lock);
ac7f467fef  568) return error(_("could not read index"));
ac7f467fef  572) error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef  573) rollback_lock_file(&lock);
ac7f467fef  574) free((void *)desc.buffer);
ac7f467fef  575) return -1;
ac7f467fef  588) ret = error(_("could not write index"));
ac7f467fef  592) return ret;
ac7f467fef  608) } else if (old_orig)
ac7f467fef  609) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  637) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  671) return 1;
9a48a615b4  687) return 0;
55071ea248  895) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  898) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  899) die_errno(_("could not exec %s"), path);
0eabf4b95c  917) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  954) usage_with_options(builtin_rebase_usage,
f95736288a  974) die(_("Cannot read HEAD"));
f95736288a  978) die(_("could not read index"));
f95736288a  992) exit(1);
122420c295 1004) die(_("could not discard worktree changes"));
122420c295 1006) exit(1);
5e5d96197c 1017) exit(1);
5e5d96197c 1020) die(_("could not move back to %s"),
5a61494539 1030) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1049) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1050) const char *state_dir_base =
c54dacb50e 1051) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1052) const char *cmd_live_rebase =
c54dacb50e 1054) strbuf_reset(&buf);
c54dacb50e 1055) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1056) die(_("It seems that there is already a %s directory, 
and\n"
53f9e5be94 1080) strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94 1081) options.flags |= REBASE_FORCE;
7998dbe1ec 1093) strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
3c3588c7d3 1125) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1126) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1148) die(_("--strategy requires --merge or --interactive"));
cda614e489 1166) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1175) options.state_dir = apply_dir();
ac7f467fef 1176) break;
ac7f467fef 1253) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1259) die(_("Could not create new root commit"));
e65123a71d 1309) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1317) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1329) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1342) die(_("could not read index"));
6defce2b02 1369) die(_("Cannot autostash"));
6defce2b02 1372) die(_("Unexpected stash response: '%s'"),
6defce2b02 1378) die(_("Could not create directory for '%s'"),
6defce2b02 1384) die(_("could not reset --hard"));
e65123a71d 1428) ret = !!error(_("could not parse '%s'"),
e65123a71d 1430) goto cleanup;
e65123a71d 1439) ret = !!error(_("could not switch to "
1ed9c14ff2 1449)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1450) puts(_("HEAD is up to date."));
9a48a615b4 1459)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1460) puts(_("HEAD is up to date, rebase forced."));

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

sequencer.c
65850686cf 2279) return;
65850686cf 2376) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3374) return error(_("could not checkout %s"), commit);
4df66c40b0 3388) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3408) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4772) return -1;
b97e187364 4775) return -1;
b97e187364 4781) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4784) todo_list_release(&todo_list);
b97e187364 4785) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4804) todo_list_release(&todo_list);
b97e187364 4805) return -1;
b97e187364 4809) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4813) return error(_("could not transform the todo list"));
b97e187364 4842) return error(_("could not transform the todo list"));
b97e187364 4845) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4851) return -1;

strbuf.c
f95736288a  127) --sb->len;

Commits introducing uncovered code:
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      53f9e5be9: builtin rebase: support `ignore-date` option
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      7998dbe1e: builtin rebase: support `-C` and 
`--whitespace=<type>`
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue




^ permalink raw reply	[relevance 3%]

* Re: submodule support in git-bundle
  2018-11-02 18:34  7%   ` Duy Nguyen
@ 2018-11-02 19:00  7%     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-02 19:00 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

> > This offloading-to-CDN (or "mostly resumable clone" in the
> > sense that the communication with the server is minimal, and
> > you get most of your data via resumable http range-requests)
> > sounds like complete offtopic, but is one of the requirements
> > for the repo to submodule migration, hence I came to speak of it.
>
> Hm.. so what you're saying is, we could have a pack file that lists
> other (real) pack files and for the bundle case they are all in the
> same file. And "download from $THERE" in this case is "download at
> this file offset"? That might actually work.

We're conflating 2 things here.
This idea of CDN offloading has nothing to do with submodules, it's
just a general thing to improve the fetch protocol.
And the pointed at file doesn't need to be a "real" packfile, as long
as the bytestream at the end looks like a real packfile. For example
the bytes to get from $THERE would not need to have a pack header
(or if it had, I would ask you to omit the first bytes containing the header)
as I can give the header myself.

The idea for submodules is more along the lines of having "just"
multiple pack files in the stream. For the bundle case we would
probably not have redirection to $THERE in there, as it should
be self contained completely (we don't know if the bundle recipient
can access $THERE in a timely manner).


> > Did you have other things in mind, on a higher level?
> > e.g. querying the bundle and creating submodule bundles
> > based off the superproject bundle? 'git bundle create' could
> > learn the --recurse-submodules option, which then produces
> > multiple bundle files without changing the file formats.
>
> This is probably the simplest way to support submodules.

Yep, that sounds simplest, but I think it makes for bad UX.
(Multiple files, need to be kept in some order and applied correctly)


> I just
> haven't really thought much about it (the problem just came up to me
> like 2 hours ago). Two problems with this are convenience (I don't
> want to handle multiple files) and submodule info (which pack should
> be unbundled on which submodule?). But I suppose if "git bundle"
> produces a tarball of these bundle files then you solve both.

The tarball makes it one file and would naturally provide some
order. It feels iffy, I'd rather have multiple packs in the bundle.

> But of course there may be other and better options like what you
> described above. If in long term we have "pack with hyperlinks" anyway
> for resumable clone and other fancy stuff then reusing the same
> mechanism for bundles makes sense, less maintenance burden.

I think of the hyperlinks in packs as an orthogonal feature, but closely
nearby in code and implementation, which is why I brought it up.

^ permalink raw reply	[relevance 7%]

* Re: submodule support in git-bundle
  2018-11-02 17:08  7% ` Stefan Beller
@ 2018-11-02 18:34  7%   ` Duy Nguyen
  2018-11-02 19:00  7%     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Duy Nguyen @ 2018-11-02 18:34 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Git Mailing List

On Fri, Nov 2, 2018 at 6:09 PM Stefan Beller <sbeller@google.com> wrote:
>
> On Fri, Nov 2, 2018 at 9:10 AM Duy Nguyen <pclouds@gmail.com> wrote:
> >
> > I use git-bundle today and it occurs to me that if I want to use it to
> > transfer part of a history that involves submodule changes, things
> > aren't pretty. Has anybody given thought on how to do binary history
> > transfer that contains changes from submodules?
> >
> > Since .bundle files are basically .pack files, i'm not sure if it's
> > easy to bundle multiple pack files (one per repo)...
>
> That is a really good discussion starter!
>
> As bundles are modeled after the fetch protocol, I would
> redirect the discussion there.
>
> The new fetch protocol could support sending more than
> one pack, which could be for both the superproject as
> well as the relevant submodule updates (i.e. what is recorded
> in the superproject) based on a new capability.
>
> We at Google have given this idea some thought, but from a
> different angle: As you may know currently Android uses the
> repo tool, which we want to replace with Gits native submodules
> eventually. The repo tool tests for each repository to clone if
> there is a bundle file for that repository, such that instead of
> cloning the repo, the bundle can be downloaded and then
> a catch-up fetch can be performed. (This helps the Git servers
> as well as the client, the bundle can be hosted on a CDN,
> which is faster and cheaper than a git server for us).
>
> So we've given some thought on extending the packfiles in the
> fetch protocol to have some redirection to a CDN possible,
> i.e. instead of sending bytes as is, you get more or less a "todo"
> list, which might be
>     (a) take the following bytes as is (current pack format)
>     (b) download these other bytes from $THERE
>         (possibly with a checksum)
> once the stream of bytes is assembled, it will look like a regular
> packfile with deltas etc.
>
> This offloading-to-CDN (or "mostly resumable clone" in the
> sense that the communication with the server is minimal, and
> you get most of your data via resumable http range-requests)
> sounds like complete offtopic, but is one of the requirements
> for the repo to submodule migration, hence I came to speak of it.

Hm.. so what you're saying is, we could have a pack file that lists
other (real) pack files and for the bundle case they are all in the
same file. And "download from $THERE" in this case is "download at
this file offset"? That might actually work.

> Did you have other things in mind, on a higher level?
> e.g. querying the bundle and creating submodule bundles
> based off the superproject bundle? 'git bundle create' could
> learn the --recurse-submodules option, which then produces
> multiple bundle files without changing the file formats.

This is probably the simplest way to support submodules. I just
haven't really thought much about it (the problem just came up to me
like 2 hours ago). Two problems with this are convenience (I don't
want to handle multiple files) and submodule info (which pack should
be unbundled on which submodule?). But I suppose if "git bundle"
produces a tarball of these bundle files then you solve both.

But of course there may be other and better options like what you
described above. If in long term we have "pack with hyperlinks" anyway
for resumable clone and other fancy stuff then reusing the same
mechanism for bundles makes sense, less maintenance burden.
-- 
Duy

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 19/24] submodule: use submodule repos for object lookup
  2018-11-02 17:23  5%     ` Stefan Beller
@ 2018-11-02 17:27  5%       ` Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-02 17:27 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, SZEDER Gábor, Jonathan Tan

On 11/2/2018 1:23 PM, Stefan Beller wrote:
> On Fri, Nov 2, 2018 at 6:03 AM Derrick Stolee <stolee@gmail.com> wrote:
>> On 10/30/2018 6:08 PM, Stefan Beller wrote:
>>> This converts the 'show_submodule_header' function to use
>>> the repository API properly, such that the submodule objects
>>> are not added to the main object store.
>>>
>>> Signed-off-by: Stefan Beller <sbeller@google.com>
>> A couple tests are broken in 'pu' when run with GIT_TEST_COMMIT_GRAPH=1,
>> including t4041-diff-submodule-option.sh. The failure bisects to this patch.
>>
>> Here is a verbose output of the first failure in that script:;
>>
>>
>> expecting success:
>>           git diff-index -p --submodule=log HEAD >actual &&
>>           cat >expected <<-EOF &&
>>           Submodule sm1 $head2..$head3 (rewind):
>>             < Add foo3 ($added foo3)
>>             < Add foo2 ($added foo2)
>>           EOF
>>           test_cmp expected actual
>>
>> + git diff-index -p --submodule=log HEAD
>> + cat
>> + test_cmp expected actual
>> + diff -u expected actual
>> --- expected    2018-11-02 12:58:43.429262380 +0000
>> +++ actual      2018-11-02 12:58:43.429262380 +0000
>> @@ -1,3 +1,5 @@
>> -Submodule sm1 30b9670..dafb207 (rewind):
>> +Submodule sm1 30b9670...dafb207:
>>      < Add foo3 (hinzugefügt foo3)
>>      < Add foo2 (hinzugefügt foo2)
>> +  > Add foo1 (hinzugefügt foo1)
>> +  < Add foo1 (hinzugefügt foo1)
>> error: last command exited with $?=1
>> not ok 9 - modified submodule(backward)
>>
>> I've been looking into the patch below to see if there is an obvious
>> problem, but the best I can think is that open_submodule() creates an
>> alternate 'struct repository' and somehow the commit-graph feature is
>> interacting poorly with that struct.
>>
>> Stefan, do you know what's going on?
> Sure, see the last four patches of this series
> https://public-inbox.org/git/20181030220817.61691-1-sbeller@google.com/
> (to which you also reply to? Junio did not queue this one, yet).

Sorry! Got a bit mixed up looking at everything. I didn't realize that 
the current 'pu' didn't have your latest. Thanks!


^ permalink raw reply	[relevance 5%]

* Re: [PATCH 19/24] submodule: use submodule repos for object lookup
  2018-11-02 13:03  8%   ` Derrick Stolee
@ 2018-11-02 17:23  5%     ` Stefan Beller
  2018-11-02 17:27  5%       ` Derrick Stolee
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-02 17:23 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, SZEDER Gábor, Jonathan Tan

On Fri, Nov 2, 2018 at 6:03 AM Derrick Stolee <stolee@gmail.com> wrote:
>
> On 10/30/2018 6:08 PM, Stefan Beller wrote:
> > This converts the 'show_submodule_header' function to use
> > the repository API properly, such that the submodule objects
> > are not added to the main object store.
> >
> > Signed-off-by: Stefan Beller <sbeller@google.com>
>
> A couple tests are broken in 'pu' when run with GIT_TEST_COMMIT_GRAPH=1,
> including t4041-diff-submodule-option.sh. The failure bisects to this patch.
>
> Here is a verbose output of the first failure in that script:;
>
>
> expecting success:
>          git diff-index -p --submodule=log HEAD >actual &&
>          cat >expected <<-EOF &&
>          Submodule sm1 $head2..$head3 (rewind):
>            < Add foo3 ($added foo3)
>            < Add foo2 ($added foo2)
>          EOF
>          test_cmp expected actual
>
> + git diff-index -p --submodule=log HEAD
> + cat
> + test_cmp expected actual
> + diff -u expected actual
> --- expected    2018-11-02 12:58:43.429262380 +0000
> +++ actual      2018-11-02 12:58:43.429262380 +0000
> @@ -1,3 +1,5 @@
> -Submodule sm1 30b9670..dafb207 (rewind):
> +Submodule sm1 30b9670...dafb207:
>     < Add foo3 (hinzugefügt foo3)
>     < Add foo2 (hinzugefügt foo2)
> +  > Add foo1 (hinzugefügt foo1)
> +  < Add foo1 (hinzugefügt foo1)
> error: last command exited with $?=1
> not ok 9 - modified submodule(backward)
>
> I've been looking into the patch below to see if there is an obvious
> problem, but the best I can think is that open_submodule() creates an
> alternate 'struct repository' and somehow the commit-graph feature is
> interacting poorly with that struct.
>
> Stefan, do you know what's going on?

Sure, see the last four patches of this series
https://public-inbox.org/git/20181030220817.61691-1-sbeller@google.com/
(to which you also reply to? Junio did not queue this one, yet).

^ permalink raw reply	[relevance 5%]

* Re: submodule support in git-bundle
  @ 2018-11-02 17:08  7% ` Stefan Beller
  2018-11-02 18:34  7%   ` Duy Nguyen
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-02 17:08 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

On Fri, Nov 2, 2018 at 9:10 AM Duy Nguyen <pclouds@gmail.com> wrote:
>
> I use git-bundle today and it occurs to me that if I want to use it to
> transfer part of a history that involves submodule changes, things
> aren't pretty. Has anybody given thought on how to do binary history
> transfer that contains changes from submodules?
>
> Since .bundle files are basically .pack files, i'm not sure if it's
> easy to bundle multiple pack files (one per repo)...

That is a really good discussion starter!

As bundles are modeled after the fetch protocol, I would
redirect the discussion there.

The new fetch protocol could support sending more than
one pack, which could be for both the superproject as
well as the relevant submodule updates (i.e. what is recorded
in the superproject) based on a new capability.

We at Google have given this idea some thought, but from a
different angle: As you may know currently Android uses the
repo tool, which we want to replace with Gits native submodules
eventually. The repo tool tests for each repository to clone if
there is a bundle file for that repository, such that instead of
cloning the repo, the bundle can be downloaded and then
a catch-up fetch can be performed. (This helps the Git servers
as well as the client, the bundle can be hosted on a CDN,
which is faster and cheaper than a git server for us).

So we've given some thought on extending the packfiles in the
fetch protocol to have some redirection to a CDN possible,
i.e. instead of sending bytes as is, you get more or less a "todo"
list, which might be
    (a) take the following bytes as is (current pack format)
    (b) download these other bytes from $THERE
        (possibly with a checksum)
once the stream of bytes is assembled, it will look like a regular
packfile with deltas etc.

This offloading-to-CDN (or "mostly resumable clone" in the
sense that the communication with the server is minimal, and
you get most of your data via resumable http range-requests)
sounds like complete offtopic, but is one of the requirements
for the repo to submodule migration, hence I came to speak of it.

Did you have other things in mind, on a higher level?
e.g. querying the bundle and creating submodule bundles
based off the superproject bundle? 'git bundle create' could
learn the --recurse-submodules option, which then produces
multiple bundle files without changing the file formats.

Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 19/24] submodule: use submodule repos for object lookup
  2018-10-30 22:08 20% ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-11-02 13:03  8%   ` Derrick Stolee
  2018-11-02 17:23  5%     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Derrick Stolee @ 2018-11-02 13:03 UTC (permalink / raw)
  To: Stefan Beller, git; +Cc: szeder.dev, jonathantanmy

On 10/30/2018 6:08 PM, Stefan Beller wrote:
> This converts the 'show_submodule_header' function to use
> the repository API properly, such that the submodule objects
> are not added to the main object store.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>

A couple tests are broken in 'pu' when run with GIT_TEST_COMMIT_GRAPH=1, 
including t4041-diff-submodule-option.sh. The failure bisects to this patch.

Here is a verbose output of the first failure in that script:;


expecting success:
         git diff-index -p --submodule=log HEAD >actual &&
         cat >expected <<-EOF &&
         Submodule sm1 $head2..$head3 (rewind):
           < Add foo3 ($added foo3)
           < Add foo2 ($added foo2)
         EOF
         test_cmp expected actual

+ git diff-index -p --submodule=log HEAD
+ cat
+ test_cmp expected actual
+ diff -u expected actual
--- expected    2018-11-02 12:58:43.429262380 +0000
+++ actual      2018-11-02 12:58:43.429262380 +0000
@@ -1,3 +1,5 @@
-Submodule sm1 30b9670..dafb207 (rewind):
+Submodule sm1 30b9670...dafb207:
    < Add foo3 (hinzugefügt foo3)
    < Add foo2 (hinzugefügt foo2)
+  > Add foo1 (hinzugefügt foo1)
+  < Add foo1 (hinzugefügt foo1)
error: last command exited with $?=1
not ok 9 - modified submodule(backward)

I've been looking into the patch below to see if there is an obvious 
problem, but the best I can think is that open_submodule() creates an 
alternate 'struct repository' and somehow the commit-graph feature is 
interacting poorly with that struct.

Stefan, do you know what's going on?

Thanks,

-Stolee

> ---
>   submodule.c | 76 ++++++++++++++++++++++++++++++++++++++++++-----------
>   1 file changed, 61 insertions(+), 15 deletions(-)
>
> diff --git a/submodule.c b/submodule.c
> index d9d3046689..0fdda45252 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
>   	return prepare_revision_walk(rev);
>   }
>   
> -static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
> +static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
>   {
>   	static const char format[] = "  %m %s";
>   	struct strbuf sb = STRBUF_INIT;
> @@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
>   		ctx.date_mode = rev->date_mode;
>   		ctx.output_encoding = get_log_output_encoding();
>   		strbuf_setlen(&sb, 0);
> -		format_commit_message(commit, format, &sb, &ctx);
> +		repo_format_commit_message(r, commit, format, &sb,
> +				      &ctx);
>   		strbuf_addch(&sb, '\n');
>   		if (commit->object.flags & SYMMETRIC_LEFT)
>   			diff_emit_submodule_del(o, sb.buf);
> @@ -481,14 +482,47 @@ void prepare_submodule_repo_env(struct argv_array *out)
>   			 DEFAULT_GIT_DIR_ENVIRONMENT);
>   }
>   
> -/* Helper function to display the submodule header line prior to the full
> - * summary output. If it can locate the submodule objects directory it will
> - * attempt to lookup both the left and right commits and put them into the
> - * left and right pointers.
> +/*
> + * Initialize 'out' based on the provided submodule path.
> + *
> + * Unlike repo_submodule_init, this tolerates submodules not present
> + * in .gitmodules. This function exists only to preserve historical behavior,
> + *
> + * Returns 0 on success, -1 when the submodule is not present.
>    */
> -static void show_submodule_header(struct diff_options *o, const char *path,
> +static struct repository *open_submodule(const char *path)
> +{
> +	struct strbuf sb = STRBUF_INIT;
> +	struct repository *out = xmalloc(sizeof(*out));
> +
> +	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> +		strbuf_release(&sb);
> +		free(out);
> +		return NULL;
> +	}
> +
> +	out->submodule_prefix = xstrfmt("%s%s/",
> +					the_repository->submodule_prefix ?
> +					the_repository->submodule_prefix :
> +					"", path);
> +
> +	strbuf_release(&sb);
> +	return out;
> +}
> +
> +/*
> + * Helper function to display the submodule header line prior to the full
> + * summary output.
> + *
> + * If it can locate the submodule git directory it will create a repository
> + * handle for the submodule and lookup both the left and right commits and
> + * put them into the left and right pointers.
> + */
> +static void show_submodule_header(struct diff_options *o,
> +		const char *path,
>   		struct object_id *one, struct object_id *two,
>   		unsigned dirty_submodule,
> +		struct repository *sub,
>   		struct commit **left, struct commit **right,
>   		struct commit_list **merge_bases)
>   {
> @@ -507,7 +541,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
>   	else if (is_null_oid(two))
>   		message = "(submodule deleted)";
>   
> -	if (add_submodule_odb(path)) {
> +	if (!sub) {
>   		if (!message)
>   			message = "(commits not present)";
>   		goto output_header;
> @@ -517,8 +551,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
>   	 * Attempt to lookup the commit references, and determine if this is
>   	 * a fast forward or fast backwards update.
>   	 */
> -	*left = lookup_commit_reference(the_repository, one);
> -	*right = lookup_commit_reference(the_repository, two);
> +	*left = lookup_commit_reference(sub, one);
> +	*right = lookup_commit_reference(sub, two);
>   
>   	/*
>   	 * Warn about missing commits in the submodule project, but only if
> @@ -528,7 +562,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
>   	     (!is_null_oid(two) && !*right))
>   		message = "(commits not present)";
>   
> -	*merge_bases = get_merge_bases(*left, *right);
> +	*merge_bases = repo_get_merge_bases(sub, *left, *right);
>   	if (*merge_bases) {
>   		if ((*merge_bases)->item == *left)
>   			fast_forward = 1;
> @@ -562,16 +596,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
>   	struct rev_info rev;
>   	struct commit *left = NULL, *right = NULL;
>   	struct commit_list *merge_bases = NULL;
> +	struct repository *sub;
>   
> +	sub = open_submodule(path);
>   	show_submodule_header(o, path, one, two, dirty_submodule,
> -			      &left, &right, &merge_bases);
> +			      sub, &left, &right, &merge_bases);
>   
>   	/*
>   	 * If we don't have both a left and a right pointer, there is no
>   	 * reason to try and display a summary. The header line should contain
>   	 * all the information the user needs.
>   	 */
> -	if (!left || !right)
> +	if (!left || !right || !sub)
>   		goto out;
>   
>   	/* Treat revision walker failure the same as missing commits */
> @@ -580,13 +616,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
>   		goto out;
>   	}
>   
> -	print_submodule_summary(&rev, o);
> +	print_submodule_summary(sub, &rev, o);
>   
>   out:
>   	if (merge_bases)
>   		free_commit_list(merge_bases);
>   	clear_commit_marks(left, ~0);
>   	clear_commit_marks(right, ~0);
> +	if (sub) {
> +		repo_clear(sub);
> +		free(sub);
> +	}
>   }
>   
>   void show_submodule_inline_diff(struct diff_options *o, const char *path,
> @@ -598,9 +638,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
>   	struct commit_list *merge_bases = NULL;
>   	struct child_process cp = CHILD_PROCESS_INIT;
>   	struct strbuf sb = STRBUF_INIT;
> +	struct repository *sub;
>   
> +	sub = open_submodule(path);
>   	show_submodule_header(o, path, one, two, dirty_submodule,
> -			      &left, &right, &merge_bases);
> +			      sub, &left, &right, &merge_bases);
>   
>   	/* We need a valid left and right commit to display a difference */
>   	if (!(left || is_null_oid(one)) ||
> @@ -661,6 +703,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
>   		clear_commit_marks(left, ~0);
>   	if (right)
>   		clear_commit_marks(right, ~0);
> +	if (sub) {
> +		repo_clear(sub);
> +		free(sub);
> +	}
>   }
>   
>   int should_update_submodules(void)

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 18/19] submodule: use submodule repos for object lookup
  2018-10-31 13:38  5%   ` Derrick Stolee
@ 2018-11-01 19:13  5%     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-01 19:13 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, Jonathan Tan

On Wed, Oct 31, 2018 at 6:38 AM Derrick Stolee <stolee@gmail.com> wrote:
>
> On 10/16/2018 7:35 PM, Stefan Beller wrote:
> > @@ -482,14 +483,46 @@ void prepare_submodule_repo_env(struct argv_array *out)
> >                        DEFAULT_GIT_DIR_ENVIRONMENT);
> >   }
> >
> > -/* Helper function to display the submodule header line prior to the full
> > - * summary output. If it can locate the submodule objects directory it will
> > - * attempt to lookup both the left and right commits and put them into the
> > - * left and right pointers.
> > +/*
> > + * Initialize 'out' based on the provided submodule path.
> > + *
> > + * Unlike repo_submodule_init, this tolerates submodules not present
> > + * in .gitmodules. This function exists only to preserve historical behavior,
> > + *
> > + * Returns 0 on success, -1 when the submodule is not present.
> > + */
> > +static int open_submodule(struct repository *out, const char *path)
> > +{
> > +     struct strbuf sb = STRBUF_INIT;
> > +
> > +     if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> > +             strbuf_release(&sb);
> > +             return -1;
> > +     }
> > +
> > +     out->submodule_prefix = xstrdup(path);
> > +     out->submodule_prefix = xstrfmt("%s%s/",
> > +                                     the_repository->submodule_prefix ?
> > +                                     the_repository->submodule_prefix :
> > +                                     "", path);
> > +
> > +     strbuf_release(&sb);
> > +     return 0;
> > +}
>
> Based on the recent test coverage report [1], this xstrfmt() call is never
> run witha non-null the_repository->submodule_prefix. Is there a way we can
> exercise that branch?

No it's dead code, actually. the_repository never has submodule_prefix set
as it is the main repository. So this is overly cautious to enable the
'any repo'
case.
In a resend we'll go with xstrdup(path);

^ permalink raw reply	[relevance 5%]

* Git Test Coverage Report (Thursday, Nov 1) Part A
@ 2018-11-01 16:15  3% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-01 16:15 UTC (permalink / raw)
  To: Git List

Today's test report doesn't contain any information for the 'master'
branch because the ref was not updated before this run (see 'master' and
'master@{1}' are the same below). If 'master' updates today, then I will
rerun the build and send the report for new lines in 'next' and 'master'.

Thanks,
-Stolee

[1] https://git.visualstudio.com/git/_build/results?buildId=237&view=logs

---

pu: f86906bb5aab712b2a63746c4a643efd6ce19d5b
jch: ce1cd767b7bb0e53083d26b4d60257e3ec0eaeb4
next: 0c4a18a71f0e8e4f10970951c5f8875f429eaef7
master: 4ede3d42dfb57f9a41ac96a1f216c62eb7566cc2
master@{1}: 4ede3d42dfb57f9a41ac96a1f216c62eb7566cc2

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
f86906bb5a builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    924) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    925) break;

builtin/describe.c
f86906bb5a builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/fsck.c
209830491c builtin/fsck.c 622) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
209830491c builtin/fsck.c 627) return error(_("invalid %s"), head_ref_name);

builtin/grep.c
76e9bdc437 builtin/grep.c  429) grep_read_unlock();

builtin/pack-objects.c
f86906bb5a builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 585) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 621) continue;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fsck.c
f86906bb5a  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
f86906bb5a  878) repo_read_object_file(the_repository,
f86906bb5a  879)       &tag->object.oid, &type, &size);

http-push.c
f86906bb5a 1635) if (!repo_has_object_file(the_repository, &head_oid))
f86906bb5a 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

merge-recursive.c
4cdc48e412 1585) return -1;
4cdc48e412 1588) return -1;
4cdc48e412 1594) return -1;
4cdc48e412 1596) if (update_file(o, 1, b_oid, b_mode, collide_path))
4cdc48e412 1597) return -1;
4cdc48e412 1664) return -1;
4cdc48e412 1667) return -1;
4cdc48e412 1670) return -1;
b58ae691c0 1703) return -1;
387361a6a7 1738) return -1;
387361a6a7 1786) return -1;
387361a6a7 1795) new_path = unique_path(o, a->path, ci->branch1);
387361a6a7 1796) output(o, 1, _("Refusing to lose untracked file"
387361a6a7 1802) return -1;
387361a6a7 1805) return -1;
387361a6a7 1815) return -1;
387361a6a7 1831) return -1;
387361a6a7 1834) return -1;

negotiator/default.c
f86906bb5a  71) if (repo_parse_commit(the_repository, commit))

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
f86906bb5a  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
f86906bb5a 1624) repo_unuse_commit_buffer(the_repository, head_commit,
f86906bb5a 3868) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule-config.c
bcbc780d14 740) return CONFIG_INVALID_KEY;
45f5ef3d77 755) warning(_("Could not update .gitmodules entry %s"), key);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
e2419f7e30 1378) strbuf_release(&gitdir);
7454fe5cb6 1501) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1505) get_next_submodule_task_release(task);
7454fe5cb6 1532) return 0;
7454fe5cb6 1536) goto out;
7454fe5cb6 1551) return 0;

tree.c
f86906bb5a 108) if (repo_parse_commit(the_repository, commit))

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Elijah Newren      387361a6a: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      4cdc48e41: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      b58ae691c: merge-recursive: fix rename/add conflict 
handling
Junio C Hamano      209830491: Merge branch 
'nd/per-worktree-ref-iteration' into pu
Junio C Hamano      f86906bb5: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

archive.c
48a40549d5 399) die(_("'%s' is not a valid object name"), name);
48a40549d5 412) die(_("%s is not a tree object"), oid_to_hex(&oid));
48a40549d5 422) die(_("current working directory is untracked"));

attr.c
847aa0ff7a  369) fprintf(stderr, _("%s not allowed: %s:%d\n"),

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));

builtin/fetch.c
builtin/fsck.c
09120ea781 builtin/fsck.c 154) objerror(parent, _("wrong object type in 
link"));
09120ea781 builtin/fsck.c 265) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
09120ea781 builtin/fsck.c 293) error(_("could not create lost-found"));
09120ea781 builtin/fsck.c 300) die_errno(_("could not write '%s'"), 
filename);
09120ea781 builtin/fsck.c 304) die_errno(_("could not finish '%s'"),
09120ea781 builtin/fsck.c 321) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
09120ea781 builtin/fsck.c 339) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
09120ea781 builtin/fsck.c 358) fprintf_ln(stderr, _("Checking %s %s"),
09120ea781 builtin/fsck.c 371) printf_ln(_("root %s"),
09120ea781 builtin/fsck.c 407) return error(_("%s: object corrupt or 
missing"),
09120ea781 builtin/fsck.c 446) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
09120ea781 builtin/fsck.c 545) error(_("%s: object could not be parsed: 
%s"),
09120ea781 builtin/fsck.c 580) fprintf_ln(stderr, _("Checking object 
directory"));
09120ea781 builtin/fsck.c 596) fprintf_ln(stderr, _("Checking HEAD link"));
09120ea781 builtin/fsck.c 601) return error(_("invalid HEAD"));
09120ea781 builtin/fsck.c 628) fprintf_ln(stderr, _("Checking cache tree"));
09120ea781 builtin/fsck.c 644) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/grep.c
389f2f2d79 builtin/grep.c 1034) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/merge.c
35408df41e builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/reflog.c
b9c4009cca builtin/reflog.c 563) usage(_(reflog_expire_usage));
b9c4009cca builtin/reflog.c 605) status |= error(_("%s points 
nowhere!"), argv[i]);
b9c4009cca builtin/reflog.c 651) usage(_(reflog_delete_usage));
b9c4009cca builtin/reflog.c 657) return error(_("nothing to delete?"));
b9c4009cca builtin/reflog.c 666) status |= error(_("not a reflog: %s"), 
argv[i]);
b9c4009cca builtin/reflog.c 671) status |= error(_("no reflog for 
'%s'"), argv[i]);
b9c4009cca builtin/reflog.c 706) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 714) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 717) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
eb6c5a15dc 200) die(_("could not start pack-objects to repack promisor 
objects"));
479fbb285c 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
eb6c5a15dc 250) die_errno(("unable to create '%s'"), promisor_name);
479fbb285c 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

git.c
b63c352c11 341) die_errno(_("while expanding alias '%s': '%s'"),
b63c352c11 350) die(_("alias '%s' changes environment variables.\n"
b63c352c11 358) die(_("empty alias for %s"), alias_command);
b63c352c11 361) die(_("recursive alias: %s"), alias_command);
b63c352c11 436) die_errno(_("write failure on standard output"));
b63c352c11 438) die(_("unknown write failure on standard output"));
b63c352c11 440) die_errno(_("close failed on standard output"));
b63c352c11 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

midx.c
1dcd9f2043  184) return;

name-hash.c
31bfd155d8 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
31bfd155d8 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
31bfd155d8 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

parse-options-cb.c
35408df41e  21) return error(_("option `%s' expects a numerical value"),
35408df41e  58) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
35408df41e  88) return error(_("%s takes no value"), optname(opt, flags));
35408df41e  90) return error(_("%s isn't available"), optname(opt, flags));
35408df41e  92) return error(_("%s takes no value"), optname(opt, flags));
35408df41e 178) return error(_("%s expects a numerical value"),
35408df41e 194) return error(_("%s expects a non-negative integer value"
e0948db833 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
e0948db833 651) error(_("unknown non-ascii option in string: `%s'"),
35408df41e 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

preload-index.c
31bfd155d8 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
5257b0625a  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
5257b0625a  676)     ce->name, alias->name);
5257b0625a  691) die(_("cannot create an empty blob in the object 
database"));
5257b0625a  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
5257b0625a  786) return error(_("unable to add '%s' to index"), path);
5257b0625a  822) error(_("invalid path '%s'"), path);
5257b0625a  848) error(_("invalid path '%s'"), path);
5257b0625a 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
5257b0625a 1689) return error(_("bad index version %d"), hdr_version);
5257b0625a 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
5257b0625a 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
5257b0625a 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
5257b0625a 1848) die(_("unordered stage entries in index"));
5257b0625a 1851) die(_("multiple stage entries for merged file '%s'"),
5257b0625a 1854) die(_("unordered stage entries for '%s'"),
5257b0625a 2148) die_errno(_("%s: index file open failed"), path);
5257b0625a 2152) die_errno(_("%s: cannot stat the open index"), path);
5257b0625a 2156) die(_("%s: index file smaller than expected"), path);
5257b0625a 2160) die_errno(_("%s: unable to map index file"), path);
5257b0625a 2252) warning(_("could not freshen shared index '%s'"), 
shared_index);
5257b0625a 2287) die(_("broken index, expect %s in %s, got %s"),
5257b0625a 3073) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
5257b0625a 3219) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
35408df41e 2324) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
a454d6a26b  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
a454d6a26b  417) error(_("more than one uploadpack given, using the 
first"));
a454d6a26b  683) die(_("key '%s' of pattern had no '*'"), key);
a454d6a26b  693) die(_("value '%s' of pattern has no '*'"), value);
a454d6a26b 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
a454d6a26b 1066) return error(_("dst ref %s receives from more than one 
src"),
a454d6a26b 1753) die(_("couldn't find remote ref %s"), name);
a454d6a26b 1766) error(_("* Ignoring funny ref '%s' locally"),
a454d6a26b 1861) die(_("revision walk setup failed"));
a454d6a26b 2134) return error(_("cannot parse expected object name '%s'"),

revision.c
a63d88e595 2932) return;
a63d88e595 2935) return;
a63d88e595 2941) c->object.flags |= UNINTERESTING;
a63d88e595 2944) return;
a63d88e595 2947) mark_parents_uninteresting(c);
a63d88e595 2970) return;
a63d88e595 2973) return;
a63d88e595 2978) return;
a63d88e595 3042) continue;
f33f8de6af 3090) if (!revs->ignore_missing_links)
f33f8de6af 3091) die("Failed to traverse parents of commit %s",
a63d88e595 3092) oid_to_hex(&commit->object.oid));
a63d88e595 3100) continue;

run-command.c
31bfd155d8 1229) error(_("cannot create async thread: %s"), strerror(err));

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      a63d88e59: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f33f8de6a: revision.c: begin refactoring 
--topo-order logic
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Junio C Hamano      479fbb285: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      09120ea78: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      31bfd155d: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      35408df41: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      389f2f2d7: grep: remove #ifdef NO_PTHREADS
Nguyễn Thái Ngọc Duy      48a40549d: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      5257b0625: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      847aa0ff7: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      a454d6a26: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      b63c352c1: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      b9c4009cc: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      e0948db83: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      eb6c5a15d: repack: mark more strings for 
translation
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Phillip Wood      bcd33ec25: add read_author_script() to libgit



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
55071ea248   61) strbuf_trim(&out);
55071ea248   62) ret = !strcmp("true", out.buf);
55071ea248   63) strbuf_release(&out);
002ee2fe68  115) die(_("%s requires an interactive rebase"), option);
f95736288a  148) return error_errno(_("could not read '%s'"), path);
f95736288a  162) return -1;
f95736288a  167) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  178) return -1;
f95736288a  179) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  180) return -1;
f95736288a  182) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  186) return -1;
f95736288a  188) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  196) opts->signoff = 1;
73d51ed0a5  197) opts->flags |= REBASE_FORCE;
ead98c111b  204) return -1;
12026a412c  219) return -1;
ba1905a5fe  227) return -1;
ba1905a5fe  235) return -1;
6defce2b02  255) return error(_("Could not read '%s'"), path);
6defce2b02  273) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  277) return res;
bc24382c2b  375) argv_array_pushf(&child.args,
bc24382c2b  377) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  509) struct strbuf dir = STRBUF_INIT;
6defce2b02  511) apply_autostash(opts);
ac7f467fef  512) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  513) remove_dir_recursively(&dir, 0);
ac7f467fef  514) strbuf_release(&dir);
ac7f467fef  515) die("Nothing to do");
ac7f467fef  545) return -1;
ac7f467fef  549) rollback_lock_file(&lock);
ac7f467fef  550) return error(_("could not determine HEAD revision"));
ac7f467fef  567) rollback_lock_file(&lock);
ac7f467fef  568) return error(_("could not read index"));
ac7f467fef  572) error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef  573) rollback_lock_file(&lock);
ac7f467fef  574) free((void *)desc.buffer);
ac7f467fef  575) return -1;
ac7f467fef  588) ret = error(_("could not write index"));
ac7f467fef  592) return ret;
ac7f467fef  608) } else if (old_orig)
ac7f467fef  609) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  637) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  671) return 1;
9a48a615b4  687) return 0;
55071ea248  895) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  898) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  899) die_errno(_("could not exec %s"), path);
0eabf4b95c  917) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  954) usage_with_options(builtin_rebase_usage,
f95736288a  974) die(_("Cannot read HEAD"));
f95736288a  978) die(_("could not read index"));
f95736288a  992) exit(1);
122420c295 1004) die(_("could not discard worktree changes"));
122420c295 1006) exit(1);
5e5d96197c 1017) exit(1);
5e5d96197c 1020) die(_("could not move back to %s"),
5a61494539 1030) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1049) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1050) const char *state_dir_base =
c54dacb50e 1051) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1052) const char *cmd_live_rebase =
c54dacb50e 1054) strbuf_reset(&buf);
c54dacb50e 1055) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1056) die(_("It seems that there is already a %s directory, 
and\n"
53f9e5be94 1080) strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94 1081) options.flags |= REBASE_FORCE;
7998dbe1ec 1093) strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
3c3588c7d3 1125) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1126) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1148) die(_("--strategy requires --merge or --interactive"));
cda614e489 1166) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1175) options.state_dir = apply_dir();
ac7f467fef 1176) break;
ac7f467fef 1253) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1259) die(_("Could not create new root commit"));
e65123a71d 1309) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1317) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1329) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1342) die(_("could not read index"));
6defce2b02 1369) die(_("Cannot autostash"));
6defce2b02 1372) die(_("Unexpected stash response: '%s'"),
6defce2b02 1378) die(_("Could not create directory for '%s'"),
6defce2b02 1384) die(_("could not reset --hard"));
e65123a71d 1428) ret = !!error(_("could not parse '%s'"),
e65123a71d 1430) goto cleanup;
e65123a71d 1439) ret = !!error(_("could not switch to "
1ed9c14ff2 1449)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1450) puts(_("HEAD is up to date."));
9a48a615b4 1459)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1460) puts(_("HEAD is up to date, rebase forced."));

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

gpg-interface.c
4de9394dcb 155) break;

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

sequencer.c
65850686cf 2279) return;
65850686cf 2376) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3374) return error(_("could not checkout %s"), commit);
4df66c40b0 3388) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3408) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4772) return -1;
b97e187364 4775) return -1;
b97e187364 4781) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4784) todo_list_release(&todo_list);
b97e187364 4785) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4804) todo_list_release(&todo_list);
b97e187364 4805) return -1;
b97e187364 4809) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4813) return error(_("could not transform the todo list"));
b97e187364 4842) return error(_("could not transform the todo list"));
b97e187364 4845) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4851) return -1;

setup.c
58b284a2e9  413) return config_error_nonbool(var);

strbuf.c
f95736288a  127) --sb->len;

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      53f9e5be9: builtin rebase: support `ignore-date` option
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      7998dbe1e: builtin rebase: support `-C` and 
`--whitespace=<type>`
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed


^ permalink raw reply	[relevance 3%]

* Re: [PATCH 18/19] submodule: use submodule repos for object lookup
  @ 2018-10-31 13:38  5%   ` Derrick Stolee
  2018-11-01 19:13  5%     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Derrick Stolee @ 2018-10-31 13:38 UTC (permalink / raw)
  To: Stefan Beller, git; +Cc: jonathantanmy

On 10/16/2018 7:35 PM, Stefan Beller wrote:
> @@ -482,14 +483,46 @@ void prepare_submodule_repo_env(struct argv_array *out)
>   			 DEFAULT_GIT_DIR_ENVIRONMENT);
>   }
>   
> -/* Helper function to display the submodule header line prior to the full
> - * summary output. If it can locate the submodule objects directory it will
> - * attempt to lookup both the left and right commits and put them into the
> - * left and right pointers.
> +/*
> + * Initialize 'out' based on the provided submodule path.
> + *
> + * Unlike repo_submodule_init, this tolerates submodules not present
> + * in .gitmodules. This function exists only to preserve historical behavior,
> + *
> + * Returns 0 on success, -1 when the submodule is not present.
> + */
> +static int open_submodule(struct repository *out, const char *path)
> +{
> +	struct strbuf sb = STRBUF_INIT;
> +
> +	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> +		strbuf_release(&sb);
> +		return -1;
> +	}
> +
> +	out->submodule_prefix = xstrdup(path);
> +	out->submodule_prefix = xstrfmt("%s%s/",
> +					the_repository->submodule_prefix ?
> +					the_repository->submodule_prefix :
> +					"", path);
> +
> +	strbuf_release(&sb);
> +	return 0;
> +}

Based on the recent test coverage report [1], this xstrfmt() call is never
run witha non-null the_repository->submodule_prefix. Is there a way we can
exercise that branch?

Thanks,
-Stolee

[1] 
https://public-inbox.org/git/62f0bcf6-aa73-c192-d804-e6d69cac146f@gmail.com/

^ permalink raw reply	[relevance 5%]

* Re: [PATCHv2 00/24] Bring more repository handles into our code base]
  2018-10-30 22:07  7% [PATCHv2 00/24] Bring more repository handles into our code base] Stefan Beller
  2018-10-30 22:08 20% ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
  2018-10-30 22:08 14% ` [PATCH 20/24] submodule: don't add submodule as odb for push Stefan Beller
@ 2018-10-31  6:41  2% ` Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-10-31  6:41 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, szeder.dev, jonathantanmy

Stefan Beller <sbeller@google.com> writes:

> I also picked up the patch for pending semantic patches, as the
> first patch, can I have your sign off, please?

I find this step quite lacking.  

What was posted would have been perfectly fine as a "how about doing
it this way" weatherbaloon patch, but as a part of real series, it
needs to explain to the developers what the distinctions between two
classes are, and who is to use the cocci patch at what point in the
development cycle, etc., in an accompanying documentation update.

So can we have both sign-off and write-up (perhaps cut&paste from
the original e-mail discussion)?

> Stefan Beller (23):
>   sha1_file: allow read_object to read objects in arbitrary repositories
>   packfile: allow has_packed_and_bad to handle arbitrary repositories
>   object-store: allow read_object_file_extended to read from arbitrary
>     repositories
>   object-store: prepare read_object_file to deal with arbitrary
>     repositories
>   object-store: prepare has_{sha1, object}_file[_with_flags] to handle
>     arbitrary repositories
>   object: parse_object to honor its repository argument
>   commit: allow parse_commit* to handle arbitrary repositories
>   commit-reach.c: allow paint_down_to_common to handle arbitrary
>     repositories
>   commit-reach.c: allow merge_bases_many to handle arbitrary
>     repositories
>   commit-reach.c: allow remove_redundant to handle arbitrary
>     repositories
>   commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary
>     repositories
>   commit-reach: prepare get_merge_bases to handle arbitrary repositories
>   commit-reach: prepare in_merge_bases[_many] to handle arbitrary
>     repositories
>   commit: prepare get_commit_buffer to handle arbitrary repositories
>   commit: prepare repo_unuse_commit_buffer to handle arbitrary
>     repositories
>   commit: prepare logmsg_reencode to handle arbitrary repositories
>   pretty: prepare format_commit_message to handle arbitrary repositories
>   submodule: use submodule repos for object lookup
>   submodule: don't add submodule as odb for push
>   commit-graph: convert remaining function to handle arbitrary
>     repositories
>   commit: make free_commit_buffer and release_commit_memory repository
>     agnostic
>   path.h: make REPO_GIT_PATH_FUNC repository agnostic
>   t/helper/test-repository: celebrate independence from the_repository

It seems that this topic is full of commits with overly long title.

>
>  Makefile                                      |   6 +-
>  builtin/fsck.c                                |   3 +-
>  builtin/log.c                                 |   6 +-
>  builtin/rev-list.c                            |   3 +-
>  cache.h                                       |   2 +
>  commit-graph.c                                |  40 +++--
>  commit-reach.c                                |  73 +++++----
>  commit-reach.h                                |  38 +++--
>  commit.c                                      |  41 ++---
>  commit.h                                      |  43 +++++-
>  .../coccinelle/the_repository.pending.cocci   | 144 ++++++++++++++++++
>  object-store.h                                |  35 ++++-
>  object.c                                      |   8 +-
>  packfile.c                                    |   5 +-
>  packfile.h                                    |   2 +-
>  path.h                                        |   2 +-
>  pretty.c                                      |  28 ++--
>  pretty.h                                      |   7 +-
>  sha1-file.c                                   |  34 +++--
>  streaming.c                                   |   2 +-
>  submodule.c                                   |  79 +++++++---
>  t/helper/test-repository.c                    |  10 ++
>  22 files changed, 459 insertions(+), 152 deletions(-)
>  create mode 100644 contrib/coccinelle/the_repository.pending.cocci
>
> git range-diff origin/sb/more-repo-in-api...
> [...] # rebased to origin/master

I offhand do not recall what happened during these 100+ pacthes.
DId we acquire something significantly new that would have
conflicted with this new round of the topic?  I do not mind at all
seeing that a series gets adjusted to the updated codebase, but I do
dislike seeing it done without explanation---an unexplained rebase
to a new base is a wasted opportunity to learn what areas of the
codebase are so hot that multiple and separate topics would want to
touch them.

>   -:  ---------- > 116:  4ede3d42df Seventh batch for 2.20
>   -:  ---------- > 117:  b1de196491 Makefile: add pending semantic patches
>   1:  1b9b5c695e = 118:  f1be5eb487 sha1_file: allow read_object to read objects in arbitrary repositories
>   2:  33b94066f2 = 119:  9100a5705d packfile: allow has_packed_and_bad to handle arbitrary repositories
>   3:  5217b6b1e1 = 120:  a4ad7791da object-store: allow read_object_file_extended to read from arbitrary repositories
>   4:  2b7239b55b ! 121:  5d7b3a6dd9 object-store: prepare read_object_file to deal with arbitrary repositories
>     @@ -19,10 +19,10 @@
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>          Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>     - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
>     + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
>       new file mode 100644
>       --- /dev/null
>     - +++ b/contrib/coccinelle/the_repository.cocci
>     + +++ b/contrib/coccinelle/the_repository.pending.cocci
>      @@
>      +// This file is used for the ongoing refactoring of
>      +// bringing the index or repository struct in all of
>     @@ -36,6 +36,7 @@
>      +- read_object_file(
>      ++ repo_read_object_file(the_repository,
>      +  E, F, G)
>     ++

Is it necessary for this file to end with a trailing blank line?



Thanks.

^ permalink raw reply	[relevance 2%]

* [PATCH 20/24] submodule: don't add submodule as odb for push
  2018-10-30 22:07  7% [PATCHv2 00/24] Bring more repository handles into our code base] Stefan Beller
  2018-10-30 22:08 20% ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-10-30 22:08 14% ` Stefan Beller
  2018-10-31  6:41  2% ` [PATCHv2 00/24] Bring more repository handles into our code base] Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-30 22:08 UTC (permalink / raw)
  To: git; +Cc: szeder.dev, jonathantanmy, Stefan Beller

In push_submodule(), because we do not actually need access to objects
in the submodule, do not invoke add_submodule_odb().
(for_each_remote_ref_submodule() does not require access to those
objects, and the actual push is done by spawning another process,
which handles object access by itself.)

This code of push_submodule() is exercised in t5531 and continues
to work, showing that the submodule odbc is not needed.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index 0fdda45252..da1ac1e6f8 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1024,9 +1024,6 @@ static int push_submodule(const char *path,
 			  const struct string_list *push_options,
 			  int dry_run)
 {
-	if (add_submodule_odb(path))
-		return 1;
-
 	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
 		struct child_process cp = CHILD_PROCESS_INIT;
 		argv_array_push(&cp.args, "push");
-- 
2.19.1.930.g4563a0d9d0-goog


^ permalink raw reply related	[relevance 14%]

* [PATCH 19/24] submodule: use submodule repos for object lookup
  2018-10-30 22:07  7% [PATCHv2 00/24] Bring more repository handles into our code base] Stefan Beller
@ 2018-10-30 22:08 20% ` Stefan Beller
  2018-11-02 13:03  8%   ` Derrick Stolee
  2018-10-30 22:08 14% ` [PATCH 20/24] submodule: don't add submodule as odb for push Stefan Beller
  2018-10-31  6:41  2% ` [PATCHv2 00/24] Bring more repository handles into our code base] Junio C Hamano
  2 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-30 22:08 UTC (permalink / raw)
  To: git; +Cc: szeder.dev, jonathantanmy, Stefan Beller

This converts the 'show_submodule_header' function to use
the repository API properly, such that the submodule objects
are not added to the main object store.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 76 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 61 insertions(+), 15 deletions(-)

diff --git a/submodule.c b/submodule.c
index d9d3046689..0fdda45252 100644
--- a/submodule.c
+++ b/submodule.c
@@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
 	return prepare_revision_walk(rev);
 }
 
-static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
+static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
 {
 	static const char format[] = "  %m %s";
 	struct strbuf sb = STRBUF_INIT;
@@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
 		ctx.date_mode = rev->date_mode;
 		ctx.output_encoding = get_log_output_encoding();
 		strbuf_setlen(&sb, 0);
-		format_commit_message(commit, format, &sb, &ctx);
+		repo_format_commit_message(r, commit, format, &sb,
+				      &ctx);
 		strbuf_addch(&sb, '\n');
 		if (commit->object.flags & SYMMETRIC_LEFT)
 			diff_emit_submodule_del(o, sb.buf);
@@ -481,14 +482,47 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
-/* Helper function to display the submodule header line prior to the full
- * summary output. If it can locate the submodule objects directory it will
- * attempt to lookup both the left and right commits and put them into the
- * left and right pointers.
+/*
+ * Initialize 'out' based on the provided submodule path.
+ *
+ * Unlike repo_submodule_init, this tolerates submodules not present
+ * in .gitmodules. This function exists only to preserve historical behavior,
+ *
+ * Returns 0 on success, -1 when the submodule is not present.
  */
-static void show_submodule_header(struct diff_options *o, const char *path,
+static struct repository *open_submodule(const char *path)
+{
+	struct strbuf sb = STRBUF_INIT;
+	struct repository *out = xmalloc(sizeof(*out));
+
+	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
+		strbuf_release(&sb);
+		free(out);
+		return NULL;
+	}
+
+	out->submodule_prefix = xstrfmt("%s%s/",
+					the_repository->submodule_prefix ?
+					the_repository->submodule_prefix :
+					"", path);
+
+	strbuf_release(&sb);
+	return out;
+}
+
+/*
+ * Helper function to display the submodule header line prior to the full
+ * summary output.
+ *
+ * If it can locate the submodule git directory it will create a repository
+ * handle for the submodule and lookup both the left and right commits and
+ * put them into the left and right pointers.
+ */
+static void show_submodule_header(struct diff_options *o,
+		const char *path,
 		struct object_id *one, struct object_id *two,
 		unsigned dirty_submodule,
+		struct repository *sub,
 		struct commit **left, struct commit **right,
 		struct commit_list **merge_bases)
 {
@@ -507,7 +541,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	else if (is_null_oid(two))
 		message = "(submodule deleted)";
 
-	if (add_submodule_odb(path)) {
+	if (!sub) {
 		if (!message)
 			message = "(commits not present)";
 		goto output_header;
@@ -517,8 +551,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	 * Attempt to lookup the commit references, and determine if this is
 	 * a fast forward or fast backwards update.
 	 */
-	*left = lookup_commit_reference(the_repository, one);
-	*right = lookup_commit_reference(the_repository, two);
+	*left = lookup_commit_reference(sub, one);
+	*right = lookup_commit_reference(sub, two);
 
 	/*
 	 * Warn about missing commits in the submodule project, but only if
@@ -528,7 +562,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	     (!is_null_oid(two) && !*right))
 		message = "(commits not present)";
 
-	*merge_bases = get_merge_bases(*left, *right);
+	*merge_bases = repo_get_merge_bases(sub, *left, *right);
 	if (*merge_bases) {
 		if ((*merge_bases)->item == *left)
 			fast_forward = 1;
@@ -562,16 +596,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 	struct rev_info rev;
 	struct commit *left = NULL, *right = NULL;
 	struct commit_list *merge_bases = NULL;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/*
 	 * If we don't have both a left and a right pointer, there is no
 	 * reason to try and display a summary. The header line should contain
 	 * all the information the user needs.
 	 */
-	if (!left || !right)
+	if (!left || !right || !sub)
 		goto out;
 
 	/* Treat revision walker failure the same as missing commits */
@@ -580,13 +616,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 		goto out;
 	}
 
-	print_submodule_summary(&rev, o);
+	print_submodule_summary(sub, &rev, o);
 
 out:
 	if (merge_bases)
 		free_commit_list(merge_bases);
 	clear_commit_marks(left, ~0);
 	clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 void show_submodule_inline_diff(struct diff_options *o, const char *path,
@@ -598,9 +638,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 	struct commit_list *merge_bases = NULL;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strbuf sb = STRBUF_INIT;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/* We need a valid left and right commit to display a difference */
 	if (!(left || is_null_oid(one)) ||
@@ -661,6 +703,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 		clear_commit_marks(left, ~0);
 	if (right)
 		clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 int should_update_submodules(void)
-- 
2.19.1.930.g4563a0d9d0-goog


^ permalink raw reply related	[relevance 20%]

* [PATCHv2 00/24] Bring more repository handles into our code base]
@ 2018-10-30 22:07  7% Stefan Beller
  2018-10-30 22:08 20% ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Stefan Beller @ 2018-10-30 22:07 UTC (permalink / raw)
  To: git; +Cc: szeder.dev, jonathantanmy, Stefan Beller

This resends sb/more-repo-in-api

On Thu, Oct 25, 2018 at 2:14 AM SZEDER Gábor <szeder.dev@gmail.com> wrote:
> On Tue, Oct 16, 2018 at 04:35:49PM -0700, Stefan Beller wrote:
> > This converts the 'show_submodule_header' function to use
> > the repository API properly, such that the submodule objects
> > are not added to the main object store.
>
> This patch breaks the test suite with 'GIT_TEST_COMMIT_GRAPH=1', in
> particular 't4041-diff-submodule-option.sh' fails with:
> [...]

I debugged into this and the last four patches will fix it.

I also picked up the patch for pending semantic patches, as the
first patch, can I have your sign off, please?

This also addresses Jonathans feedback in
https://public-inbox.org/git/20181019203750.110741-1-jonathantanmy@google.com/

A range-diff is below.

Thanks,
Stefan

SZEDER Gábor (1):
  Makefile: add pending semantic patches

Stefan Beller (23):
  sha1_file: allow read_object to read objects in arbitrary repositories
  packfile: allow has_packed_and_bad to handle arbitrary repositories
  object-store: allow read_object_file_extended to read from arbitrary
    repositories
  object-store: prepare read_object_file to deal with arbitrary
    repositories
  object-store: prepare has_{sha1, object}_file[_with_flags] to handle
    arbitrary repositories
  object: parse_object to honor its repository argument
  commit: allow parse_commit* to handle arbitrary repositories
  commit-reach.c: allow paint_down_to_common to handle arbitrary
    repositories
  commit-reach.c: allow merge_bases_many to handle arbitrary
    repositories
  commit-reach.c: allow remove_redundant to handle arbitrary
    repositories
  commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary
    repositories
  commit-reach: prepare get_merge_bases to handle arbitrary repositories
  commit-reach: prepare in_merge_bases[_many] to handle arbitrary
    repositories
  commit: prepare get_commit_buffer to handle arbitrary repositories
  commit: prepare repo_unuse_commit_buffer to handle arbitrary
    repositories
  commit: prepare logmsg_reencode to handle arbitrary repositories
  pretty: prepare format_commit_message to handle arbitrary repositories
  submodule: use submodule repos for object lookup
  submodule: don't add submodule as odb for push
  commit-graph: convert remaining function to handle arbitrary
    repositories
  commit: make free_commit_buffer and release_commit_memory repository
    agnostic
  path.h: make REPO_GIT_PATH_FUNC repository agnostic
  t/helper/test-repository: celebrate independence from the_repository

 Makefile                                      |   6 +-
 builtin/fsck.c                                |   3 +-
 builtin/log.c                                 |   6 +-
 builtin/rev-list.c                            |   3 +-
 cache.h                                       |   2 +
 commit-graph.c                                |  40 +++--
 commit-reach.c                                |  73 +++++----
 commit-reach.h                                |  38 +++--
 commit.c                                      |  41 ++---
 commit.h                                      |  43 +++++-
 .../coccinelle/the_repository.pending.cocci   | 144 ++++++++++++++++++
 object-store.h                                |  35 ++++-
 object.c                                      |   8 +-
 packfile.c                                    |   5 +-
 packfile.h                                    |   2 +-
 path.h                                        |   2 +-
 pretty.c                                      |  28 ++--
 pretty.h                                      |   7 +-
 sha1-file.c                                   |  34 +++--
 streaming.c                                   |   2 +-
 submodule.c                                   |  79 +++++++---
 t/helper/test-repository.c                    |  10 ++
 22 files changed, 459 insertions(+), 152 deletions(-)
 create mode 100644 contrib/coccinelle/the_repository.pending.cocci

git range-diff origin/sb/more-repo-in-api...
[...] # rebased to origin/master
  -:  ---------- > 116:  4ede3d42df Seventh batch for 2.20
  -:  ---------- > 117:  b1de196491 Makefile: add pending semantic patches
  1:  1b9b5c695e = 118:  f1be5eb487 sha1_file: allow read_object to read objects in arbitrary repositories
  2:  33b94066f2 = 119:  9100a5705d packfile: allow has_packed_and_bad to handle arbitrary repositories
  3:  5217b6b1e1 = 120:  a4ad7791da object-store: allow read_object_file_extended to read from arbitrary repositories
  4:  2b7239b55b ! 121:  5d7b3a6dd9 object-store: prepare read_object_file to deal with arbitrary repositories
    @@ -19,10 +19,10 @@
         Signed-off-by: Stefan Beller <sbeller@google.com>
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
      new file mode 100644
      --- /dev/null
    - +++ b/contrib/coccinelle/the_repository.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
     +// This file is used for the ongoing refactoring of
     +// bringing the index or repository struct in all of
    @@ -36,6 +36,7 @@
     +- read_object_file(
     ++ repo_read_object_file(the_repository,
     +  E, F, G)
    ++
     
      diff --git a/object-store.h b/object-store.h
      --- a/object-store.h
  5:  24291f4d84 ! 122:  77d406fc51 object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
    @@ -3,16 +3,14 @@
         object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
    - - read_object_file(
      + repo_read_object_file(the_repository,
        E, F, G)
    -+
    + 
     +@@
     +expression E;
     +@@
  6:  6aa209978e = 123:  7224b378d8 object: parse_object to honor its repository argument
  7:  9b2d6aa7c3 ! 124:  e4d4ae08ca commit: allow parse_commit* to handle arbitrary repositories
    @@ -93,9 +93,9 @@
      
      struct buffer_slab;
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - has_object_file_with_flags(
      + repo_has_object_file_with_flags(the_repository,
  8:  0e7e681118 ! 125:  f739ef6078 commit-reach.c: allow paint_down_to_common to handle arbitrary repositories
    @@ -5,7 +5,6 @@
         As the function is file local and not widely used, migrate it all at once.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
  9:  e83b26f5b3 ! 126:  c054a80564 commit-reach.c: allow merge_bases_many to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit-reach.c: allow merge_bases_many to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
 10:  d80b9de832 ! 127:  3434a5a262 commit-reach.c: allow remove_redundant to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit-reach.c: allow remove_redundant to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
 11:  3ec21ad503 ! 128:  82f6e797bf commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
 12:  3f21279f50 ! 129:  b66b636a97 commit-reach: prepare get_merge_bases to handle arbitrary repositories
    @@ -9,7 +9,6 @@
         functions behind a wrapper macro.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
    @@ -91,9 +90,9 @@
      int is_descendant_of(struct commit *commit, struct commit_list *with_commit);
      int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - parse_commit(
      + repo_parse_commit(the_repository,
    @@ -124,3 +123,4 @@
     +- get_merge_bases_many_dirty(
     ++ repo_get_merge_bases_many_dirty(the_repository,
     +  E, F, G);
    ++
 13:  4decc3acc1 ! 130:  e68e48ca91 commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
    @@ -76,14 +75,13 @@
      /*
       * Takes a list of commits and returns a new list where those
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
    - - get_merge_bases_many_dirty(
      + repo_get_merge_bases_many_dirty(the_repository,
        E, F, G);
    -+
    + 
     +@@
     +expression E;
     +expression F;
 14:  141b86ea89 ! 131:  aac401ca98 commit: prepare get_commit_buffer to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit: prepare get_commit_buffer to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -46,9 +45,9 @@
      /*
       * Tell the commit subsytem that we are done with a particular commit buffer.
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - in_merge_bases_many(
      + repo_in_merge_bases_many(the_repository,
 15:  2cc415c1db ! 132:  c45e6d2c0c commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -42,9 +41,9 @@
      /*
       * Free any cached object buffer associated with the commit.
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - get_commit_buffer(
      + repo_get_commit_buffer(the_repository,
 16:  554daa8cfc ! 133:  25e8f5dec4 commit: prepare logmsg_reencode to handle arbitrary repositories
    @@ -24,9 +24,9 @@
      
      /** Removes the first commit from a list sorted by date, and adds all
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - unuse_commit_buffer(
      + repo_unuse_commit_buffer(the_repository,
 17:  bd8737176b ! 134:  2cab6c18b6 pretty: prepare format_commit_message to handle arbitrary repositories
    @@ -5,9 +5,9 @@
         Signed-off-by: Stefan Beller <sbeller@google.com>
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - logmsg_reencode(
      + repo_logmsg_reencode(the_repository,
 18:  b303ef65e7 ! 135:  794592c573 submodule: use submodule repos for object lookup
    @@ -7,7 +7,6 @@
         are not added to the main object store.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
    @@ -46,24 +45,26 @@
     + * in .gitmodules. This function exists only to preserve historical behavior,
     + *
     + * Returns 0 on success, -1 when the submodule is not present.
    -+ */
    -+static int open_submodule(struct repository *out, const char *path)
    +  */
    +-static void show_submodule_header(struct diff_options *o, const char *path,
    ++static struct repository *open_submodule(const char *path)
     +{
     +	struct strbuf sb = STRBUF_INIT;
    ++	struct repository *out = xmalloc(sizeof(*out));
     +
     +	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
     +		strbuf_release(&sb);
    -+		return -1;
    ++		free(out);
    ++		return NULL;
     +	}
     +
    -+	out->submodule_prefix = xstrdup(path);
     +	out->submodule_prefix = xstrfmt("%s%s/",
     +					the_repository->submodule_prefix ?
     +					the_repository->submodule_prefix :
     +					"", path);
     +
     +	strbuf_release(&sb);
    -+	return 0;
    ++	return out;
     +}
     +
     +/*
    @@ -73,8 +74,7 @@
     + * If it can locate the submodule git directory it will create a repository
     + * handle for the submodule and lookup both the left and right commits and
     + * put them into the left and right pointers.
    -  */
    --static void show_submodule_header(struct diff_options *o, const char *path,
    ++ */
     +static void show_submodule_header(struct diff_options *o,
     +		const char *path,
      		struct object_id *one, struct object_id *two,
    @@ -116,11 +116,9 @@
      	struct rev_info rev;
      	struct commit *left = NULL, *right = NULL;
      	struct commit_list *merge_bases = NULL;
    -+	struct repository subrepo, *sub = &subrepo;
    -+
    -+	if (open_submodule(&subrepo, path) < 0)
    -+		sub = NULL;
    ++	struct repository *sub;
      
    ++	sub = open_submodule(path);
      	show_submodule_header(o, path, one, two, dirty_submodule,
     -			      &left, &right, &merge_bases);
     +			      sub, &left, &right, &merge_bases);
    @@ -147,8 +145,10 @@
      		free_commit_list(merge_bases);
      	clear_commit_marks(left, ~0);
      	clear_commit_marks(right, ~0);
    -+	if (sub)
    ++	if (sub) {
     +		repo_clear(sub);
    ++		free(sub);
    ++	}
      }
      
      void show_submodule_inline_diff(struct diff_options *o, const char *path,
    @@ -156,11 +156,9 @@
      	struct commit_list *merge_bases = NULL;
      	struct child_process cp = CHILD_PROCESS_INIT;
      	struct strbuf sb = STRBUF_INIT;
    -+	struct repository subrepo, *sub = &subrepo;
    -+
    -+	if (open_submodule(&subrepo, path) < 0)
    -+		sub = NULL;
    ++	struct repository *sub;
      
    ++	sub = open_submodule(path);
      	show_submodule_header(o, path, one, two, dirty_submodule,
     -			      &left, &right, &merge_bases);
     +			      sub, &left, &right, &merge_bases);
    @@ -171,8 +169,10 @@
      		clear_commit_marks(left, ~0);
      	if (right)
      		clear_commit_marks(right, ~0);
    -+	if (sub)
    ++	if (sub) {
     +		repo_clear(sub);
    ++		free(sub);
    ++	}
      }
      
      int should_update_submodules(void)
 19:  dbb0dd9322 ! 136:  df748a859f submodule: don't add submodule as odb for push
    @@ -8,8 +8,10 @@
         objects, and the actual push is done by spawning another process,
         which handles object access by itself.)
     
    +    This code of push_submodule() is exercised in t5531 and continues
    +    to work, showing that the submodule odbc is not needed.
    +
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
  -:  ---------- > 137:  c9e990afac commit-graph: convert remaining function to handle arbitrary repositories
  -:  ---------- > 138:  a086f3dd11 commit: make free_commit_buffer and release_commit_memory repository agnostic
  -:  ---------- > 139:  878bd34799 path.h: make REPO_GIT_PATH_FUNC repository agnostic
  -:  ---------- > 140:  641824bbeb t/helper/test-repository: celebrate independence from the_repository

^ permalink raw reply	[relevance 7%]

* Git Test Coverage Report (Tuesday, Oct 30)
@ 2018-10-30 13:37  3% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-10-30 13:37 UTC (permalink / raw)
  To: Git List

This coverage report uses a new build definition that runs the four 
suites in parallel, then combines the results into the report below. You 
can see the build that generated this report at [1].

Thanks,
-Stolee

[1] https://git.visualstudio.com/git/_build/results?buildId=235&view=logs

---

pu: 7f50cad4af91f508e14338e87c5911f990d0a938
jch: 13c38c20c0c9afee77ede86d423027eb79c51ced
next: 53cd27f688b0bae2a5f2d8f5cea6ba63c6e4a781
master: 4ede3d42dfb57f9a41ac96a1f216c62eb7566cc2
master@{1}: c670b1f876521c9f7cd40184bf7ed05aad843433

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
7f50cad4af builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    924) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    925) break;

builtin/describe.c
7f50cad4af builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/fsck.c
372738935a builtin/fsck.c 622) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
372738935a builtin/fsck.c 627) return error(_("invalid %s"), head_ref_name);

builtin/grep.c
c22b820141 builtin/grep.c  429) grep_read_unlock();

builtin/pack-objects.c
7f50cad4af builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 585) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 621) continue;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fsck.c
7f50cad4af  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
7f50cad4af  878) repo_read_object_file(the_repository,
7f50cad4af  879)       &tag->object.oid, &type, &size);

http-push.c
7f50cad4af 1635) if (!repo_has_object_file(the_repository, &head_oid))
7f50cad4af 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

merge-recursive.c
4cdc48e412 1585) return -1;
4cdc48e412 1588) return -1;
4cdc48e412 1594) return -1;
4cdc48e412 1596) if (update_file(o, 1, b_oid, b_mode, collide_path))
4cdc48e412 1597) return -1;
4cdc48e412 1664) return -1;
4cdc48e412 1667) return -1;
4cdc48e412 1670) return -1;
b58ae691c0 1703) return -1;
387361a6a7 1738) return -1;
387361a6a7 1786) return -1;
387361a6a7 1795) new_path = unique_path(o, a->path, ci->branch1);
387361a6a7 1796) output(o, 1, _("Refusing to lose untracked file"
387361a6a7 1802) return -1;
387361a6a7 1805) return -1;
387361a6a7 1815) return -1;
387361a6a7 1831) return -1;
387361a6a7 1834) return -1;

midx.c
1dcd9f2043  184) return;

negotiator/default.c
7f50cad4af  71) if (repo_parse_commit(the_repository, commit))

packfile.c
dc7d664335  350) close_midx(o->multi_pack_index);
dc7d664335  351) o->multi_pack_index = NULL;

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
7f50cad4af  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
7f50cad4af 1624) repo_unuse_commit_buffer(the_repository, head_commit,
7f50cad4af 3865) repo_unuse_commit_buffer(the_repository,

sha1-array.c
7fdf90d541 91) oidcpy(&oids[dst], &oids[src]);

submodule-config.c
bcbc780d14 740) return CONFIG_INVALID_KEY;
45f5ef3d77 755) warning(_("Could not update .gitmodules entry %s"), key);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
060675d4fc 1378) strbuf_release(&gitdir);
183be9660a 1501) struct get_next_submodule_task *task = task_cb;
183be9660a 1505) get_next_submodule_task_release(task);
183be9660a 1532) return 0;
183be9660a 1536) goto out;
183be9660a 1551) return 0;

tree.c
7f50cad4af 108) if (repo_parse_commit(the_repository, commit))

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Antonio Ospite      c22b82014: submodule: support reading .gitmodules 
when it's not in the working tree
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      dc7d66433: packfile: close multi-pack-index in 
close_all_packs
Elijah Newren      387361a6a: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      4cdc48e41: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      b58ae691c: merge-recursive: fix rename/add conflict 
handling
Junio C Hamano      372738935: Merge branch 
'nd/per-worktree-ref-iteration' into pu
Junio C Hamano      7f50cad4a: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Stefan Beller      060675d4f: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      183be9660: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      7fdf90d54: sha1-array: provide oid_array_filter
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup



Uncovered code in 'jch' not in 'next'
----------------------------------------

archive.c
48a40549d5 399) die(_("'%s' is not a valid object name"), name);
48a40549d5 412) die(_("%s is not a tree object"), oid_to_hex(&oid));
48a40549d5 422) die(_("current working directory is untracked"));

attr.c
847aa0ff7a  369) fprintf(stderr, _("%s not allowed: %s:%d\n"),

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/fetch.c
builtin/fsck.c
09120ea781 builtin/fsck.c 154) objerror(parent, _("wrong object type in 
link"));
09120ea781 builtin/fsck.c 265) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
09120ea781 builtin/fsck.c 293) error(_("could not create lost-found"));
09120ea781 builtin/fsck.c 300) die_errno(_("could not write '%s'"), 
filename);
09120ea781 builtin/fsck.c 304) die_errno(_("could not finish '%s'"),
09120ea781 builtin/fsck.c 321) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
09120ea781 builtin/fsck.c 339) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
09120ea781 builtin/fsck.c 358) fprintf_ln(stderr, _("Checking %s %s"),
09120ea781 builtin/fsck.c 371) printf_ln(_("root %s"),
09120ea781 builtin/fsck.c 407) return error(_("%s: object corrupt or 
missing"),
09120ea781 builtin/fsck.c 446) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
09120ea781 builtin/fsck.c 545) error(_("%s: object could not be parsed: 
%s"),
09120ea781 builtin/fsck.c 580) fprintf_ln(stderr, _("Checking object 
directory"));
09120ea781 builtin/fsck.c 596) fprintf_ln(stderr, _("Checking HEAD link"));
09120ea781 builtin/fsck.c 601) return error(_("invalid HEAD"));
09120ea781 builtin/fsck.c 628) fprintf_ln(stderr, _("Checking cache tree"));
09120ea781 builtin/fsck.c 644) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/grep.c
389f2f2d79 builtin/grep.c 1034) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/merge.c
35408df41e builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/reflog.c
b9c4009cca builtin/reflog.c 563) usage(_(reflog_expire_usage));
b9c4009cca builtin/reflog.c 605) status |= error(_("%s points 
nowhere!"), argv[i]);
b9c4009cca builtin/reflog.c 651) usage(_(reflog_delete_usage));
b9c4009cca builtin/reflog.c 657) return error(_("nothing to delete?"));
b9c4009cca builtin/reflog.c 666) status |= error(_("not a reflog: %s"), 
argv[i]);
b9c4009cca builtin/reflog.c 671) status |= error(_("no reflog for 
'%s'"), argv[i]);
b9c4009cca builtin/reflog.c 706) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 714) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 717) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
eb6c5a15dc 200) die(_("could not start pack-objects to repack promisor 
objects"));
3e582cd8a1 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
eb6c5a15dc 250) die_errno(("unable to create '%s'"), promisor_name);
3e582cd8a1 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

git.c
b63c352c11 341) die_errno(_("while expanding alias '%s': '%s'"),
b63c352c11 350) die(_("alias '%s' changes environment variables.\n"
b63c352c11 358) die(_("empty alias for %s"), alias_command);
b63c352c11 361) die(_("recursive alias: %s"), alias_command);
b63c352c11 436) die_errno(_("write failure on standard output"));
b63c352c11 438) die(_("unknown write failure on standard output"));
b63c352c11 440) die_errno(_("close failed on standard output"));
b63c352c11 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

name-hash.c
31bfd155d8 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
31bfd155d8 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
31bfd155d8 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

parse-options-cb.c
35408df41e  21) return error(_("option `%s' expects a numerical value"),
35408df41e  58) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
35408df41e  88) return error(_("%s takes no value"), optname(opt, flags));
35408df41e  90) return error(_("%s isn't available"), optname(opt, flags));
35408df41e  92) return error(_("%s takes no value"), optname(opt, flags));
35408df41e 178) return error(_("%s expects a numerical value"),
35408df41e 194) return error(_("%s expects a non-negative integer value"
e0948db833 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
e0948db833 651) error(_("unknown non-ascii option in string: `%s'"),
35408df41e 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

preload-index.c
31bfd155d8 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
5257b0625a  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
5257b0625a  676)     ce->name, alias->name);
5257b0625a  691) die(_("cannot create an empty blob in the object 
database"));
5257b0625a  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
5257b0625a  786) return error(_("unable to add '%s' to index"), path);
5257b0625a  822) error(_("invalid path '%s'"), path);
5257b0625a  848) error(_("invalid path '%s'"), path);
5257b0625a 1680) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
5257b0625a 1683) return error(_("bad index version %d"), hdr_version);
5257b0625a 1722) return error(_("index uses %.4s extension, which we do 
not understand"),
5257b0625a 1724) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
5257b0625a 1771) die(_("unknown index entry format 0x%08x"), 
extended_flags);
5257b0625a 1842) die(_("unordered stage entries in index"));
5257b0625a 1845) die(_("multiple stage entries for merged file '%s'"),
5257b0625a 1848) die(_("unordered stage entries for '%s'"),
5257b0625a 2142) die_errno(_("%s: index file open failed"), path);
5257b0625a 2146) die_errno(_("%s: cannot stat the open index"), path);
5257b0625a 2150) die(_("%s: index file smaller than expected"), path);
5257b0625a 2154) die_errno(_("%s: unable to map index file"), path);
5257b0625a 2246) warning(_("could not freshen shared index '%s'"), 
shared_index);
5257b0625a 2281) die(_("broken index, expect %s in %s, got %s"),
5257b0625a 3067) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
5257b0625a 3213) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
35408df41e 2324) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
a454d6a26b  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
a454d6a26b  417) error(_("more than one uploadpack given, using the 
first"));
a454d6a26b  683) die(_("key '%s' of pattern had no '*'"), key);
a454d6a26b  693) die(_("value '%s' of pattern has no '*'"), value);
a454d6a26b 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
a454d6a26b 1066) return error(_("dst ref %s receives from more than one 
src"),
a454d6a26b 1753) die(_("couldn't find remote ref %s"), name);
a454d6a26b 1766) error(_("* Ignoring funny ref '%s' locally"),
a454d6a26b 1861) die(_("revision walk setup failed"));
a454d6a26b 2134) return error(_("cannot parse expected object name '%s'"),

revision.c
a63d88e595 2932) return;
a63d88e595 2935) return;
a63d88e595 2941) c->object.flags |= UNINTERESTING;
a63d88e595 2944) return;
a63d88e595 2947) mark_parents_uninteresting(c);
a63d88e595 2970) return;
a63d88e595 2973) return;
a63d88e595 2978) return;
a63d88e595 3042) continue;
f33f8de6af 3090) if (!revs->ignore_missing_links)
f33f8de6af 3091) die("Failed to traverse parents of commit %s",
a63d88e595 3092) oid_to_hex(&commit->object.oid));
a63d88e595 3100) continue;

run-command.c
31bfd155d8 1229) error(_("cannot create async thread: %s"), strerror(err));

sequencer.c
08b6ba5cc0  683) np = strchrnul(buf, '\n');
08b6ba5cc0  684) return error(_("unable to parse '%.*s'"),
08b6ba5cc0  695) return error(_("unable to dequote value of '%s'"),
08b6ba5cc0  737) goto finish;
08b6ba5cc0  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
08b6ba5cc0  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
08b6ba5cc0  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
08b6ba5cc0  756) err = error(_("unknown variable '%s'"),
08b6ba5cc0  761) error(_("missing 'GIT_AUTHOR_NAME'"));
08b6ba5cc0  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
08b6ba5cc0  765) error(_("missing 'GIT_AUTHOR_DATE'"));

setup.c
58b284a2e9  413) return config_error_nonbool(var);

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      a63d88e59: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f33f8de6a: revision.c: begin refactoring 
--topo-order logic
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Junio C Hamano      3e582cd8a: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      09120ea78: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      31bfd155d: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      35408df41: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      389f2f2d7: grep: remove #ifdef NO_PTHREADS
Nguyễn Thái Ngọc Duy      48a40549d: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      5257b0625: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      847aa0ff7: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      a454d6a26: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      b63c352c1: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      b9c4009cc: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      e0948db83: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      eb6c5a15d: repack: mark more strings for 
translation
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Phillip Wood      08b6ba5cc: add read_author_script() to libgit



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
55071ea248   61) strbuf_trim(&out);
55071ea248   62) ret = !strcmp("true", out.buf);
55071ea248   63) strbuf_release(&out);
002ee2fe68  115) die(_("%s requires an interactive rebase"), option);
f95736288a  148) return error_errno(_("could not read '%s'"), path);
f95736288a  162) return -1;
f95736288a  167) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  178) return -1;
f95736288a  179) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  180) return -1;
f95736288a  182) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  186) return -1;
f95736288a  188) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  196) opts->signoff = 1;
73d51ed0a5  197) opts->flags |= REBASE_FORCE;
ead98c111b  204) return -1;
12026a412c  219) return -1;
ba1905a5fe  227) return -1;
ba1905a5fe  235) return -1;
6defce2b02  255) return error(_("Could not read '%s'"), path);
6defce2b02  273) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  277) return res;
bc24382c2b  375) argv_array_pushf(&child.args,
bc24382c2b  377) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  509) struct strbuf dir = STRBUF_INIT;
6defce2b02  511) apply_autostash(opts);
ac7f467fef  512) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  513) remove_dir_recursively(&dir, 0);
ac7f467fef  514) strbuf_release(&dir);
ac7f467fef  515) die("Nothing to do");
ac7f467fef  545) return -1;
ac7f467fef  549) rollback_lock_file(&lock);
ac7f467fef  550) return error(_("could not determine HEAD revision"));
ac7f467fef  567) rollback_lock_file(&lock);
ac7f467fef  568) return error(_("could not read index"));
ac7f467fef  572) error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef  573) rollback_lock_file(&lock);
ac7f467fef  574) free((void *)desc.buffer);
ac7f467fef  575) return -1;
ac7f467fef  588) ret = error(_("could not write index"));
ac7f467fef  592) return ret;
ac7f467fef  608) } else if (old_orig)
ac7f467fef  609) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  637) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  671) return 1;
9a48a615b4  687) return 0;
55071ea248  895) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  898) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  899) die_errno(_("could not exec %s"), path);
0eabf4b95c  917) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  954) usage_with_options(builtin_rebase_usage,
f95736288a  974) die(_("Cannot read HEAD"));
f95736288a  978) die(_("could not read index"));
f95736288a  992) exit(1);
122420c295 1004) die(_("could not discard worktree changes"));
122420c295 1006) exit(1);
5e5d96197c 1017) exit(1);
5e5d96197c 1020) die(_("could not move back to %s"),
5a61494539 1030) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1049) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1050) const char *state_dir_base =
c54dacb50e 1051) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1052) const char *cmd_live_rebase =
c54dacb50e 1054) strbuf_reset(&buf);
c54dacb50e 1055) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1056) die(_("It seems that there is already a %s directory, 
and\n"
53f9e5be94 1080) strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94 1081) options.flags |= REBASE_FORCE;
7998dbe1ec 1093) strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
3c3588c7d3 1125) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1126) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1148) die(_("--strategy requires --merge or --interactive"));
cda614e489 1166) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1175) options.state_dir = apply_dir();
ac7f467fef 1176) break;
ac7f467fef 1253) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1259) die(_("Could not create new root commit"));
e65123a71d 1309) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1317) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1329) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1342) die(_("could not read index"));
6defce2b02 1369) die(_("Cannot autostash"));
6defce2b02 1372) die(_("Unexpected stash response: '%s'"),
6defce2b02 1378) die(_("Could not create directory for '%s'"),
6defce2b02 1384) die(_("could not reset --hard"));
e65123a71d 1428) ret = !!error(_("could not parse '%s'"),
e65123a71d 1430) goto cleanup;
e65123a71d 1439) ret = !!error(_("could not switch to "
1ed9c14ff2 1449)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1450) puts(_("HEAD is up to date."));
9a48a615b4 1459)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1460) puts(_("HEAD is up to date, rebase forced."));

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

gpg-interface.c
4de9394dcb 155) break;

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

sequencer.c
65850686cf 2278) return;
65850686cf 2375) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3373) return error(_("could not checkout %s"), commit);
4df66c40b0 3387) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3407) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4771) return -1;
b97e187364 4774) return -1;
b97e187364 4780) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4783) todo_list_release(&todo_list);
b97e187364 4784) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4803) todo_list_release(&todo_list);
b97e187364 4804) return -1;
b97e187364 4808) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4812) return error(_("could not transform the todo list"));
b97e187364 4841) return error(_("could not transform the todo list"));
b97e187364 4844) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4850) return -1;

strbuf.c
f95736288a  127) --sb->len;

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      53f9e5be9: builtin rebase: support `ignore-date` option
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      7998dbe1e: builtin rebase: support `-C` and 
`--whitespace=<type>`
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

apply.c
eccb5a5f3d 4071) return get_oid_hex(p->old_oid_prefix, oid);

builtin/repack.c
2f0c9e9a9b 239) die("repack: Expecting full hex object ID lines only 
from pack-objects.");
2f0c9e9a9b 411) die("repack: Expecting full hex object ID lines only 
from pack-objects.");

builtin/rev-list.c
7c0fe330d5 builtin/rev-list.c 227) die("unexpected missing %s object '%s'",
7c0fe330d5 builtin/rev-list.c 228)     type_name(obj->type), 
oid_to_hex(&obj->oid));

list-objects-filter-options.c
bc5975d24f  55) if (errbuf) {
bc5975d24f  56) strbuf_addstr(
bc5975d24f  60) return 1;
cc0b05a4cc  86) if (errbuf)

list-objects-filter.c
list-objects.c
f447a499db 200) ctx->show_object(obj, base->buf, ctx->show_data);

ref-filter.c
f0062d3b74 1035) v->s = xstrdup("");
f0062d3b74 1298) free((char *)to_free);
f0062d3b74 1299) return xstrdup("");
f0062d3b74 1336) free((char *)to_free);
f0062d3b74 1337) return xstrdup("");
f0062d3b74 1387) *s = xstrdup("=");
f0062d3b74 1389) *s = xstrdup("<");
f0062d3b74 1514) ref->symref = xstrdup("");
f0062d3b74 1583) v->s = xstrdup("");

Commits introducing uncovered code:
brian m. carlson      2f0c9e9a9: builtin/repack: replace hard-coded 
constants
brian m. carlson      eccb5a5f3: apply: rename new_sha1_prefix and 
old_sha1_prefix
Matthew DeVore      7c0fe330d: rev-list: handle missing tree objects 
properly
Matthew DeVore      bc5975d24: list-objects-filter: implement filter tree:0
Matthew DeVore      cc0b05a4c: list-objects-filter-options: do not 
over-strbuf_init
Matthew DeVore      f447a499d: list-objects: store common func args in 
struct
Olga Telezhnaya      f0062d3b7: ref-filter: free item->value and 
item->value->s

^ permalink raw reply	[relevance 3%]

* Re: [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip
  @ 2018-10-29  3:44  4% ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-10-29  3:44 UTC (permalink / raw)
  To: Stefan Beller; +Cc: jonathantanmy, git

Stefan Beller <sbeller@google.com> writes:

> Thanks Jonathan for your thoughtful comments,
> here is the product of the discussion:

Can you use v$n in the subject (if these rerolls are meant for
application and not primarily for discussion, that is)?  It quickly
gets confusing to see many messages with the same subject from
different attempts.

> This is still based on ao/submodule-wo-gitmodules-checked-out.

... which just got updated but I think only one test script changed,
so I expect there won't be anything unexpected when I queue this on
top of a merge of that topic and master.

It seems that the first three preparatory steps haven't changed,
patch #4-#7 have moderate amount of changes, and the previous #8 got
updated quite a lot.  Let's see how well this and updated base topic
will play with other topics in flight.

Thanks.

> previous version
> https://public-inbox.org/git/20181016181327.107186-1-sbeller@google.com/
>
> Stefan Beller (10):
>   sha1-array: provide oid_array_filter
>   submodule.c: fix indentation
>   submodule.c: sort changed_submodule_names before searching it
>   submodule.c: tighten scope of changed_submodule_names struct
>   submodule: store OIDs in changed_submodule_names
>   repository: repo_submodule_init to take a submodule struct
>   submodule: migrate get_next_submodule to use repository structs
>   submodule.c: fetch in submodules git directory instead of in worktree
>   fetch: try fetching submodules if needed objects were not fetched
>   builtin/fetch: check for submodule updates in any ref update
>
>  Documentation/technical/api-oid-array.txt    |   5 +
>  builtin/fetch.c                              |  11 +-
>  builtin/grep.c                               |  17 +-
>  builtin/ls-files.c                           |  12 +-
>  builtin/submodule--helper.c                  |   2 +-
>  repository.c                                 |  27 +-
>  repository.h                                 |  12 +-
>  sha1-array.c                                 |  17 ++
>  sha1-array.h                                 |   3 +
>  submodule.c                                  | 265 ++++++++++++++++---
>  t/helper/test-submodule-nested-repo-config.c |   8 +-
>  t/t5526-fetch-submodules.sh                  |  55 ++++
>  12 files changed, 346 insertions(+), 88 deletions(-)
>
>   git range-diff origin/sb/submodule-recursive-fetch-gets-the-tip... 
>
> 1:  3fbb06aedd ! 1:  0fdb0e2ad9 submodule.c: move global changed_submodule_names into fetch submodule struct
>     @@ -1,12 +1,11 @@
>      Author: Stefan Beller <sbeller@google.com>
>      
>     -    submodule.c: move global changed_submodule_names into fetch submodule struct
>     +    submodule.c: tighten scope of changed_submodule_names struct
>      
>          The `changed_submodule_names` are only used for fetching, so let's make it
>          part of the struct that is passed around for fetching submodules.
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>      diff --git a/submodule.c b/submodule.c
>      --- a/submodule.c
>     @@ -16,7 +15,6 @@
>       
>       static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
>      -static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
>     -+
>       static int initialized_fetch_ref_tips;
>       static struct oid_array ref_tips_before_fetch;
>       static struct oid_array ref_tips_after_fetch;
>     @@ -25,22 +23,8 @@
>       }
>       
>      -static void calculate_changed_submodule_paths(void)
>     -+struct submodule_parallel_fetch {
>     -+	int count;
>     -+	struct argv_array args;
>     -+	struct repository *r;
>     -+	const char *prefix;
>     -+	int command_line_option;
>     -+	int default_option;
>     -+	int quiet;
>     -+	int result;
>     -+
>     -+	struct string_list changed_submodule_names;
>     -+};
>     -+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
>     -+
>      +static void calculate_changed_submodule_paths(
>     -+	struct submodule_parallel_fetch *spf)
>     ++	struct string_list *changed_submodule_names)
>       {
>       	struct argv_array argv = ARGV_ARRAY_INIT;
>       	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
>     @@ -49,30 +33,23 @@
>       
>       		if (!submodule_has_commits(path, commits))
>      -			string_list_append(&changed_submodule_names, name->string);
>     -+			string_list_append(&spf->changed_submodule_names,
>     ++			string_list_append(changed_submodule_names,
>      +					   name->string);
>       	}
>       
>       	free_submodules_oids(&changed_submodules);
>      @@
>     - 	return ret;
>     - }
>     - 
>     --struct submodule_parallel_fetch {
>     --	int count;
>     --	struct argv_array args;
>     --	struct repository *r;
>     --	const char *prefix;
>     --	int command_line_option;
>     --	int default_option;
>     --	int quiet;
>     --	int result;
>     --};
>     + 	int default_option;
>     + 	int quiet;
>     + 	int result;
>     ++
>     ++	struct string_list changed_submodule_names;
>     + };
>      -#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0}
>     --
>     ++#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
>     + 
>       static int get_fetch_recurse_config(const struct submodule *submodule,
>       				    struct submodule_parallel_fetch *spf)
>     - {
>      @@
>       		case RECURSE_SUBMODULES_ON_DEMAND:
>       			if (!submodule ||
>     @@ -88,7 +65,7 @@
>       
>      -	calculate_changed_submodule_paths();
>      -	string_list_sort(&changed_submodule_names);
>     -+	calculate_changed_submodule_paths(&spf);
>     ++	calculate_changed_submodule_paths(&spf.changed_submodule_names);
>      +	string_list_sort(&spf.changed_submodule_names);
>       	run_processes_parallel(max_parallel_jobs,
>       			       get_next_submodule,
> 2:  a64a8322a1 ! 2:  a11e6e39a2 submodule.c: do not copy around submodule list
>     @@ -1,6 +1,6 @@
>      Author: Stefan Beller <sbeller@google.com>
>      
>     -    submodule.c: do not copy around submodule list
>     +    submodule: store OIDs in changed_submodule_names
>      
>          'calculate_changed_submodule_paths' uses a local list to compute the
>          changed submodules, and then produces the result by copying appropriate
>     @@ -14,13 +14,13 @@
>          useful in a later patch.
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>     +    Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
>      
>      diff --git a/submodule.c b/submodule.c
>      --- a/submodule.c
>      +++ b/submodule.c
>      @@
>     - 	struct submodule_parallel_fetch *spf)
>     + 	struct string_list *changed_submodule_names)
>       {
>       	struct argv_array argv = ARGV_ARRAY_INIT;
>      -	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
>     @@ -34,10 +34,10 @@
>       	 * commits have been recorded upstream in "changed_submodule_names".
>       	 */
>      -	collect_changed_submodules(&changed_submodules, &argv);
>     -+	collect_changed_submodules(&spf->changed_submodule_names, &argv);
>     ++	collect_changed_submodules(changed_submodule_names, &argv);
>       
>      -	for_each_string_list_item(name, &changed_submodules) {
>     -+	for_each_string_list_item(name, &spf->changed_submodule_names) {
>     ++	for_each_string_list_item(name, changed_submodule_names) {
>       		struct oid_array *commits = name->util;
>       		const struct submodule *submodule;
>       		const char *path = NULL;
>     @@ -46,7 +46,7 @@
>       			continue;
>       
>      -		if (!submodule_has_commits(path, commits))
>     --			string_list_append(&spf->changed_submodule_names,
>     +-			string_list_append(changed_submodule_names,
>      -					   name->string);
>      +		if (submodule_has_commits(path, commits)) {
>      +			oid_array_clear(commits);
>     @@ -55,7 +55,7 @@
>       	}
>       
>      -	free_submodules_oids(&changed_submodules);
>     -+	string_list_remove_empty_items(&spf->changed_submodule_names, 1);
>     ++	string_list_remove_empty_items(changed_submodule_names, 1);
>      +
>       	argv_array_clear(&argv);
>       	oid_array_clear(&ref_tips_before_fetch);
> 3:  9341b92c83 ! 3:  3f4e0d4b8d repository: repo_submodule_init to take a submodule struct
>     @@ -5,17 +5,19 @@
>          When constructing a struct repository for a submodule for some revision
>          of the superproject where the submodule is not contained in the index,
>          it may not be present in the working tree currently either. In that
>     -    siutation giving a 'path' argument is not useful. Upgrade the
>     +    situation giving a 'path' argument is not useful. Upgrade the
>          repo_submodule_init function to take a struct submodule instead.
>     +    The submodule struct can be obtained via submodule_from_{path, name} or
>     +    an artificial submodule struct can be passed in.
>      
>     -    While we are at it, overhaul the repo_submodule_init function by renaming
>     -    the submodule repository struct, which is to be initialized, to a name
>     -    that is not confused with the struct submodule as easily.
>     +    While we are at it, rename the repository struct in the repo_submodule_init
>     +    function, which is to be initialized, to a name that is not confused with
>     +    the struct submodule as easily. Perform such renames in similar functions
>     +    as well.
>      
>          Also move its documentation into the header file.
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>      diff --git a/builtin/grep.c b/builtin/grep.c
>      --- a/builtin/grep.c
>     @@ -104,6 +106,19 @@
>       
>       static void show_ce(struct repository *repo, struct dir_struct *dir,
>      
>     +diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
>     +--- a/builtin/submodule--helper.c
>     ++++ b/builtin/submodule--helper.c
>     +@@
>     + 	if (!sub)
>     + 		BUG("We could get the submodule handle before?");
>     + 
>     +-	if (repo_submodule_init(&subrepo, the_repository, path))
>     ++	if (repo_submodule_init(&subrepo, the_repository, sub))
>     + 		die(_("could not get a repository handle for submodule '%s'"), path);
>     + 
>     + 	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
>     +
>      diff --git a/repository.c b/repository.c
>      --- a/repository.c
>      +++ b/repository.c
>     @@ -178,7 +193,8 @@
>      +/*
>      + * Initialize the repository 'subrepo' as the submodule given by the
>      + * struct submodule 'sub' in parent repository 'superproject'.
>     -+ * Return 0 upon success and a non-zero value upon failure.
>     ++ * Return 0 upon success and a non-zero value upon failure, which may happen
>     ++ * if the submodule is not found, or 'sub' is NULL.
>      + */
>      +struct submodule;
>      +int repo_submodule_init(struct repository *subrepo,
> 4:  cea909cbd4 ! 4:  b1566069e7 submodule: fetch in submodules git directory instead of in worktree
>     @@ -1,44 +1,19 @@
>      Author: Stefan Beller <sbeller@google.com>
>      
>     -    submodule: fetch in submodules git directory instead of in worktree
>     +    submodule: migrate get_next_submodule to use repository structs
>      
>     -    This patch started as a refactoring to make 'get_next_submodule' more
>     -    readable, but upon doing so, I realized that "git fetch" of the submodule
>     -    actually doesn't need to be run in the submodules worktree. So let's run
>     -    it in its git dir instead.
>     +    We used to recurse into submodules, even if they were broken having
>     +    only an objects directory. The child process executed in the submodule
>     +    would fail though if the submodule was broken.
>      
>     -    That should pave the way towards fetching submodules that are currently
>     -    not checked out.
>     -
>     -    This patch leaks the cp->dir in get_next_submodule, as any further
>     -    callback in run_processes_parallel doesn't have access to the child
>     -    process any more. In an early iteration of this patch, the function
>     -    get_submodule_repo_for directly returned the string containing the
>     -    git directory, which would be a better design choice for this patch.
>     -
>     -    However the next patch both fixes the memory leak of cp->dir and also has
>     -    a use case for using the full repository handle of the submodule, so
>     -    it makes sense to introduce the get_submodule_repo_for here already.
>     +    This patch tightens the check upfront, such that we do not need
>     +    to spawn a child process to find out if the submodule is broken.
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>      diff --git a/submodule.c b/submodule.c
>      --- a/submodule.c
>      +++ b/submodule.c
>     -@@
>     - 			 DEFAULT_GIT_DIR_ENVIRONMENT);
>     - }
>     - 
>     -+static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out)
>     -+{
>     -+	prepare_submodule_repo_env_no_git_dir(out);
>     -+	argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT);
>     -+}
>     -+
>     - /* Helper function to display the submodule header line prior to the full
>     -  * summary output. If it can locate the submodule objects directory it will
>     -  * attempt to lookup both the left and right commits and put them into the
>      @@
>       	return spf->default_option;
>       }
>     @@ -99,9 +74,8 @@
>      +		if (repo) {
>       			child_process_init(cp);
>      -			cp->dir = strbuf_detach(&submodule_path, NULL);
>     --			prepare_submodule_repo_env(&cp->env_array);
>     -+			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
>     -+			cp->dir = xstrdup(repo->gitdir);
>     + 			prepare_submodule_repo_env(&cp->env_array);
>     ++			cp->dir = xstrdup(repo->worktree);
>       			cp->git_cmd = 1;
>       			if (!spf->quiet)
>       				strbuf_addf(err, "Fetching submodule %s%s\n",
>     @@ -113,27 +87,17 @@
>      +			repo_clear(repo);
>      +			free(repo);
>       			ret = 1;
>     ++		} else {
>     ++			/*
>     ++			 * An empty directory is normal,
>     ++			 * the submodule is not initialized
>     ++			 */
>     ++			if (S_ISGITLINK(ce->ce_mode) &&
>     ++			    !is_empty_dir(ce->name))
>     ++				die(_("Could not access submodule '%s'"), ce->name);
>       		}
>      -		strbuf_release(&submodule_path);
>      -		strbuf_release(&submodule_git_dir);
>       		strbuf_release(&submodule_prefix);
>       		if (ret) {
>       			spf->count++;
>     -
>     -diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
>     ---- a/t/t5526-fetch-submodules.sh
>     -+++ b/t/t5526-fetch-submodules.sh
>     -@@
>     - 
>     - 	test_must_fail git -C dst status &&
>     - 	test_must_fail git -C dst diff &&
>     --	test_must_fail git -C dst fetch --recurse-submodules
>     -+
>     -+	# git-fetch cannot find the git directory of the submodule,
>     -+	# so it will do nothing, successfully, as it cannot distinguish between
>     -+	# this broken submodule and a submodule that was just set active but
>     -+	# not cloned yet
>     -+	git -C dst fetch --recurse-submodules
>     - '
>     - 
>     - test_expect_success "fetch new commits when submodule got renamed" '
> -:  ---------- > 5:  2d98ff1201 submodule.c: fetch in submodules git directory instead of in worktree
> 5:  9ad0125310 ! 6:  092b9cbcba fetch: retry fetching submodules if needed objects were not fetched
>     @@ -1,25 +1,23 @@
>      Author: Stefan Beller <sbeller@google.com>
>      
>     -    fetch: retry fetching submodules if needed objects were not fetched
>     +    fetch: try fetching submodules if needed objects were not fetched
>      
>          Currently when git-fetch is asked to recurse into submodules, it dispatches
>          a plain "git-fetch -C <submodule-dir>" (with some submodule related options
>          such as prefix and recusing strategy, but) without any information of the
>          remote or the tip that should be fetched.
>      
>     -    This works surprisingly well in some workflows (such as using submodules
>     -    as a third party library), while not so well in other scenarios, such
>     -    as in a Gerrit topic-based workflow, that can tie together changes
>     -    (potentially across repositories) on the server side. One of the parts
>     -    of such a Gerrit workflow is to download a change when wanting to examine
>     -    it, and you'd want to have its submodule changes that are in the same
>     -    topic downloaded as well. However these submodule changes reside in their
>     -    own repository in their own ref (refs/changes/<int>).
>     +    But this default fetch is not sufficient, as a newly fetched commit in
>     +    the superproject could point to a commit in the submodule that is not
>     +    in the default refspec. This is common in workflows like Gerrit's.
>     +    When fetching a Gerrit change under review (from refs/changes/??), the
>     +    commits in that change likely point to submodule commits that have not
>     +    been merged to a branch yet.
>      
>     -    Retry fetching a submodule by object name if the object id that the
>     +    Try fetching a submodule by object id if the object id that the
>          superproject points to, cannot be found.
>      
>     -    This retrying does not happen when the "git fetch" done at the
>     +    The try does not happen when the "git fetch" done at the
>          superproject is not storing the fetched results in remote
>          tracking branches (i.e. instead just recording them to
>          FETCH_HEAD) in this step. A later patch will fix this.
>     @@ -32,7 +30,6 @@
>          in case the submodule recursion is set to "on".
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>      diff --git a/builtin/fetch.c b/builtin/fetch.c
>      --- a/builtin/fetch.c
>     @@ -75,16 +72,16 @@
>       	int result;
>       
>       	struct string_list changed_submodule_names;
>     -+	struct get_next_submodule_task **retry;
>     -+	int retry_nr, retry_alloc;
>     ++	struct get_next_submodule_task **fetch_specific_oids;
>     ++	int fetch_specific_oids_nr, fetch_specific_oids_alloc;
>       };
>      -#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
>      +#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \
>      +		  STRING_LIST_INIT_DUP, \
>      +		  NULL, 0, 0}
>       
>     - static void calculate_changed_submodule_paths(
>     - 	struct submodule_parallel_fetch *spf)
>     + static int get_fetch_recurse_config(const struct submodule *submodule,
>     + 				    struct submodule_parallel_fetch *spf)
>      @@
>       	return spf->default_option;
>       }
>     @@ -93,6 +90,8 @@
>      +	struct repository *repo;
>      +	const struct submodule *sub;
>      +	unsigned free_sub : 1; /* Do we need to free the submodule? */
>     ++
>     ++	/* fetch specific oids if set, otherwise fetch default refspec */
>      +	struct oid_array *commits;
>      +};
>      +
>     @@ -224,24 +223,29 @@
>      -			repo_clear(repo);
>      -			free(repo);
>      -			ret = 1;
>     --		}
>     --		strbuf_release(&submodule_prefix);
>     --		if (ret) {
>     - 			spf->count++;
>     ++			spf->count++;
>      +			*task_cb = task;
>      +
>      +			strbuf_release(&submodule_prefix);
>     - 			return 1;
>     -+		} else {
>     ++			return 1;
>     + 		} else {
>     ++
>      +			get_next_submodule_task_release(task);
>      +			free(task);
>     ++
>     + 			/*
>     + 			 * An empty directory is normal,
>     + 			 * the submodule is not initialized
>     +@@
>     + 			    !is_empty_dir(ce->name))
>     + 				die(_("Could not access submodule '%s'"), ce->name);
>       		}
>     - 	}
>     ++	}
>      +
>     -+	if (spf->retry_nr) {
>     -+		struct get_next_submodule_task *task = spf->retry[spf->retry_nr - 1];
>     ++	if (spf->fetch_specific_oids_nr) {
>     ++		struct get_next_submodule_task *task = spf->fetch_specific_oids[spf->fetch_specific_oids_nr - 1];
>      +		struct strbuf submodule_prefix = STRBUF_INIT;
>     -+		spf->retry_nr--;
>     ++		spf->fetch_specific_oids_nr--;
>      +
>      +		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, task->sub->path);
>      +
>     @@ -262,9 +266,13 @@
>      +					  append_oid_to_argv, &cp->args);
>      +
>      +		*task_cb = task;
>     -+		strbuf_release(&submodule_prefix);
>     + 		strbuf_release(&submodule_prefix);
>     +-		if (ret) {
>     +-			spf->count++;
>     +-			return 1;
>     +-		}
>      +		return 1;
>     -+	}
>     + 	}
>      +
>       	return 0;
>       }
>     @@ -326,9 +334,11 @@
>      +			return 0;
>      +
>      +		task->commits = commits;
>     -+		ALLOC_GROW(spf->retry, spf->retry_nr + 1, spf->retry_alloc);
>     -+		spf->retry[spf->retry_nr] = task;
>     -+		spf->retry_nr++;
>     ++		ALLOC_GROW(spf->fetch_specific_oids,
>     ++			   spf->fetch_specific_oids_nr + 1,
>     ++			   spf->fetch_specific_oids_alloc);
>     ++		spf->fetch_specific_oids[spf->fetch_specific_oids_nr] = task;
>     ++		spf->fetch_specific_oids_nr++;
>      +		return 0;
>      +	}
>      +
>     @@ -346,18 +356,33 @@
>       	test_cmp expect actual
>       '
>       
>     -+test_expect_success "fetch new commits on-demand when they are not reachable" '
>     ++test_expect_success "fetch new submodule commits on-demand outside standard refspec" '
>     ++	# add a second submodule and ensure it is around in downstream first
>     ++	git clone submodule sub1 &&
>     ++	git submodule add ./sub1 &&
>     ++	git commit -m "adding a second submodule" &&
>     ++	git -C downstream pull &&
>     ++	git -C downstream submodule update --init --recursive &&
>     ++
>      +	git checkout --detach &&
>     ++
>      +	C=$(git -C submodule commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
>      +	git -C submodule update-ref refs/changes/1 $C &&
>      +	git update-index --cacheinfo 160000 $C submodule &&
>     -+	git commit -m "updated submodule outside of refs/heads" &&
>     -+	D=$(git rev-parse HEAD) &&
>     -+	git update-ref refs/changes/2 $D &&
>     ++	test_tick &&
>     ++
>     ++	D=$(git -C sub1 commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
>     ++	git -C sub1 update-ref refs/changes/2 $D &&
>     ++	git update-index --cacheinfo 160000 $D sub1 &&
>     ++
>     ++	git commit -m "updated submodules outside of refs/heads" &&
>     ++	E=$(git rev-parse HEAD) &&
>     ++	git update-ref refs/changes/2 $E &&
>      +	(
>      +		cd downstream &&
>     -+		git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2:refs/heads/my_branch &&
>     ++		git fetch --recurse-submodules origin refs/changes/2:refs/heads/my_branch &&
>      +		git -C submodule cat-file -t $C &&
>     ++		git -C sub1 cat-file -t $D &&
>      +		git checkout --recurse-submodules FETCH_HEAD
>      +	)
>      +'
> 6:  b8db3b45bf < -:  ---------- builtin/fetch: check for submodule updates for non branch fetches
> 7:  905a4f0d4f < -:  ---------- fixup! repository: repo_submodule_init to take a submodule struct
> -:  ---------- > 7:  11bf819782 builtin/fetch: check for submodule updates in any ref update

^ permalink raw reply	[relevance 4%]

* Git Test Coverage Report (Saturday, Oct 27)
@ 2018-10-27 13:27  4% Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-10-27 13:27 UTC (permalink / raw)
  To: git@vger.kernel.org

In an effort to ensure new code is reasonably covered by the test suite, 
we now have contrib/coverage-diff.sh to combine the gcov output from 
'make coverage-test ; make coverage-report' with the output from 'git 
diff A B' to discover _new_lines of code that are not covered. This 
report ignores lines including "BUG(".

This report takes the output of these results after running on four 
branches:

         pu: a5dda2204a27a14f65171e29307400194b522051
        jch: 280dd2581eb7191db037cf1243dd64fd200455ba
       next: 0250525e6984e0e5e803c7e2e3417279b036f1c9
     master: c670b1f876521c9f7cd40184bf7ed05aad843433
master@{1}: c4df23f7927d8d00e666a3c8d1b3375f1dc8a3c1


Uncovered in pu not in jch
--------------------------
(Note: t4041-diff-submodule-option.sh failed with extra test options, so 
some lines that
would be covered by that test run were not covered.)

builtin/blame.c
a5dda2204a builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    924) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    925) break;

builtin/describe.c
a5dda2204a builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/fsck.c
b29759d89a builtin/fsck.c 613) fprintf(stderr, "Checking %s link\n", 
head_ref_name);
b29759d89a builtin/fsck.c 618) return error("Invalid %s", head_ref_name);

builtin/grep.c
c22b820141 builtin/grep.c  442) grep_read_unlock();

builtin/pack-objects.c
a5dda2204a builtin/pack-objects.c 2852) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/rebase--interactive.c
6424061be4 builtin/rebase--interactive.c   23) return 
error_errno(_("could not read '%s'."), todo_file);
6424061be4 builtin/rebase--interactive.c   28) return 
error_errno(_("could not write '%s'"), todo_file);
7ccfac40bc builtin/rebase--interactive.c   43) return 
error_errno(_("could not read '%s'."), todo_file);
7ccfac40bc builtin/rebase--interactive.c   46) 
todo_list_release(&todo_list);
7ccfac40bc builtin/rebase--interactive.c   47) return error(_("unusable 
todo list: '%s'"), todo_file);
9787d17d40 builtin/rebase--interactive.c  294) ret = 
rearrange_squash_in_todo_file();

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 581) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 617) continue;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fsck.c
a5dda2204a  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
a5dda2204a  878) repo_read_object_file(the_repository,
a5dda2204a  879)       &tag->object.oid, &type, &size);

http-push.c
a5dda2204a 1635) if (!repo_has_object_file(the_repository, &head_oid))
a5dda2204a 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

merge-recursive.c
4cdc48e412 1585) return -1;
4cdc48e412 1588) return -1;
4cdc48e412 1594) return -1;
4cdc48e412 1596) if (update_file(o, 1, b_oid, b_mode, collide_path))
4cdc48e412 1597) return -1;
4cdc48e412 1664) return -1;
4cdc48e412 1667) return -1;
4cdc48e412 1670) return -1;
b58ae691c0 1703) return -1;
387361a6a7 1738) return -1;
387361a6a7 1786) return -1;
387361a6a7 1795) new_path = unique_path(o, a->path, ci->branch1);
387361a6a7 1796) output(o, 1, _("Refusing to lose untracked file"
387361a6a7 1802) return -1;
387361a6a7 1805) return -1;
387361a6a7 1815) return -1;
387361a6a7 1831) return -1;
387361a6a7 1834) return -1;

midx.c
1dcd9f2043  184) return;

negotiator/default.c
a5dda2204a  71) if (repo_parse_commit(the_repository, commit))

packfile.c
dc7d664335  350) close_midx(o->multi_pack_index);
dc7d664335  351) o->multi_pack_index = NULL;

rebase-interactive.c
b74a37a5a7  26) warning(_("unrecognized setting %s for option "
6424061be4 107) return error_errno(_("could not write '%s''"), todo_file);
6424061be4 110) return error(_("could not copy '%s' to '%s'."), todo_file,
b74a37a5a7 174) goto leave_check;

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
revision.c
a5dda2204a  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
a5dda2204a 1597) repo_unuse_commit_buffer(the_repository, head_commit,
a5dda2204a 3821) repo_unuse_commit_buffer(the_repository,
b5d6062402 4486) strbuf_insert(buf, todo_list->items[insert].offset_in_buf +
b5d6062402 4498) int sequencer_add_exec_commands(const char *commands)
06d8136126 4505) return error_errno(_("could not read '%s'."), todo_file);
b5d6062402 4507) if (todo_list_parse_insn_buffer(todo_list.buf.buf, 
&todo_list)) {
b5d6062402 4512) todo_list_add_exec_commands(&todo_list, commands);
b5d6062402 4513) res = write_message(todo_list.buf.buf, 
todo_list.buf.len, todo_file, 0);
0cce4a2756 4514) todo_list_release(&todo_list);
b5d6062402 4516) return res;
b74a37a5a7 4576) goto out;
b74a37a5a7 4581) goto out;
b8dac44d10 4721) todo_list_release(&new_todo);
009173ed7b 4726) todo_list_release(&new_todo);
009173ed7b 4727) return error_errno(_("could not write '%s'"), todo_file);
9787d17d40 4921) int rearrange_squash_in_todo_file(void)
9787d17d40 4923) const char *todo_file = rebase_path_todo();
9787d17d40 4924) struct todo_list todo_list = TODO_LIST_INIT;
9787d17d40 4925) int res = 0;
9787d17d40 4927) if (strbuf_read_file_or_whine(&todo_list.buf, 
todo_file) < 0)
9787d17d40 4928) return -1;
9787d17d40 4929) if (todo_list_parse_insn_buffer(todo_list.buf.buf, 
&todo_list) < 0) {
9787d17d40 4930) todo_list_release(&todo_list);
9787d17d40 4931) return -1;
9787d17d40 4934) res = todo_list_rearrange_squash(&todo_list);
9787d17d40 4935) if (!res)
9787d17d40 4936) res = rewrite_file(todo_file, todo_list.buf.buf, 
todo_list.buf.len);
9787d17d40 4938) todo_list_release(&todo_list);

setup.c
58b284a2e9  413) return config_error_nonbool(var);

sha1-array.c
7fdf90d541 91) oidcpy(&oids[dst], &oids[src]);

submodule-config.c
bcbc780d14 740) return CONFIG_INVALID_KEY;
45f5ef3d77 755) warning(_("Could not update .gitmodules entry %s"), key);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
060675d4fc 1378) strbuf_release(&gitdir);
183be9660a 1501) struct get_next_submodule_task *task = task_cb;
183be9660a 1505) get_next_submodule_task_release(task);
183be9660a 1532) return 0;
183be9660a 1536) goto out;
183be9660a 1551) return 0;

tree.c
a5dda2204a 108) if (repo_parse_commit(the_repository, commit))

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Alban Gruin      009173ed7: sequencer: change complete_action() to use 
the refactored functions
Alban Gruin      06d813612: sequencer: fix a call to error() in 
transform_todo_file()
Alban Gruin      6424061be: rebase-interactive: rewrite edit_todo_list() 
to handle the initial edit
Alban Gruin      7ccfac40b: rebase--interactive: move 
transform_todo_file() to rebase--interactive.c
Alban Gruin      9787d17d4: sequencer: refactor rearrange_squash() to 
work on a todo_list
Alban Gruin      b5d606240: sequencer: refactor 
sequencer_add_exec_commands() to work on a todo_list
Alban Gruin      b74a37a5a: sequencer: refactor check_todo_list() to 
work on a todo_list
Alban Gruin      b8dac44d1: sequencer: refactor skip_unnecessary_picks() 
to work on a todo_list
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Antonio Ospite      c22b82014: submodule: support reading .gitmodules 
when it's not in the working tree
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      dc7d66433: packfile: close multi-pack-index in 
close_all_packs
Elijah Newren      387361a6a: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      4cdc48e41: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      b58ae691c: merge-recursive: fix rename/add conflict 
handling
Junio C Hamano      a5dda2204: treewide: apply cocci patch
Liam Beguin      0cce4a275: rebase -i -x: add exec commands via the 
rebase--helper
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      b29759d89: fsck: check HEAD and reflog from 
other worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Stefan Beller      060675d4f: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      183be9660: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      7fdf90d54: sha1-array: provide oid_array_filter
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup


Uncovered in jch not in next
----------------------------

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/fetch.c
c806111692 builtin/fetch.c  373) continue; /* can this happen??? */

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

revision.c
a63d88e595 2932) return;
a63d88e595 2935) return;
a63d88e595 2941) c->object.flags |= UNINTERESTING;
a63d88e595 2944) return;
a63d88e595 2947) mark_parents_uninteresting(c);
a63d88e595 2970) return;
a63d88e595 2973) return;
a63d88e595 2978) return;
a63d88e595 3042) continue;
f33f8de6af 3090) if (!revs->ignore_missing_links)
f33f8de6af 3091) die("Failed to traverse parents of commit %s",
a63d88e595 3092) oid_to_hex(&commit->object.oid));
a63d88e595 3100) continue;

sequencer.c
08b6ba5cc0  683) np = strchrnul(buf, '\n');
08b6ba5cc0  684) return error(_("unable to parse '%.*s'"),
08b6ba5cc0  695) return error(_("unable to dequote value of '%s'"),
08b6ba5cc0  737) goto finish;
08b6ba5cc0  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
08b6ba5cc0  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
08b6ba5cc0  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
08b6ba5cc0  756) err = error(_("unknown variable '%s'"),
08b6ba5cc0  761) error(_("missing 'GIT_AUTHOR_NAME'"));
08b6ba5cc0  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
08b6ba5cc0  765) error(_("missing 'GIT_AUTHOR_DATE'"));

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      a63d88e59: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f33f8de6a: revision.c: begin refactoring 
--topo-order logic
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Junio C Hamano      c80611169: fetch: replace string-list used as a 
look-up table with a hashmap
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Phillip Wood      08b6ba5cc: add read_author_script() to libgit
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed


Uncovered in next not in master
-------------------------------

apply.c
eccb5a5f3d 4071) return get_oid_hex(p->old_oid_prefix, oid);

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
55071ea248   61) strbuf_trim(&out);
55071ea248   62) ret = !strcmp("true", out.buf);
55071ea248   63) strbuf_release(&out);
002ee2fe68  115) die(_("%s requires an interactive rebase"), option);
f95736288a  148) return error_errno(_("could not read '%s'"), path);
f95736288a  162) return -1;
f95736288a  167) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  178) return -1;
f95736288a  179) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  180) return -1;
f95736288a  182) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  186) return -1;
f95736288a  188) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  196) opts->signoff = 1;
73d51ed0a5  197) opts->flags |= REBASE_FORCE;
ead98c111b  204) return -1;
12026a412c  219) return -1;
ba1905a5fe  227) return -1;
ba1905a5fe  235) return -1;
6defce2b02  255) return error(_("Could not read '%s'"), path);
6defce2b02  271) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  275) return res;
bc24382c2b  373) argv_array_pushf(&child.args,
bc24382c2b  375) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  507) struct strbuf dir = STRBUF_INIT;
6defce2b02  509) apply_autostash(opts);
ac7f467fef  510) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  511) remove_dir_recursively(&dir, 0);
ac7f467fef  512) strbuf_release(&dir);
ac7f467fef  513) die("Nothing to do");
ac7f467fef  543) return -1;
ac7f467fef  547) rollback_lock_file(&lock);
ac7f467fef  548) return error(_("could not determine HEAD revision"));
ac7f467fef  565) rollback_lock_file(&lock);
ac7f467fef  566) return error(_("could not read index"));
ac7f467fef  570) error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef  571) rollback_lock_file(&lock);
ac7f467fef  572) free((void *)desc.buffer);
ac7f467fef  573) return -1;
ac7f467fef  586) ret = error(_("could not write index"));
ac7f467fef  590) return ret;
ac7f467fef  606) } else if (old_orig)
ac7f467fef  607) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  635) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  669) return 1;
9a48a615b4  685) return 0;
55071ea248  893) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  896) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  897) die_errno(_("could not exec %s"), path);
0eabf4b95c  915) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  952) usage_with_options(builtin_rebase_usage,
f95736288a  972) die(_("Cannot read HEAD"));
f95736288a  976) die(_("could not read index"));
f95736288a  990) exit(1);
122420c295 1002) die(_("could not discard worktree changes"));
122420c295 1004) exit(1);
5e5d96197c 1015) exit(1);
5e5d96197c 1018) die(_("could not move back to %s"),
5a61494539 1028) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1047) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1048) const char *state_dir_base =
c54dacb50e 1049) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1050) const char *cmd_live_rebase =
c54dacb50e 1052) strbuf_reset(&buf);
c54dacb50e 1053) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1054) die(_("It seems that there is already a %s directory, 
and\n"
53f9e5be94 1078) strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94 1079) options.flags |= REBASE_FORCE;
7998dbe1ec 1091) strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
3c3588c7d3 1123) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1124) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1146) die(_("--strategy requires --merge or --interactive"));
cda614e489 1164) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1173) options.state_dir = apply_dir();
ac7f467fef 1174) break;
ac7f467fef 1251) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1257) die(_("Could not create new root commit"));
e65123a71d 1307) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1315) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1327) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1340) die(_("could not read index"));
6defce2b02 1367) die(_("Cannot autostash"));
6defce2b02 1370) die(_("Unexpected stash response: '%s'"),
6defce2b02 1376) die(_("Could not create directory for '%s'"),
6defce2b02 1382) die(_("could not reset --hard"));
e65123a71d 1426) ret = !!error(_("could not parse '%s'"),
e65123a71d 1428) goto cleanup;
e65123a71d 1437) ret = !!error(_("could not switch to "
1ed9c14ff2 1447)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1448) puts(_("HEAD is up to date."));
9a48a615b4 1457)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1458) puts(_("HEAD is up to date, rebase forced."));

builtin/repack.c
2f0c9e9a9b 239) die("repack: Expecting full hex object ID lines only 
from pack-objects.");
2f0c9e9a9b 411) die("repack: Expecting full hex object ID lines only 
from pack-objects.");

builtin/rev-list.c
7c0fe330d5 builtin/rev-list.c 227) die("unexpected missing %s object '%s'",
7c0fe330d5 builtin/rev-list.c 228)     type_name(obj->type), 
oid_to_hex(&obj->oid));

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

gpg-interface.c
4de9394dcb 155) break;

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

list-objects-filter-options.c
bc5975d24f  55) if (errbuf) {
bc5975d24f  56) strbuf_addstr(
bc5975d24f  60) return 1;
cc0b05a4cc  86) if (errbuf)

list-objects-filter.c
list-objects.c
f447a499db 200) ctx->show_object(obj, base->buf, ctx->show_data);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

ref-filter.c
f0062d3b74 1035) v->s = xstrdup("");
f0062d3b74 1298) free((char *)to_free);
f0062d3b74 1299) return xstrdup("");
f0062d3b74 1336) free((char *)to_free);
f0062d3b74 1337) return xstrdup("");
f0062d3b74 1387) *s = xstrdup("=");
f0062d3b74 1389) *s = xstrdup("<");
f0062d3b74 1514) ref->symref = xstrdup("");
f0062d3b74 1583) v->s = xstrdup("");

sequencer.c
65850686cf 2278) return;
65850686cf 2375) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3373) return error(_("could not checkout %s"), commit);
4df66c40b0 3387) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3407) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4771) return -1;
b97e187364 4774) return -1;
b97e187364 4780) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4783) todo_list_release(&todo_list);
b97e187364 4784) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4803) todo_list_release(&todo_list);
b97e187364 4804) return -1;
b97e187364 4808) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4812) return error(_("could not transform the todo list"));
b97e187364 4841) return error(_("could not transform the todo list"));
b97e187364 4844) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4850) return -1;

strbuf.c
f95736288a  127) --sb->len;

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

Commits introducing uncovered code:
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
brian m. carlson      2f0c9e9a9: builtin/repack: replace hard-coded 
constants
brian m. carlson      eccb5a5f3: apply: rename new_sha1_prefix and 
old_sha1_prefix
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Matthew DeVore      7c0fe330d: rev-list: handle missing tree objects 
properly
Matthew DeVore      bc5975d24: list-objects-filter: implement filter tree:0
Matthew DeVore      cc0b05a4c: list-objects-filter-options: do not 
over-strbuf_init
Matthew DeVore      f447a499d: list-objects: store common func args in 
struct
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Olga Telezhnaya      f0062d3b7: ref-filter: free item->value and 
item->value->s
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      53f9e5be9: builtin rebase: support `ignore-date` option
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      7998dbe1e: builtin rebase: support `-C` and 
`--whitespace=<type>`
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue


Uncovered in mater not in master@{1}
------------------------------------

builtin/help.c
e6e76baaf4 builtin/help.c 429) if (!exclude_guides || alias[0] == '!') {
e6e76baaf4 builtin/help.c 430) printf_ln(_("'%s' is aliased to '%s'"), 
cmd, alias);
e6e76baaf4 builtin/help.c 431) free(alias);
e6e76baaf4 builtin/help.c 432) exit(0);
e6e76baaf4 builtin/help.c 441) fprintf_ln(stderr, _("'%s' is aliased to 
'%s'"), cmd, alias);
e6e76baaf4 builtin/help.c 442) count = split_cmdline(alias, &argv);
e6e76baaf4 builtin/help.c 443) if (count < 0)
e6e76baaf4 builtin/help.c 444) die(_("bad alias.%s string: %s"), cmd,
e6e76baaf4 builtin/help.c 446) free(argv);
e6e76baaf4 builtin/help.c 448) return alias;

git.c
a9a60b94cc 322) fprintf_ln(stderr, _("'%s' is aliased to '%s'"),

ident.c
501afcb8b0 172) strbuf_addstr(&git_default_email, email);
501afcb8b0 173) free((char *)email);

packfile.c
1127a98cce  117) return error("index file %s is too small", path);
1127a98cce  119) return error("empty data");

split-index.c
e3d837989e 335) ce->ce_flags |= CE_UPDATE_IN_BASE;

Commits introducing uncovered code:
Johannes Schindelin      501afcb8b: mingw: use domain information for 
default email
Josh Steadmon      1127a98cc: fuzz: add fuzz testing for packfile indices.
Rasmus Villemoes      a9a60b94c: git.c: handle_alias: prepend alias info 
when first argument is -h
Rasmus Villemoes      e6e76baaf: help: redirect to aliased commands for 
"git cmd --help"
SZEDER Gábor      e3d837989: split-index: don't compare cached data of 
entries already marked for split index


^ permalink raw reply	[relevance 4%]

Results 1-200 of ~6000   | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2018-03-17  3:57     Confusing behavior with ignored submodules and `git commit -a` Michael Forney
2018-10-25 18:03     ` Michael Forney
2018-10-25 18:26       ` Stefan Beller
2018-11-15  5:12  7%     ` Michael Forney
2018-11-15  6:05  5%       ` Michael Forney
2018-11-15 20:03  4%         ` Stefan Beller
2018-11-15 21:33  9%           ` Michael Forney
2018-11-15 22:23  7%             ` Stefan Beller
2018-11-16  0:31  6%               ` Michael Forney
2018-11-27  0:03  4%                 ` Stefan Beller
2018-11-15 19:39  7%       ` Stefan Beller
2018-08-07 23:06     [RFC] submodule: munge paths to submodule git directories Brandon Williams
2019-01-15  1:25     ` Jonathan Nieder
2019-01-17 17:32       ` Jeff King
2019-01-17 17:57  7%     ` Stefan Beller
2018-09-27 22:16     [PATCH] FYI / RFC: submodules: introduce repo-like workflow Stefan Beller
2019-01-14 22:34 19% ` Jonathan Nieder
2018-10-16 23:35     [PATCH 00/19] Bring more repository handles into our code base Stefan Beller
2018-10-16 23:35     ` [PATCH 18/19] submodule: use submodule repos for object lookup Stefan Beller
2018-10-31 13:38  5%   ` Derrick Stolee
2018-11-01 19:13  5%     ` Stefan Beller
2018-10-25 23:32     [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
2018-10-29  3:44  4% ` Junio C Hamano
2018-10-25 23:32     [PATCH 09/10] fetch: try fetching submodules if needed objects were not fetched Stefan Beller
2018-10-26 20:41     ` Jonathan Tan
2018-11-29  0:30  4%   ` Stefan Beller
2018-10-27 13:27  4% Git Test Coverage Report (Saturday, Oct 27) Derrick Stolee
2018-10-30 13:37  3% Git Test Coverage Report (Tuesday, Oct 30) Derrick Stolee
2018-10-30 22:07  7% [PATCHv2 00/24] Bring more repository handles into our code base] Stefan Beller
2018-10-30 22:08 20% ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
2018-11-02 13:03  8%   ` Derrick Stolee
2018-11-02 17:23  5%     ` Stefan Beller
2018-11-02 17:27  5%       ` Derrick Stolee
2018-10-30 22:08 14% ` [PATCH 20/24] submodule: don't add submodule as odb for push Stefan Beller
2018-10-31  6:41  2% ` [PATCHv2 00/24] Bring more repository handles into our code base] Junio C Hamano
2018-11-01 16:15  3% Git Test Coverage Report (Thursday, Nov 1) Part A Derrick Stolee
2018-11-02 16:09     submodule support in git-bundle Duy Nguyen
2018-11-02 17:08  7% ` Stefan Beller
2018-11-02 18:34  7%   ` Duy Nguyen
2018-11-02 19:00  7%     ` Stefan Beller
2018-11-03  2:16  3% Git Test Coverage Report (Friday, Nov 2) Derrick Stolee
2018-11-06 19:54     [PATCH] gitk: don't highlight submodule diff lines outside submodule diffs Роман Донченко
2018-11-06 20:06  5% ` Stefan Beller
2018-11-06 21:56  7%   ` Роман Донченко
2018-11-07 14:37  4% Git Test Coverage Report (Wednesday, Nov 7) Derrick Stolee
2018-11-12 14:46     [PATCH 0/9] caching loose objects Jeff King
2018-11-12 14:47     ` [PATCH 2/9] submodule--helper: prefer strip_suffix() to ends_with() Jeff King
2018-11-12 18:23  7%   ` Stefan Beller
2018-11-13 18:05  3% Git Test Coverage Report (Tuesday, Nov 13) Derrick Stolee
2018-11-14  0:12  7% [PATCHv3 00/23] Bring more repository handles into our code base Stefan Beller
2018-11-14  0:13 20% ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
2018-11-15 19:54       ` Jonathan Tan
2018-11-15 20:36  7%     ` Stefan Beller
2018-12-12 20:22 24%       ` Stefan Beller
2018-12-12 20:58 23%         ` [PATCH] submodule: correct documentation for open_submodule Stefan Beller
2018-11-14  0:13 14% ` [PATCH 19/23] submodule: don't add submodule as odb for push Stefan Beller
2018-11-18 14:20  2% [ANNOUNCE] Git v2.20.0-rc0 Junio C Hamano
2018-11-18 16:38     [PATCH] grep: use grep_opt->repo instead of explict repo argument Nguyễn Thái Ngọc Duy
2018-11-26 19:52  7% ` Stefan Beller
2018-11-18 20:01  2% Git Test Coverage Report (Sunday, Nov 18th) Derrick Stolee
2018-11-19  2:54  3% Git Test Coverage Report (v2.20.0-rc0) Derrick Stolee
2018-11-20 17:45     [RFC] Introduce two new commands, switch-branch and restore-paths Duy Nguyen
2018-11-27 16:52     ` [PATCH/RFC v2 0/7] Introduce new commands switch-branch and checkout-files Nguyễn Thái Ngọc Duy
2018-11-27 16:52       ` [PATCH v2 6/7] checkout: split into " Nguyễn Thái Ngọc Duy
2018-11-28  6:03         ` Junio C Hamano
2018-11-28 15:30           ` Duy Nguyen
2018-11-28 23:22             ` Stefan Xenos
2018-11-29 15:46               ` Duy Nguyen
2018-11-29 18:14  5%             ` Stefan Beller
2018-11-29 18:30  4%               ` Duy Nguyen
2018-11-21  9:00     What's cooking in git.git (Nov 2018, #06; Wed, 21) Junio C Hamano
2018-11-26 21:57  2% ` Stefan Beller
2018-11-26 23:34  2%   ` Junio C Hamano
2018-11-21 14:46  2% Git Test Coverage Report (Wednesday Nov 21) Derrick Stolee
2018-11-21 15:19  2% [ANNOUNCE] Git v2.19.2 Junio C Hamano
2018-11-21 15:20  2% [ANNOUNCE] Git v2.20.0-rc1 Junio C Hamano
2018-11-29  0:27 10% [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
2018-11-29  0:27 24% ` [PATCH 2/9] submodule.c: fix indentation Stefan Beller
2018-11-29  0:27 16% ` [PATCH 3/9] submodule.c: sort changed_submodule_names before searching it Stefan Beller
2018-11-29  0:27 16% ` [PATCH 4/9] submodule.c: tighten scope of changed_submodule_names struct Stefan Beller
2018-11-29  0:27 16% ` [PATCH 5/9] submodule: store OIDs in changed_submodule_names Stefan Beller
2018-11-29  0:27 25% ` [PATCH 6/9] repository: repo_submodule_init to take a submodule struct Stefan Beller
2018-11-29  0:27 23% ` [PATCH 7/9] submodule: migrate get_next_submodule to use repository structs Stefan Beller
2019-02-02  1:58  4%   ` Jonathan Nieder
2018-11-29  0:27 17% ` [PATCH 8/9] submodule.c: fetch in submodules git directory instead of in worktree Stefan Beller
2018-11-29  0:27 22% ` [PATCH 9/9] fetch: try fetching submodules if needed objects were not fetched Stefan Beller
2018-12-05  3:10  7% ` [PATCHv2 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Junio C Hamano
2018-12-06 21:59  4%   ` Stefan Beller
2018-12-07  0:25  6% ` Josh Steadmon
2018-11-30 18:03  3% Git Test Coverage Report (Friday Nov 30) Derrick Stolee
2018-12-01 14:58  2% [ANNOUNCE] Git v2.20.0-rc2 Junio C Hamano
2018-12-03 20:45  0% ` Johannes Schindelin
2018-12-05  1:07     [PATCH 9/9] fetch: try fetching submodules if needed objects were not fetched Jonathan Tan
2018-12-06 21:26 21% ` [PATCH] fetch: ensure submodule objects fetched Stefan Beller
2018-12-09  1:57  4%   ` Junio C Hamano
2018-12-05 20:13     git, monorepos, and access control Coiner, John
2018-12-05 21:01     ` Jeff King
2018-12-06 20:08       ` Johannes Schindelin
2018-12-06 22:15  5%     ` Stefan Beller
2018-12-06 17:35     [wishlist] git submodule update --reset-hard Yaroslav Halchenko
2018-12-06 18:29  7% ` Stefan Beller
2018-12-06 21:24  6%   ` Yaroslav Halchenko
2018-12-06 21:55  7%     ` Stefan Beller
2018-12-07  1:22  7%       ` Yaroslav Halchenko
2018-12-07 21:55  7%         ` Stefan Beller
2018-12-08  2:15  4%           ` Yaroslav Halchenko
2018-12-08  4:21 29%             ` Yaroslav Halchenko
2018-12-10 18:58  6%               ` Stefan Beller
2018-12-11  4:08                     ` [PATCH 1/2] submodule: Add --reset-hard option for git submodule update Yaroslav Halchenko
2018-12-11  4:08                       ` [PATCH 2/2] RF+ENH(TST): compare the entire list of submodule status --recursive to stay intact Yaroslav Halchenko
2018-12-12 19:48  7%                     ` Stefan Beller
2018-12-13 16:42  6%                       ` Yaroslav O Halchenko
2018-12-13 20:44  7%                         ` Stefan Beller
2018-12-13 22:43  6%                           ` Yaroslav O Halchenko
2018-12-13 23:58  7%                             ` Stefan Beller
2018-12-14  4:22  7%                               ` Yaroslav O Halchenko
2018-12-07 23:54  8% [PATCH 0/4] Stefan Beller
2018-12-07 23:54 25% ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
2018-12-09  0:11  4%   ` Junio C Hamano
2018-12-07 23:54 20% ` [PATCH 2/4] submodule: unset core.worktree if no working tree is present Stefan Beller
2018-12-08  6:44  7%   ` Junio C Hamano
2018-12-07 23:54 18% ` [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree Stefan Beller
2018-12-08  6:55  4%   ` Junio C Hamano
2018-12-12 22:46  4%     ` Stefan Beller
2018-12-13  3:14  4%       ` Junio C Hamano
2018-12-07 23:54 24% ` [PATCH 4/4] submodule deinit: unset core.worktree Stefan Beller
2018-12-08  7:03  7%   ` Junio C Hamano
2018-12-08  5:57  2% ` [PATCH 0/4] Junio C Hamano
2018-12-12 22:35  4%   ` Stefan Beller
2018-12-14 23:59  9%   ` [PATCH 0/4] submodules: unset core.worktree when no working tree present Stefan Beller
2018-12-14 23:59 25%     ` [PATCH 1/4] submodule update: add regression test with old style setups Stefan Beller
2018-12-26 18:21  4%       ` Junio C Hamano
2018-12-14 23:59 18%     ` [PATCH 2/4] submodule: unset core.worktree if no working tree is present Stefan Beller
2018-12-26 18:27  4%       ` Junio C Hamano
2018-12-14 23:59 19%     ` [PATCH 3/4] submodule--helper: fix BUG message in ensure_core_worktree Stefan Beller
2018-12-14 23:59 23%     ` [PATCH 4/4] submodule deinit: unset core.worktree Stefan Beller
2018-12-08 15:45     [wishlist] submodule.update config Yaroslav Halchenko
2018-12-10 20:40  8% ` Stefan Beller
2018-12-10 22:49  7%   ` Yaroslav Halchenko
2018-12-11  0:08 23%     ` [PATCH] " Stefan Beller
2018-12-11  5:10  7%       ` Yaroslav O Halchenko
2018-12-12 19:31  7%         ` Stefan Beller
2018-12-13 16:50  7%           ` Yaroslav Halchenko
2018-12-09  8:42     What's cooking in git.git (Dec 2018, #01; Sun, 9) Junio C Hamano
2018-12-11  2:00  2% ` Stefan Beller
2018-12-09  8:43  2% [ANNOUNCE] Git v2.20.0 Junio C Hamano
2018-12-09 18:04  2% Git Test Coverage Report (Sunday, Dec 9) Derrick Stolee
2018-12-13  9:15     2.20.0 - Undocumented change in submodule update wrt # parallel jobs Sjon Hortensius
2018-12-13 14:17     ` Junio C Hamano
2018-12-13 18:50  8%   ` Stefan Beller
2018-12-13 19:02 19%     ` [PATCH] submodule update: run at most one fetch job unless otherwise set Stefan Beller
2018-12-13 19:04  4%       ` Eric Sunshine
2018-12-14  2:53  7%       ` Junio C Hamano
2018-12-13 17:19     [wishlist] support of cloning recursively from non-bare submodule hierarchies? Yaroslav Halchenko
2018-12-13 21:59  7% ` Stefan Beller
2018-12-15  0:09  7% [PATCH 00/23] sb/more-repo-in-api Stefan Beller
2018-12-15  0:09 20% ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
2018-12-15  0:09 14% ` [PATCH 19/23] submodule: don't add submodule as odb for push Stefan Beller
2018-12-26 18:42  2% ` [PATCH 00/23] sb/more-repo-in-api Junio C Hamano
2018-12-29 22:31  2% Git Test Coverage Report (Saturday, Dec 29) Derrick Stolee
2019-01-02 22:14     Submodule log bug David Turner
2019-01-09 23:13 12% ` Stefan Beller
2019-01-05  5:51     [PATCH 00/10] Remove the_index, the final part Nguyễn Thái Ngọc Duy
2019-01-12  2:13     ` [PATCH v2 00/11] " Nguyễn Thái Ngọc Duy
2019-01-12  2:13 10%   ` [PATCH v2 01/11] grep: use grep_opt->repo instead of explict repo argument Nguyễn Thái Ngọc Duy
2019-01-07 23:34     What's cooking in git.git (Jan 2019, #01; Mon, 7) Junio C Hamano
2019-01-10 18:02  2% ` Stefan Beller
2019-01-08 17:50  3% Git Test Coverage Report (Tues, Jan 8) Derrick Stolee
2019-01-08 22:16     Regression: submodule worktrees can clobber core.worktree config Tomasz Śniatowski
2019-01-09 17:42  7% ` Stefan Beller
2019-01-09 23:57  7%   ` Tomasz Śniatowski
2019-01-10 20:07  7%     ` Stefan Beller
2019-01-11  0:07  7%       ` Duy Nguyen
     [not found]     <20181229034342.11543-1-e@80x24.org>
2018-12-29  3:56     ` "IMAP IDLE"-like long-polling "git fetch" Eric Wong
2018-12-29  4:38       ` Konstantin Ryabitsev
2019-01-09 22:27  4%     ` Stefan Beller
2019-01-16 10:31     [RFC/PATCH 00/10] Support using submodules with worktrees Nguyễn Thái Ngọc Duy
2019-01-16 10:31     ` [PATCH 01/10] doc: about submodule support with multiple worktrees Nguyễn Thái Ngọc Duy
2019-01-16 22:06  7%   ` Stefan Beller
2019-01-17 10:22  4%     ` Duy Nguyen
2019-01-16 10:31     ` [PATCH 03/10] submodule add: support " Nguyễn Thái Ngọc Duy
2019-01-16 22:27  7%   ` Stefan Beller
2019-01-16 18:22  2% Git Test Coverage Report (Wed Jan 16) Derrick Stolee
2019-01-18 21:55 22% [PATCH] git-submodule: abort if core.worktree could not be set correctly Stefan Beller
2019-01-18 23:18  4% ` Junio C Hamano
2019-01-18 23:30  4%   ` Stefan Beller
2019-01-20  1:07  1% Git Test Coverage Report (Sat Jan 19) Derrick Stolee
2019-01-24 18:15     ` Junio C Hamano
2019-01-24 19:18       ` Derrick Stolee
2019-01-24 19:39         ` Ramsay Jones
2019-01-24 20:56  1%       ` Derrick Stolee
2019-01-24  8:29     [PATCH 00/11] nd/the-index-final small update Nguyễn Thái Ngọc Duy
2019-01-24  8:29 10% ` [PATCH 01/11] grep: use grep_opt->repo instead of explict repo argument Nguyễn Thái Ngọc Duy
2019-01-29 17:46  1% Git Test Coverage Report (Tue. January 29, 2019) Derrick Stolee
2019-02-06 14:41  1% Git Test Coverage Report (Wednesday, Feb. 6) Derrick Stolee
2019-02-07  7:28  3% [ANNOUNCE] Git v2.21.0-rc0 Junio C Hamano
2019-02-07 19:47  0% ` Johannes Schindelin
2019-02-14  3:32  3% [ANNOUNCE] Git v2.21.0-rc1 Junio C Hamano
2019-02-18 15:45  0% ` Johannes Schindelin
2019-02-19 23:29  3% [ANNOUNCE] Git v2.21.0-rc2 Junio C Hamano
2019-02-21 10:46  0% ` Git for Windows v2.21.0-rc2, was " Johannes Schindelin
2019-02-24 18:17  3% [ANNOUNCE] Git v2.21.0 Junio C Hamano
2019-02-24 22:32  0% ` Git for Windows v2.21.0 due Tuesday, was " Johannes Schindelin
2019-05-24  9:14  6% Performance regression on git fetch in 2.21 Orgad Shaneh
2019-06-10 13:55  0% ` Orgad Shaneh
2019-10-23  7:22     Issue: "Could not access submodule" error when pulling recursively with Git 2.22.0 Aleksey Mikhaylov
2019-10-23 10:04  8% ` SZEDER Gábor
2019-10-25 12:41  9%   ` Johannes Schindelin
2020-01-17 12:23 14% [PATCH 0/4] checkout/reset/read-tree: fix --recurse-submodules in linked worktree Philippe Blain via GitGitGadget
2020-01-21 15:01  5% ` [PATCH v2 " Philippe Blain via GitGitGadget
2020-01-22 12:55  2%   ` Philippe Blain
2020-01-22 22:10  4%   ` Junio C Hamano
2020-01-22 22:25  2%     ` Philippe Blain
2020-01-24 23:00  2%       ` Philippe Blain
2020-01-24 23:47  2%         ` Junio C Hamano
2020-01-29 17:12     [GSoC] Exploring Previous year Projects Shourya Shukla
2020-01-29 19:15     ` Jakub Narebski
2020-01-30 11:10  5%   ` Converting scripted commands to built-ins, was " Johannes Schindelin
2020-01-30 15:14  2%     ` Derrick Stolee
2020-01-31  9:32  2%       ` Johannes Schindelin
2020-01-31  9:57  0%         ` Johannes Schindelin
2020-02-25 19:45  4% [GSoC][RFC] Proposal: Convert scripts to builtins Shourya Shukla
2020-03-02 13:32  0% ` Christian Couder
2020-03-09 13:10  5% [GSoC][RFC][Proposal v2] Convert submodule to builtin Shourya Shukla
2020-03-11 21:27  3% ` Christian Couder
2020-03-18 19:10  4% [GSoC][RFC][Proposal v3] " Shourya Shukla
2020-03-24  8:21  4% ` Christian Couder
2020-03-23 17:15  4% [GSoC][RFC][Proposal v4] " Shourya Shukla
2020-03-24  9:08  2% ` Christian Couder
2020-03-25 18:50  4% [GSoC][RFC][Proposal v5] " Shourya Shukla
2020-07-02 19:24  5% [GSoC][PATCH 0/4] submodule: port 'summary' from Shell to C Shourya Shukla
2020-07-02 19:24 15% ` [PATCH 4/4] submodule: port submodule subcommand 'summary' from shell " Shourya Shukla
2020-07-03 20:46  4%   ` Johannes Schindelin
2020-07-05 17:34  2%     ` Shourya Shukla
2020-07-06  9:16  4%       ` Kaartic Sivaraam
2020-07-06 11:15  2%         ` Shourya Shukla
2020-08-06 16:40  4% [GSoC][PATCH v2 0/5] submodule: port " Shourya Shukla
2020-08-06 16:41 18% ` [PATCH v2 5/5] submodule: port submodule " Shourya Shukla
2020-08-12 19:44     ` [GSoC][PATCH v3 0/4] submodule: port " Shourya Shukla
2020-08-12 19:44 18%   ` [PATCH v3 4/4] submodule: port submodule " Shourya Shukla
2020-08-24  9:03 18% [GSoC][PATCH] submodule: port submodule subcommand 'add' " Shourya Shukla
2020-09-19  9:03     How to checkout a revision that contains a deleted submodule? Luke Diamand
2020-09-20  9:44     ` Luke Diamand
2020-09-21 22:46  7%   ` Philippe Blain
2020-10-06 20:38  2% Git Test Coverage Report (v2.29.0-rc0) Derrick Stolee
2020-10-07  7:45  6% [PATCH v2 0/3] submodule: port subcommand add from shell to C Shourya Shukla
2020-10-07  7:45 18% ` [PATCH v2 2/3] submodule: port submodule subcommand 'add' " Shourya Shukla
2020-10-07 18:37  2%   ` Junio C Hamano
2020-12-14 23:19     [PATCH v3 0/3] submodule: port subcommand add " Shourya Shukla
2020-12-14 23:19 19% ` [PATCH v3 2/3] submodule: port submodule subcommand 'add' " Shourya Shukla
2021-04-01 11:40     [GSoC] Draft Proposal (Convert submodule to builtin) Chinmoy Chakraborty
2021-04-02  5:32     ` Bagas Sanjaya
2021-04-02  6:31       ` Christian Couder
2021-04-03 14:14  5%     ` Chinmoy Chakraborty
2021-04-05 14:44  4%       ` Christian Couder
2021-04-08  9:11  5%         ` Chinmoy Chakraborty
2021-04-10 12:03  4%           ` Christian Couder
2021-04-03 14:08  4% [GSoC][Draft Proposal] Finish converting git submodule to builtin Atharva Raykar
2021-04-08 10:19  5% ` [GSoC][Draft Proposal v2] " Atharva Raykar
2021-04-11 10:17  5%   ` [GSoC][Draft Proposal v3] " Atharva Raykar
2021-05-14 16:00  2%   ` [GSoC][Draft Proposal v2] " Atharva Raykar
2021-04-13 10:26  5% [GSoC] Proposal: Convert Git submodule to built-in Firmin Martin

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).