-2

I don't use Linux or bash. I have to run this command in Windows on CMD:

git log --no-merges --pretty=format:'- %s -- %cn' --full-history master..`git rev-parse --abbrev-ref HEAD` > ReleaseNotes.txt

This is as far as I've gotten:

git log --no-merges --pretty=format:"- %s -- %cn" --full-history master..`git rev-parse --abbrev-ref HEAD` > ReleaseNotes.txt

But this is giving me an error about an ambiguous argument 'master..`git'.

This command works in bash but I don't use bash. I use Windows CMD.

Jordan
  • 9,642
  • 10
  • 71
  • 141
  • 5
    The command includes a [command substitution](https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html#Command-Substitution); you'll have to replace it with the `CMD` equivalent. – chepner Jun 07 '22 at 17:48
  • 1
    Note that you may wish to switch to using bash or perhaps PowerShell. Both are far more capable than the klunky old CMD.EXE. PowerShell seems to have a lot of annoyances to me and I personally would avoid it, but then again I also avoid Windows to all possible extents. – torek Jun 07 '22 at 20:14

1 Answers1

3

The problem is not the two dots, but rather the backquote command-substitution (and, as you found, the kind of quote mark: CMD.EXE demands double quotes rather than single quotes, here; see What does single-quoting do in Windows batch files?).

The backquoted part (`git rev-parse --abbrev-ref HEAD`) is a bit silly since it can be replaced by just using HEAD directly:

git log --no-merges --pretty=format:"- %s -- %cn" --full-history master..HEAD > ReleaseNotes.txt

as the backquoted bit simply resolves HEAD to a raw hash ID, then abbreviates it to a short hash ID, but git log can take the full hash ID or the name HEAD directly.

There are a few more things we can do here. Let's break this up the edited command into pieces and describe each one:

git log 
--no-merges
--pretty=format:"- %s -- %cn"
--full-history
master..HEAD
> ReleaseNotes.txt
  • The git log command walks some set of commits in the repository, and displays some sub-set of the walked commits. "Walking", in this case, means visiting nodes in a Directed Acyclic Graph.

  • The --no-merges part tells git log that it should not display any merge commits. It will still use them for the graph-walk; it will just omit them from its output. A merge commit is any commit with two or more parent commits.

  • The --pretty=format:... section tells git log how to display a commit, when it goes to display it. The format part tells it that instead of a pre-coooked format like full, fuller, oneline, and the like, we're going to give git log a string that may contain individual formatting directives as well as literal characters to display. Since some of the characters will include blanks, we need the command-line-interpreter not to break up arguments at the blanks, hence the quotes.

    The actual format here is hyphen, space, %s, space, double hyphen, space, and %cn. Each of the non-percent-prefixed sequences is output literally; %s outputs the subject line of the commit log message; and %cn outputs the committer name:

    • The commit log message is whatever the author / committer provided to Git, and its "subject line" is very roughly the first line of the message. See more at Git Commit Messages: 50/72 Formatting.

    • The committer name is the user.name setting from whoever made the commit. This may be different from the author name (%an), though in most cases author and committer are the same person. The split occurs when the committer is applying an emailed commit, or using git cherry-pick on a commit written by someone else, or in other similar cases. (Technically, anyone can override the committer name and/or author name at any point, just as one can set user.name to anything one wishes, so these are more cultural distinctions than technical ones.)

    The git log command generally ensures that the format has a newline added as needed, though there's tformat to make extra doubly sure, and that's what one should generally use here (in case of tools that can't handle a final partial output line). In Git versions since 1.6.3 (all extant Git versions that I know of), instead of --pretty=tformat: we can just write --format=, which is what I would recommend here.

  • The --full-history option disables "History Simplification". History simplification is a process where git log omits parts of the graph from the graph walk. But history simplification is only turned on if we add options that we don't use here, so there's no need to turn it off either. This option can therefore be omitted entirely.

  • master..HEAD is a range syntax. It's literally short for HEAD ^master. The details are in the gitrevisions documentation. HEAD here is a positive reference, i.e., it tells git log which commit(s) should be included in the revision walk, and ^master here is a negative reference, i.e., it tells git log which commit(s) should be excluded in the revision walk. The actual walking is a bit complicated and I'll omit all the details, but note that when using the A..B syntax (which means ^A B aka B ^A), omitting one name from either side of the two dots is equivalent to writing HEAD. So instead of master..HEAD we can just write master... Do make sure to use exactly two dots here, as three dots means something else entirely (again, see the documentation).

  • Last, > ReleaseNotes.txt is an output redirection, which works the same in CMD.EXE as it does in sh, bash, and other Unix-style shells.

Omitting defaults, then, our final short version of the command is:

git log --no-merges --format="- %s -- %cn" master.. > ReleaseNotes.txt
torek
  • 448,244
  • 59
  • 642
  • 775