Showing posts with label Announce. Show all posts
Showing posts with label Announce. Show all posts

Monday, July 27, 2015

Git 2.5

The latest feature release Git v2.5.0 is now available at the usual places. It is comprised of 583 non-merge commits since v2.4.0, contributed by 70 people, 21 of which are new faces.

One interesting change is to git help. We now list commands, grouped by the situation in which you would want to use them. This came from discussion on usability, inspired by one of the talks at GitMerge conference we had in spring.

Among notable new features, some of my favourites are:
  • A new short-hand branch@{push} denotes the remote-tracking branch that tracks the branch at the remote the branch would be pushed to.
  • git send-email learned the alias file format used by the sendmail program.
  • Traditionally, external low-level 3-way merge drivers are expected to produce their results based solely on the contents of the three variants given in temporary files named by %O, %A and %B placeholders on their command line. They are now additionally told about the final path (given by %P).
  • A heuristic we use to catch mistyped paths on the command line git cmd revs pathspec is to make sure that all the non-rev parameters in the later part of the command line are names of the files in the working tree, but that means git grep string -- \*.c must always be disambiguated with --, because nobody sane will create a file whose name literally is asterisk-dot-see.  We loosen the heuristic to declare that with a wildcard string the user likely meant to give us a pathspec. So you can now simply say git grep string \*.c without --.
  • Filter scripts were run with SIGPIPE disabled on the Git side, expecting that they may not read what Git feeds them to filter. We however treated a filter that does not read its input fully before exiting as an error.  We no longer do and ignore EPIPE when writing to feed the filter scripts.

    This changes semantics, but arguably in a good way.  If a filter can produce its output without fully consuming its input using whatever magic, we now let it do so, instead of diagnosing it as a programming error.
  • Whitespace breakages in deleted and context lines can also be painted in the output of git diff and friends with the new --ws-error-highlight option.
  • git merge FETCH_HEAD learned that the previous "git fetch" could be to create an Octopus merge, i.e. recording multiple branches that are not marked as "not-for-merge"; this allows us to lose an old style invocation git merge msg HEAD commits... in the implementation of git pull script; the old style syntax can now be deprecated (but not removed yet).
There are a few "experimental" new features, too. They are still incomplete and/or buggy around the edges and likely to change in the future, but nevertheless interesting.
  • git cat-file --batch learned the --follow-symlinks option that follows an in-tree symbolic link when asked about an object via extended SHA-1 syntax.  For example, HEAD:RelNotes may be a symbolic link that points at Documentation/RelNotes/2.5.0.txt.  With the new option, the command behaves as if HEAD:Documentation/RelNotes/2.5.0.txt was given as input instead.

    This is incomplete in at least a few ways.
    (1) A symbolic link in the index, e.g. :RelNotes, should also be treated the same way, but isn't. (2) Non-batch mode, e.g. git cat-file --follow-symlinks blob HEAD:RelNotes, may also want to behave the same way, but it doesn't.
  • A replacement mechanism for contrib/workdir/git-new-workdir that does not rely on symbolic links and make sharing of objects and refs safer by making the borrowee and borrowers aware of each other has been introduced and accessible via git worktree add. This is accumulating more and more known bugs but may prove useful once they are fixed.

Thursday, June 25, 2015

Git 2.4.5

The latest maintenance release for Git v2.4.x series has been tagged.
  • The setup code used to die when core.bare and core.worktree are set inconsistently, even for commands that do not need working tree.
  • There was a dead code that used to handle git pull --tags and show special-cased error message, which was made irrelevant when the semantics of the option changed back in Git 1.9 days.
  • color.diff.plain was a misnomer; give it color.diff.context as a more logical synonym.
  • The configuration reader/writer uses mmap(2) interface to access the files; when we find a directory, it barfed with "Out of memory?".
  • Recent git prune traverses young unreachable objects to safekeep old objects in the reachability chain from them, which sometimes showed unnecessary error messages that are alarming.
  • git rebase -i fired post-rewrite hook when it shouldn't (namely, when it was told to stop sequencing with exec insn).
It also contains typofixes, documentation updates and trivial code clean-ups.

Enjoy.

Git 2.5-rc0 early preview

An early preview of the upcoming Git 2.5 has been tagged as v2.5.0-rc0. It is comprised of 492 non-merge commits since v2.4.0, contributed by 54 people, 17 of which are new faces.

Among notable new features, some of my favourites are:

  • A new short-hand <branch>@{push} denotes the remote-tracking branch that tracks the branch at the remote the <branch> would be pushed to.
  • A heuristic we use to catch mistyped paths on the command line git cmd revs pathspec is to make sure that all the non-rev parameters in the later part of the command line are names of the files in the working tree, but that means git grep string -- \*.c must always be disambiguated with --, because nobody sane will create a file whose name literally is asterisk-dot-see.  We loosen the heuristic to declare that with a wildcard string the user likely meant to give us a pathspec. So you can now simply say git grep string \*.c without --.
  • Filter scripts were run with SIGPIPE disabled on the Git side, expecting that they may not read what Git feeds them to filter. We however treated a filter that does not read its input fully before exiting as an error.  We no longer do and ignore EPIPE when writing to feed the filter scripts.
    This changes semantics, but arguably in a good way.  If a filter can produce its output without fully consuming its input using whatever magic, we now let it do so, instead of diagnosing it as a programming error.
  • Whitespace breakages in deleted and context lines can also be painted in the output of git diff and friends with the new --ws-error-highlight option.
There are a few "experimental" new features, too. They are still incomplete and/or buggy around the edges and likely to change in the future, but nevertheless interesting.
  • git cat-file --batch learned the --follow-symlinks option that follows an in-tree symbolic link when asked about an object via extended SHA-1 syntax.  For example, HEAD:RelNotes may be a symbolic link that points at Documentation/RelNotes/2.5.0.txt.  With the new option, the command behaves as if HEAD:Documentation/RelNotes/2.5.0.txt was given as input instead.
    This is incomplete in a few ways.
    (1) A symbolic link in the index, e.g. :RelNotes, should also be treated the same way, but isn't. (2) Non-batch mode, e.g. git cat-file --follow-symlinks blob HEAD:RelNotes, may also want to behave the same way, but it doesn't.
  • A replacement mechanism for contrib/workdir/git-new-workdir that does not rely on symbolic links and make sharing of objects and refs safer by making the borrowee and borrowers aware of each other has been introduced and accessible via git checkout --to. This is accumulating more and more known bugs but may prove useful once they are fixed.
A draft release notes is there.

Tuesday, May 26, 2015

Git 2.4.1 and 2.4.2

Today, the v2.4.2 maintenance release was tagged. Compared to v2.4.0 that was released end of April 2015 (i.e. last month), in addition to minor typo-fixes, documentation updates and trivial code clean-ups, today's maintenance release contains the following:
  • The usual git diff, when seeing a file turning into a directory, showed a patchset to remove the file and create all files in the directory, but git diff --no-index simply refused to work.  Also, when asked to compare a file and a directory, imitate POSIX diff and compare the file with the file with the same name in the directory, instead of refusing to run.
  • The default $HOME/.gitconfig file created upon git config --global that edits it had incorrectly spelled user.name and user.email entries in it.
  • git commit --date=now or anything that relies on approxidate lost the daylight-saving-time offset.
  • git cat-file bl $blob failed to barf even though there is no object type that is "bl".
  • Teach the codepaths that read .gitignore and .gitattributes files that these files encoded in UTF-8 may have UTF-8 BOM marker at the beginning; this makes it in line with what we do for configuration files already.
  • Access to objects in repositories that borrow from another one on a slow NFS server unnecessarily got more expensive due to recent code becoming more cautious in a naive way not to lose objects to pruning.
  • We avoid setting core.worktree when the repository location is the .git directory directly at the top level of the working tree, but the code misdetected the case in which the working tree is at the root level of the filesystem (which arguably is a silly thing to do, but still valid).
  • git rev-list --objects $old --not --all to see if everything that is reachable from $old is already connected to the existing refs was very inefficient.
  • hash-object --literally introduced in v2.2 was not prepared to take a really long object type name.
  • git rebase --quiet was not quite quiet when there is nothing to do.
  • The completion for log --decorate= parameter value was incorrect.
  • filter-branch corrupted commit log message that ends with an incomplete line on platforms with some sed implementations that munge such a line.  Work it around by avoiding to use sed.
  • git daemon failed to build from the source under NO_IPV6 configuration (regression in 2.4).
  • git stash pop/apply forgot to make sure that not just the working tree is clean but also the index is clean. The latter is important as a stash application can conflict and the index will be used for conflict resolution.
  • We have prepended $GIT_EXEC_PATH and the path git is installed in (typically /usr/bin) to $PATH when invoking subprograms and hooks for almost eternity, but the original use case the latter tried to support was semi-bogus (i.e. install git as /opt/foo/git and run it without having /opt/foo on $PATH), and more importantly it has become less and less relevant as Git grew more mainstream (i.e. the users would want to have it on their $PATH).  Stop prepending the path in which git is installed to users' $PATH, as that would interfere the command search order people depend on (e.g. they may not like versions of programs that are unrelated to Git in /usr/bin and want to override them by having different ones in /usr/local/bin and have the latter directory earlier in their $PATH).
Git hopefully continues to improve.
Have fun.

Thursday, April 2, 2015

First release candidate for Git 2.4

This release has a few changes in the user-visible output from Porcelain commands. These are not meant to be parsed by scripts, but the users still may want to be aware of the changes.
  • Output from "git log --decorate" (and "%d" format specifier used in the userformat "--format=<string>" parameter "git log" family of commands take) used to list "HEAD" just like other branch names, separated with a comma in between. E.g.

         $ git log --decorate -1 master
         commit bdb0f6788fa5e3cacc4315e9ff318a27b2676ff4 (HEAD, master)
         ...
    This release updates the output slightly when HEAD refers to the tip of a branch whose name is also shown in the output.  The above is shown as:

         $ git log --decorate -1 master
         commit bdb0f6788fa5e3cacc4315e9ff318a27b2676ff4 (HEAD -> master)
         ...

  • The phrasing "git branch" uses to describe a detached HEAD has been updated to match that of "git status". When the HEAD is at the same commit as it was originally detached, they now both show "detached at <commit object name>". When the HEAD has moved since it was originally detached, they now both show "detached from <commit object name>". Earlier "git branch" always used "from", even when the user hasn't moved HEAD since it was detached.
Otherwise, there are only minor fixes and documentation updates everywhere, and unusually low number of new and shiny toys ;-)
  • "git log --invert-grep --grep=WIP" will show only commits that do not have the string "WIP" in their messages.
  • "git push" has been taught a "--atomic" option that makes push to update more than one ref an "all-or-none" affair.
  • Extending the "push to deploy" added in 2.3, the behaviour of "git push" when updating the branch that is checked out can now be tweaked by push-to-checkout hook. The "push to deploy" implementation in 2.3 has a bug that makes it impossible to bootstrap an empty repository (or an unborn branch), but it can be worked around by using this hook.
  • "git send-email" used to accept a mistaken "y" (or "yes") as an answer to "What encoding do you want to use [UTF-8]? " without questioning.  Now it asks for confirmation when the answer looks too short to be a valid encoding name.
  • "git archive" can now be told to set the 'text' attribute in the resulting zip archive.
  • "git -C '' subcmd" used to refuse to work in the current directory, unlike "cd ''" which silently behaves as a no-op.
  • The versionsort.prerelease configuration variable can be used to specify that v1.0-pre1 comes before v1.0.
  • A new "push.followTags" configuration turns the "--follow-tags" option on by default for the "git push" command.
Please give it a good beating so that we can ship a successful v2.4 final at around the end of the month without regressions compared to v2.3 series.

Thanks.

Thursday, February 5, 2015

Git 2.3

The latest feature release of Git version control system, version 2.3, is now available at the usual places.

This one ended up to be a release with lots of small corrections and improvements without big uncomfortably exciting features. It is a lot smaller release than other recent feature releases, consisting of 255 non-merge commits (version 2.0, 2.1 and 2.2 had 475, 698 and 556 commits, respectively) by 61 contributors (among which 19 are new people—welcome!).

The recent security fix that went to 2.2.1 and older maintenance tracks is also contained in this update.

One of my favorite small changes in this release is that the "Conflicts:" section that is prepared in the buffer to write your commit log message during a merge is now commented out, just like all the other hints to help you prepare the log message (e.g. the list of files with changes you might want to mention in the log, and the list of untracked files you might have forgot to "git add"). For the full text of the release notes, please visit the list archive.

Enjoy.

Thursday, December 18, 2014

Git 1.8.5.6, 1.9.5, 2.0.5, 2.1.4 and 2.2.1 and thanking friends in Mercurial land

We have a set of urgent maintenance releases. Please update your Git if you are on Windows or Mac OS X.

Git maintains various meta-information for its repository in files in .git/ directory located at the root of the working tree. The system does not allow a file in that directory (e.g. .git/config) to be committed in the history of the project, or checked out to the working tree from the project. Otherwise, an unsuspecting user can run git pull from an innocuous-looking-but-malicious repository and have the meta-information in her repository overwritten, or executable hooks installed by the owner of that repository she pulled from (i.e. an attacker).

Unfortunately, this protection has been found to be inadequate on certain file systems:
  • You can commit and checkout to .Git/<anything> (or any permutations of cases .[gG][iI][tT], except .git all in lowercase). But this will overwrite the corresponding .git/<anything> on case-insensitive file systems (e.g. Windows and Mac OS X).
  • In addition, because HFS+ file system (Mac OS X) considers certain Unicode codepoints as ignorable; committing e.g. .g\u200cit/config, where U+200C is such an ignorable codepoint, and checking it out on HFS+ would overwrite .git/config because of this.
The issue is shared with other version control systems and has serious impact on affected systems (CVE-2014-9390).

Credit for discovering this issue goes to our friends in the Mercurial land (most notably, the inventor of Hg, Matt Mackall himself). The fixes to this issue for various implementations of Git (including mine, libgit2, JGit), ports using these implementations (including Git for Windows, Visual Studio) and also Mercurial have been coordinated for simultaneous releases. GitHub is running an updated version of their software that rejects trees with these confusing and problematic paths, in order to protect its users who use existing versions of Git (also see their blog post).

A huge thanks to all those who were involved.

New releases of Git for Windows, Git OSx Installer, JGit and libgit2 have been prepared to fix this issue. Microsoft (which uses libgit2 in their Visual Studio products) and Apple (which distributes a port of Git in their Xcode) both have fixes, as well.

For people building from the source, fixed versions of Git have been released as versions v1.8.5.6, v1.9.5, v2.0.5, v2.1.4, and v2.2.1 for various maintenance tracks.

Thanks.

Wednesday, May 28, 2014

Git 2.0

The real "Git 2.0" is finally out.

From the point of view of end users who are totally new to Git, this release will give them the defaults that are vastly improved compared to the older versions, but at the same time, for existing users, this release is designed to be as low-impact as possible, as long as they have been following recent releases along (instead of sticking to age-old releases like 1.7.x series). Some may even say, without remembering why it was a big deal to bring these new default behaviours to help new users, that the new release does not offer anything exciting—and that is exactly what we want to hear from existing users. In recent releases for the past year or so, we have added knobs to allow users to enable these new defaults before 2.0 happens, and added warnings to let users know when they perform an operation whose outcome will be different between 1.x series and 2.0 release. The existing users are hopefully very well prepared by now, and "Git 2.0" is designed to be the final "flipping the default" step.

We had to delay the final release by a week or so because we found a few problems  in earlier release candidates (request-pull had a regression that stopped it from showing the "tags/" prefix in "Please pull tags/frotz" when the user asked to compose a request for 'frotz' to be pulled; a code path in git-gui to support ancient versions of Git incorrectly triggered for Git 2.0), which we had to fix in an extra unplanned release candidate.

Hopefully the next cycle will become shorter, as topics that have been cooking on the 'next' branch had extra time to mature, so it all evens out in the end ;-).

Have fun.

Tuesday, March 18, 2014

Git 1.9.1

Traditionally, releases numbered with three Dewey-decimal digits were major releases that add new features, while ones with four were maintenance releases with only fixes. This was meant to give us some flexibility to say that the difference between 1.7.12 and 1.8.0 are larger than the difference between 1.8.1 and 1.8.2 (1.7.12 was the last major release in the 1.7.x series), while reserving the difference in the first digit for really big changes (i.e. 2.0 may finally toggle a switch that makes Git incompatible with older 1.x releases out of the box).

But we found out that in practice, we do not need to have three levels of changes (an incremental that changes the third digit between 1.8.1 to 1.8.2, a larger update that changes the second digit between 1.7.12 to 1.8.0, and a huge update that changes the first digit between 1.9 and 2.0). Hence the last major release was officially called "Git 1.9" when it was released on February 14, 2014.

It logically follows that, because we are dropping the third digit (or the second, depending on how you look at it) from the numbering of major releases, the first maintenance release for Git 1.9 is named with three digits, not four.

Git 1.9.1 is such a release. Among many changes we have been cooking on the development front towards the next major release, which will be called Git 2.0, this maintenance release contains only the fixes, and everybody is encouraged to upgrade to it.

Fixes since Git 1.9 are as follows:
  • "git clean -d pathspec" did not use the given pathspec correctly and ended up cleaning too much.
  • "git difftool" misbehaved when the repository is bound to the working tree with the ".git file" mechanism, where a textual file ".git" tells us where it is.
  • "git push" did not pay attention to branch.*.pushremote if it is defined earlier than remote.pushdefault; the order of these two variables in the configuration file should not matter, but it did by mistake.
  • Codepaths that parse timestamps in commit objects have been tightened.
  • "git diff --external-diff" incorrectly fed the submodule directory in the working tree to the external diff driver when it knew it is the same as one of the versions being compared.
  • "git reset" needs to refresh the index when working in a working tree (it can also be used to match the index to the HEAD in an otherwise bare repository), but it failed to set up the working tree properly, causing GIT_WORK_TREE to be ignored.
  • "git check-attr" when working on a repository with a working tree did not work well when the working tree was specified via the --work-tree (and obviously with --git-dir) option.
  • "merge-recursive" was broken in 1.7.7 era and stopped working in an empty (temporary) working tree, when there are renames involved.  This has been corrected.
  • "git rev-parse" was loose in rejecting command line arguments that do not make sense, e.g. "--default" without the required value for that option.
  • include.path variable (or any variable that expects a path that can use ~username expansion) in the configuration file is not a boolean, but the code failed to check it.
  • "git diff --quiet -- pathspec1 pathspec2" sometimes did not return correct status value.
  • Attempting to deepen a shallow repository by fetching over smart HTTP transport failed in the protocol exchange, when no-done extension was used.  The fetching side waited for the list of shallow boundary commits after the sending end stopped talking to it.
  • Allow "git cmd path/", when the 'path' is where a submodule is bound to the top-level working tree, to match 'path', despite the extra and unnecessary trailing slash (such a slash is often given by command line completion).
Have fun.

Wednesday, November 27, 2013

Git 1.8.5

The latest release Git 1.8.5 is out. Among many incremental improvements, there are a handful of changes that are worth mentioning:

  • Magic pathspecs like ":(icase)makefile" (matches both Makefile and makefile) and ":(glob)foo/**/bar" (matches "bar" in "foo" and any subdirectory of "foo") can be used in more places.
  • The "http.*" configuration variables can now be specified for individual URLs. E.g

    [http]
     sslVerify = true
    [http "https://weak.example.com/"] sslVerify = false

    would turn on http.sslVerify for everybody, except when talking with the specified URL.
  • "git mv A B" when moving a submodule has been taught to relocate the submodule's working tree and to adjust the paths in the .gitmodules file.
  • "git blame" can now take more than one -L option to discover the origin of multiple blocks of lines.
  • The http transport clients can optionally ask to save cookies with the http.savecookies configuration variable.
  • "git push" learned a more fine grained control over a blunt "--force" when requesting a non-fast-forward update with the "--force-with-lease=<refname>:<expected object name>" option.
  • "git diff --diff-filter=<classes of changes>" can now take lowercase letters (e.g. "--diff-filter=d") to mean "show everything but these classes".  "git diff-files -q" is now a deprecated synonym for "git diff-files --diff-filter=d".
  • "git gc" exits early without doing any work when it detects that another instance of itself is already running.

Friday, November 8, 2013

Git 1.8.4.3

The latest maintenance release Git v1.8.4.3 has been tagged and is available at the usual places (see the list of public repositories). The fixes that have already merged to the 'master' branch for the upcoming Git v1.8.5 feature release are all there.

Here are the highlights, relative to the previous maintenance release v1.8.4.2:

  • The interaction between use of Perl in our test suite and NO_PERL has been clarified a bit.
  • A fast-import stream expresses a pathname with funny characters by quoting them in C style; remote-hg remote helper (in contrib/) forgot to unquote such a path.
  • One long-standing flaw in the pack transfer protocol used by "git clone" was that there was no way to tell the other end which branch "HEAD" points at, and the receiving end needed to guess. A new capability has been defined in the pack protocol to convey this information so that cloning from a repository with more than one branches pointing at the same commit where the HEAD is at now reliably sets the initial branch in the resulting repository.
  • We did not handle cases where http transport gets redirected during the authorization request (e.g. from http:// to https://).
  • "git rev-list --objects ^v1.0^ v1.0" gave v1.0 tag itself in the output, but "git rev-list --objects v1.0^..v1.0" did not.
  • The fall-back parsing of commit objects with broken author or committer lines were less robust than ideal in picking up the timestamps.
  • Bash prompting code to deal with an SVN remote as an upstream were coded in a way not supported by older Bash versions (3.x).
  • "git checkout topic", when there is not yet a local "topic" branch but there is a unique remote-tracking branch for a remote "topic" branch, pretended as if "git checkout -t -b topic remote/$r/topic" (for that unique remote $r) was run. This hack however was not implemented for "git checkout topic --".
  • Coloring around octopus merges in "log --graph" output was screwy.
  • We did not generate HTML version of documentation to "git subtree" in contrib/.
  • The synopsis section of "git unpack-objects" documentation has been clarified a bit.
  • An ancient How-To on serving Git repositories on an HTTP server lacked a warning that it has been mostly superseded with a more modern way.


Wednesday, October 30, 2013

v1.8.5-rc0: An early preview of the upcoming release

There are many little changes everywhere.  All of the fixes that have already went into 1.8.4.2 maintenance release are also in this preview.

Foreign interfaces, subsystems and ports.

  • "git-svn" used with SVN 1.8.0 when talking over https:// connection dumped core due to a bug in the serf library that SVN uses.  Work it around on our side, even though the SVN side is being fixed.
  • On MacOS X, we detected if the filesystem needs the "pre-composed unicode strings" workaround, but did not automatically enable it.  Now we do.
  • remote-hg remote helper misbehaved when interacting with a local Hg repository relative to the home directory, e.g. "clone hg::~/there".
  • imap-send ported to OS X uses Apple's security framework instead of OpenSSL one.
  • Subversion 1.8.0 that was recently released breaks older subversion clients coming over http/https in various ways.
  • "git fast-import" treats an empty path given to "ls" as the root of the tree.

UI, Workflows & Features

  • "git grep" and "git show" pays attention to "--textconv" option when these commands are told to operate on blob objects (e.g. "git grep -e pattern HEAD:Makefile").
  • "git replace" helper no longer allows an object to be replaced with another object of a different type to avoid confusion (you can still manually craft such replacement using "git update-ref", as an escape hatch).
  • "git status" no longer prints dirty status information for submodules for which submodule.$name.ignore is set to "all".
  • "git rebase -i" honours core.abbrev when preparing the insn sheet for editing.
  • "git status" during a cherry-pick shows what original commit is being picked.
  • Instead of typing four capital letters "HEAD", you can say "@" now, e.g. "git log @".
  • "git check-ignore" follows the same rule as "git add" and "git status" in that the ignore/exclude mechanism does not take effect on paths that are already tracked.  With "--no-index" option, it can be used to diagnose which paths that should have been ignored have been mistakenly added to the index.
  • Some irrelevant "advice" messages that are shared with "git status" output have been removed from the commit log template.
  • "update-refs" learnt a "--stdin" option to read multiple update requests and perform them in an all-or-none fashion.
  • Just like "make -C <directory>", "git -C <directory> ..." tells Git to go there before doing anything else.
  • Just like "git checkout -" knows to check out and "git merge -" knows to merge the branch you were previously on, "git cherry-pick" now understands "git cherry-pick -" to pick from the previous branch.
  • "git status" now omits the prefix to make its output a comment in a commit log editor, which is not necessary for human consumption.  Scripts that parse the output of "git status" are advised to use "git status --porcelain" instead, as its format is stable and easier to parse.
  • Make "foo^{tag}" to peel a tag to itself, i.e. no-op., and fail if "foo" is not a tag.  "git rev-parse --verify v1.0^{tag}" would be a more convenient way to say "test $(git cat-file -t v1.0) = tag".
  • "git branch -v -v" (and "git status") did not distinguish among a branch that does not build on any other branch, a branch that is in sync with the branch it builds on, and a branch that is configured to build on some other branch that no longer exists.
  • A packfile that stores the same object more than once is broken and will be rejected by "git index-pack" that is run when receiving data over the wire.
  • Earlier we started rejecting an attempt to add 0{40} object name to the index and to tree objects, but it sometimes is necessary to allow so to be able to use tools like filter-branch to correct such broken tree objects.  "filter-branch" can again be used to to do so.
  • "git config" did not provide a way to set or access numbers larger than a native "int" on the platform; it now provides 64-bit signed integers on all platforms.
  • "git pull --rebase" always chose to do the bog-standard flattening rebase.  You can tell it to run "rebase --preserve-merges" by setting "pull.rebase" configuration to "preserve".
  • "git push --no-thin" actually disables the "thin pack transfer" optimization.
  • Magic pathspecs like ":(icase)makefile" that matches both Makefile and makefile can be used in more places.
  • The "http.*" variables can now be specified per URL that the configuration applies.  For example,

       [http]
           sslVerify = true
       [http "https://weak.example.com/"]
           sslVerify = false

    would flip http.sslVerify off only when talking to that specified site.
  • "git mv A B" when moving a submodule A has been taught to relocate its working tree and to adjust the paths in the .gitmodules file.
  • "git blame" can now take more than one -L option to discover the origin of multiple blocks of the lines.
  • The http transport clients can optionally ask to save cookies with http.savecookies configuration variable.
  • "git push" learned a more fine grained control over a blunt "--force" when requesting a non-fast-forward update with the "--force-with-lease=<refname>:<expected object name>" option.
  • "git diff --diff-filter=<classes of changes>" can now take lowercase letters (e.g. "--diff-filter=d") to mean "show everything but these classes".  "git diff-files -q" is now a deprecated synonym for "git diff-files --diff-filter=d".
  • "git fetch" (hence "git pull" as well) learned to check "fetch.prune" and "remote.*.prune" configuration variables and to behave as if the "--prune" command line option was given.
  • "git check-ignore -z" applied the NUL termination to both its input (with --stdin) and its output, but "git check-attr -z" ignored the option on the output side. Make both honor -z on the input and output side the same way.
  • "git whatchanged" may still be used by old timers, but mention of it in documents meant for new users will only waste readers' time wonderig what the difference is between it and "git log".  Make it less prominent in the general part of the documentation and explain that it is merely a "git log" with different default behaviour in its own document.

Performance, Internal Implementation, etc.


  • The HTTP transport will try to use TCP keepalive when able.
  • "git repack" is now written in C.
  • Build procedure for MSVC has been updated.
  • If a build-time fallback is set to "cat" instead of "less", we should apply the same "no subprocess or pipe" optimization as we apply to user-supplied GIT_PAGER=cat.
  • Many commands use --dashed-option as a operation mode selector (e.g. "git tag --delete") that the user can use at most one (e.g. "git tag --delete --verify" is a nonsense) and you cannot negate (e.g. "git tag --no-delete" is a nonsense).  parse-options API learned a new OPT_CMDMODE macro to make it easier to implement such a set of options.
  • OPT_BOOLEAN() in parse-options API was misdesigned to be "counting up" but many subcommands expect it to behave as "on/off". Update them to use OPT_BOOL() which is a proper boolean.
  • "git gc" exits early without doing a double-work when it detects that another instance of itself is already running.
  • Under memory pressure and/or file descriptor pressure, we used to close pack windows that are not used and also closed filehandle to an open but unused packfiles. These are now controlled separately to better cope with the load.


Friday, August 23, 2013

Git 1.8.4

The 1.8.4 release has finally been tagged and pushed out to the usual places. It contains 870+ changes from ~100 contributors (among which 33 people are new) since v1.8.3.

Due to regressions discovered at the last minute, two topics that have been in the master branch for a while had to be reverted. They are expected to come back after fixing the regressions in future releases.

Here are some highlights:

  • "git log" learnt the "-Lbegin,end:filename" option. This starts from the specified range and digs through the history. It may still have rough edges and memory leaks, though.
  • "git clean" learnt the interactive mode, modeled after "git add -i" interface.
  • "git check-mailmap" is a new command that lets you inquire your .mailmap file for the canonical username and e-mail address.
  • "git name-rev" learnt to name an annotated tag object name back to its tagname.
  • Various subcommands of "git submodule" now work even from a subdirectory.
  • "git submodule update" can optionally clone the submodule repositories shallowly.
  • The "push.default=simple" mode of "git push" has been updated to behave like "current" when you push to a remote that is different from where you fetch from (e.g. via remote.pushdefault), in order to better support the triangular workflow.
  • "git log" learnt the "--author-date-order" option.
  • The configuration variable color.ui defaults to "auto" now.
  • "git describe" learnt the "--first-parent" option.
  • "git fetch $remote $branch" used to avoid touching the remote-tracking branch (you could always be explicit and say "git fetch $remote $branch:refs/remotes/$remote/$branch"). The command now updates the remote-tracking branch (if configured).
  • Use of platform fnmatch(3) function (many places like pathspec matching, .gitignore and .gitattributes) have been replaced with wildmatch, allowing "foo/**/bar" to match "foo/bar", "foo/a/bar", etc.
Have fun.

Thursday, August 1, 2013

Git 1.8.4-rc1

The first release candidate for Git v1.8.4-rc1 is available for testing at the usual places.
For highlights, please refer to the previous post on v1.8.4-rc0.

Have fun.

Wednesday, July 24, 2013

Git 1.8.4-rc0

A release candidate preview Git v1.8.4-rc0 is now available for testing at the usual places.

As this cycle is a rather large update, please test this thoroughly. It contains 814 non-merge commits, from 90+ contributors (v1.8.3 consisted of 694 changes from 97 contributors).

Here are some highlights:

  • "git log" learnt the "-Lbegin,end:filename" option. This starts from the specified range and digs through the history. It may still have rough edges and memory leaks, though.
  • "git clean" learnt the interactive mode, modeled after "git add -i" interface.
  • "git check-mailmap" is a new command that lets you inquire your .mailmap file for the canonical username and e-mail address.
  • "git name-rev" learnt to name an annotated tag object name back to its tagname.
  • Various subcommands of "git submodule" now works even from a subdirectory.
  • "git submodule update" can optionally clone the submodule repositories shallowly.
  • The "push.default=simple" mode of "git push" has been updated to behave like "current" when you push to a remote that is different from where you fetch from (e.g. via remote.pushdefault), in order to better support the triangular workflow.
  • "git log" learnt the "--author-date-order" option.
  • The configuration variable color.ui defaults to "auto" now.
  • Instead of typing "HEAD", you can say "@" instead, e.g. "git log @".
  • "git describe" learnt the "--first-parent" option.
  • "git fetch $remote $branch" used to avoid touching the remote-tracking branch (you could always be explicit and say "git fetch $remote $branch:refs/remotes/$remote/$branch"). The command now updates the remote-tracking branch (if configured).
  • Use of platform fnmatch(3) function (many places like pathspec matching, .gitignore and .gitattributes) have been replaced with wildmatch, allowing "foo/**/bar" to match "foo/bar", "foo/a/bar", etc.
Have fun.

Monday, July 22, 2013

Git 1.8.3.4

The latest maintenance release Git v1.8.3.4 is now available at the usual places. This is mostly to propagate documentation fixes and test updates from the master front back to the maintenance track, but there are a handful of minor fixes as well:

  • The bisect log listed incorrect commits when bisection ends with only skipped ones.
  • The test coverage framework was left broken for some time.
  • The test suite for HTTP transport did not run with Apache 2.4.
  • "git diff" used to fail when core.safecrlf is set and the working tree contents had mixed CRLF/LF line endings. Committing such a content must be prohibited, but "git diff" should help the user to locate and fix such problems without failing.
These fixes are already on the 'master' branch to be included in upcoming Git 1.8.4. Hopefully we can do its zeroth release candidate preview early this week.

Have fun.

Monday, July 15, 2013

Git 1.8.3.3

The third maintenance release for 1.8.3.x series is now available at the usual places. It contains the following fixes that have already been applied to the 'master' branch for 1.8.4.
  • "git apply" parsed patches that add new files, generated by programs other than Git, incorrectly.  This is an old breakage in v1.7.11.
  • Older cURL wanted piece of memory we call it with to be stable, but we updated the auth material after handing it to a call.
  • "git pull" into nothing trashed "local changes" that were in the index.
  • Many "git submodule" operations did not work on a submodule at a path whose name is not in ASCII.
  • "cherry-pick" had a small leak in its error codepath.
  • Logic used by git-send-email to suppress cc mishandled names like "A U. Thor" <author@example.xz>, where the human readable part needs to be quoted (the user input may not have the double quotes around the name, and comparison was done between quoted and unquoted strings).  It also mishandled names that need RFC2047 quoting.
  • "gitweb" forgot to clear a global variable $search_regexp upon each request, mistakenly carrying over the previous search to a new one when used as a persistent CGI.
  • The wildmatch engine did not honor WM_CASEFOLD option correctly.
  •  "git log -c --follow $path" segfaulted upon hitting the commit that renamed the $path being followed.
  • When a reflog notation is used for implicit "current branch", e.g. "git log @{u}", we did not say which branch and worse said "branch ''" in the error messages.
  • Mac OS X does not like to write(2) more than INT_MAX number of bytes; work it around by chopping write(2) into smaller pieces.
  • Newer MacOS X encourages the programs to compile and link with their CommonCrypto, not with OpenSSL.

Friday, June 28, 2013

Git 1.8.3.2

The second maintenance release for 1.8.3.x series is now available at the usual places. It contains the following fixes that have already been applied to the 'master' branch for 1.8.4.

  • Cloning with "git clone --depth N" while fetch.fsckobjects (or transfer.fsckobjects) is set to true did not tell the cut-off points of the shallow history to the process that validates the objects and the history received, causing the validation to fail.
  • "git checkout foo" DWIMs the intended "upstream" and turns it into "git checkout -t -b foo remotes/origin/foo". This codepath has been updated to correctly take existing remote definitions into account.
  • "git fetch" into a shallow repository from a repository that does not know about the shallow boundary commits (e.g. a different fork from the repository the current shallow repository was cloned from) did not work correctly.
  • "git subtree" (in contrib/) had one codepath with loose error checks to lose data at the remote side.
  • "git log --ancestry-path A...B" did not work as expected, as it did not pay attention to the fact that the merge base between A and B was the bottom of the range being specified.
  • "git diff -c -p" was not showing a deleted line from a hunk when another hunk immediately begins where the earlier one ends.
  • "git merge @{-1}~22" was rewritten to "git merge frotz@{1}~22" incorrectly when your previous branch was "frotz" (it should be rewritten to "git merge frotz~22" instead).
  • "git commit --allow-empty-message -m ''" should not start an editor.
  • "git push --[no-]verify" was not documented.
  • An entry for "file://" scheme in the enumeration of URL types Git can take in the HTML documentation was made into a clickable link by mistake.
  • zsh prompt script that borrowed from bash prompt script did not work due to slight differences in array variable notation between these two shells.
  • The bash prompt code (in contrib/) displayed the name of the branch being rebased when "rebase -i/-m/-p" modes are in use, but not the plain vanilla "rebase".
  • "git push $there HEAD:branch" did not resolve HEAD early enough, so it was easy to flip it around while push is still going on and push out a branch that the user did not originally intended when the command was started.
  • "difftool --dir-diff" did not copy back changes made by the end-user in the diff tool backend to the working tree in some cases.


Friday, May 24, 2013

Git 1.8.3 and even more leftover bits

The 1.8.3 release has finally been tagged and pushed out to the usual places. Also the release tarballs at kernel.org are back.

For a list of highlights, please see the previous post on -rc2; not much has changed since then.

During the last development cycle including its pre-release feature freeze, a few more interesting topics were discussed, and at this moment there aren't actual patches or design work.

[Previous list of "leftover bits" is here]
  • "git config", when removing the last variable in a section, leaves an empty section header behind. Anybody who wants to improve this needs to consider ramifications of leaving or removing comments.
    Cf. $gmane/219524
  • [STARTED AND THEN STALLED] Add "git pull --merge" option to explicitly override configured pull.rebase=true. Make "git pull" that does not say how to integrate fail when the result does not fast-forward, and advise the user to say --merge/--rebase explicitly or configure pull.rebase=[true|false]. An unconfigured pull.rebase and pull.rebase that is explicitly set to false would mean different things (the former will trigger the "fast-forward or die" check, the latter does the "pull = fetch + merge".
    Cf. $gmane/225326
  • Teach more commands that operate on branch names about "-" shorthand for "the branch we were previously on", like we did for "git merge -" sometime after we introduced "git checkout -".
    Cf. $gmane/230828
  • Proofread our documentation set, and update to reduce newbie confusion around "remote", "remote-tracking branch", use of the verb "to track", and "upstream".
    Cf. $gmane/230786.

Monday, May 13, 2013

Git 1.8.3-rc2

The second and planned-to-be-the-final release candidate for the upcoming 1.8.3 release was tagged today. Also, the release tarballs at kernel.org are back ;-)

Hopefully we can have the final late next week, but we might end up doing another release candidate. Please help testing the rc2 early to make sure you can have a solid release.

There are numerous little fixes, new features and enhancements that cannot be covered in a single article, so I'll only highlight some selected big-picture changes here. For the full list of changes, please refer to the draft Release Notes.

Preparation for 2.0

A lot of work went into preparing the users for 2.0 release that will come sometime next year, which promises large backward-incompatible UI changes:
  • "git push" that does not say what to push from the command line will not use the "matching" semantics in Git 2.0 (it will use "simple", which pushes your current branch to the branch of the same name only when you have forked from it previously; e.g. "git push origin" done while you are on your "topic" branch that was previously created with "git checkout -t -b topic origin/topic" will push your "topic" branch to origin).

    This default change will hurt old-timers who are used to the traditional "matching" (if you have branches A, B and C, and of the other side has branches A and C, then your branches A and C will update their branches A and C, respectively), and they can use "push.default" configuration variable to keep the traditional behaviour. I.e.

    $ git config push.default matching

    Recent releases since 1.8.0 has been issuing warnings when you do not have any push.default configuration set, and this release continues to do so.

  • "git add -u" and "git add -A" that is run inside a subdirectory without any other argument to specify what to add will operate on the entire working tree in Git 2.0, so that the behaviour will be more consistent with "git commit -a" (e.g. "edit file && cd subdir && git commit -a" will commit the change to the file you just edited which is outside the directory you ran "git commit" in).

    Users can say "git add -u ." and "git add -A ." (the "dot" means "the current directory") to limit the operation to the subdirectory the command is run in with the traditional versions of Git (and this will stay the same in Git 2.0 or later), so there will be no configuration variable to change the default.

    The 1.8.3 and later releases do not yet change the behaviour until Git 2.0, and limit these operations to the current subdirectory, but they do notice when you have changes outside your current subdirectory and warn, saying that if you were to type the same command to Git 2.0, you would be adding those other files to your index, and encourages you to learn to add that explicit "dot" if you mean to add changed or all files in the current subdirectory only.

  • "git add path" has traditionally been a no-op for removed files (e.g. "rm -f dir/file && git add dir" does not record the removal of dir/file to the index), but Git 2.0 will notice and record removals, too.

    The 1.8.3 and later releases do not yet change the behaviour until Git 2.0, but they do notice when you have removed files that match the path and warn, saying that if you were to type the same command to Git 2.0, you would be recording their removal, and encourages you to learn to use the --ignore-removal option if you mean to only add modified or new files to the index.

Tightening of command line verification

There are quite a many UI fixes that tie loose ends. Some commands assumed that the users were perfect and would never throw nonsense command line arguments at them, and some operations that need two parameters were happily carried out even when they got three parameters without diagnosing such a command line as an error (the excess one was simply ignored).

Many of them have been updated to detect and die on such errors.

Helping our friends at Emacs land

We expedited the update of the foreign SCM interface to bzr we have in the contrib/ area since 1.8.2, and included a version that is vastly modified from what we had before, with help from some Emacs folks. This code could be a bit rougher than the rest of Git that usually moves slowly and cautiously, but we decided that, given the circumstance, it is more important to push out some improved version early, in order to help our friends in Emacs land, who have been (reportedly) suffering from less than ideal response to the issues they are having with their SCM of choice.

A beginning of a better triangular workflow support

The recommended workflows to collaborate with others are either:
  • to have your own repository and push your work there while pulling from your upstream to keep up to date, or
  • to have a central repository where everybody pushes to and pulls from.
The latter was primarily to make those who are coming from centralized version control systems feel at ease, and the repository configuration mechanisms such as "remote.origin.url" variable were designed to help that workflow (there is one "origin" you pull from and push to). The former however is also important, and many people on Git hosting sites (e.g. GitHub) employ this workflow (you pull from one place and push to another place, but they are not the same).

A new configuration mechanism "remote.pushdefault" has been introduced to support such a triangular workflow. After you clone from somebody else's project, that upstream repository will still be your 'origin', but you can add the repository you regularly push to in order to publish your work (and presumably then you will throw a "pull request" at the upstream) as another remote, and set it to this configuration variable. E.g.
$ git clone git://example.com/frotz.git frotz
$ cd frotz
$ git remote add publish ssh://myhost.com/myfrotz.git
$ git config remote.pushdefault publish
After this, you can say "git push" and the push does not attempt to push to your origin (i.e. git://example.com/frotz.git)  but to your publish remote (i.e. ssh://myhost.com/myfrotz.git) because of the last configuration.