Engineering - page 5

Introducing Soft U2F, a software U2F authenticator for macOS

Soft U2F - Software U2F authenticator for macOS

In an effort to increase the adoption of FIDO U2F second factor authentication, we’re releasing Soft U2F—a software-based U2F authenticator for macOS.

Soft U2F currently works with Google Chrome and Opera’s built-in U2F implementations, as well as with the U2F extensions for Safari and Firefox.

When a site loaded in a U2F-compatible browser attempts to register or authenticate with the software token, you’ll see a notification asking you to accept or reject the request. You can experiment on Yubico’s U2F demo site:

U2F authentication with Soft U2F

And as of today, you can download the Soft U2F installer and configure it for use with your GitHub account.

Interested in learning more? Head over to our Engineering Blog and read more about the motivations for the project plus the security considerations of hardware vs. software key storage.

Git LFS 2.2.0 released

Git LFS v2.2.0 is now available

Git LFS v2.2.0 is now available with the all new git-lfs-migrate command, making it easier than ever to start using Git LFS in your repository.

For example, if you’ve tried to push a large file to GitHub without LFS, you might have seen the following error:

$ git push origin master
# ...
remote: error: GH001: Large files detected. You may want to try Git Large File Storage -
remote: error: See for more information.
remote: error: File a.psd is 1.2 GB; this exceeds GitHub's file size limit of 100.00 MB
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to ''

You can use the git lfs migrate info command to see which files are causing the push failure:

$ git lfs migrate info
*.psd   1.2 GB   27/27 files(s)  100%

Using the information above, you can determine which files to pluck out of your history and store in LFS:

$ git lfs migrate import --include="*.psd"
migrate: Sorting commits: ..., done
migrate: Rewriting commits: 100% (810/810), done
  master        f18bb746d44e8ea5065fc779bb1acdf3cdae7ed8 -> 35b0fe0a7bf3ae6952ec9584895a7fb6ebcd498b
migrate: Updating refs: ..., done

$ git push origin
Git LFS: (1 of 1 files) 1.2 GB / 1.2 GB
# ...
 * [new branch]      master -> master

You can also configure the ‘import’ command to migrate specific filetypes, branches, and more. For a detailed overview, take a look at the man page.

This was a quick look at the migrate command available today in Git LFS v2.2.0. For more on the full release, check out the release notes.

Git 2.13 has been released

  • May 10, 2017
  • peff peff
  • Engineering

The open source Git project has just released Git 2.13.0, with features and bugfixes from over 65 contributors. Before we dig into the new features, we have a brief security announcement.

For those running their own Git hosting server, Git 2.13 fixes a vulnerability in the git shell program in which an untrusted Git user can potentially run shell commands on a remote host. This only affects you if you’re running a hosting server and have specifically configured git shell. If none of that makes sense to you, you’re probably fine. See this announcement for more details. As neither nor GitHub Enterprise uses git shell, both are unaffected.

Phew. With that out of the way, let’s get on to the fun stuff.

SHA-1 collision detection

Did I say fun? Oops, we’re not there yet.

You may have heard that researchers recently found the first collision in SHA-1, the hash function Git uses to identify objects. Their techniques may eventually be used to conduct collision-based attacks against Git users. Fortunately those same researchers also provided a way to detect content that is trying to exploit this technique to create collisions. In March, began using that implementation to prevent it being used as a potential platform for conducting collision attacks.

Git 2.13 ships with similar changes, and will detect and reject any objects that show signs of being part of a collision attack. The collision-detecting SHA-1 implementation is now the default. The code is included with Git, so there’s no need to install any additional dependencies. Note that this implementation is slower than the alternatives, but in practice this has a negligible effect on the overall time of most Git operations (because Git spends only a small portion of its time computing SHA-1 hashes in the first place).

In other collision detection news, efforts have continued to develop a transition plan and to prepare the code base for handling new hash functions, which will eventually allow the use of stronger hash algorithms in Git.

[collision detection, SHA-1 transition 1, SHA-1 transition 2]

More convenient pathspecs

You’ve probably passed path arguments to Git before, like:

$ git log foo.c
$ git grep my_pattern program.rb

But you may not have known that to Git, the foo.c and program.rb arguments are actually pathspecs, a Git-specific pattern for matching paths. Pathspecs can be literal paths, prefixes, or wildcards:

$ git log Documentation/      # Everything under the Documentation/ directory
$ git log '*.c'               # C files anywhere in the tree

But they also have a powerful extension syntax. Pathspecs starting with :(magic) enable special matching features. The complete list can be found in the pathspec section of git help glossary, but let’s look at a few here.

For instance, you may want to exclude some files from a grep, which you can do with the :(exclude) directive:

$ git grep src
src/foo.c:this is a C file
src/foo.rb:this is a ruby file

$ git grep -- src ':(exclude)*.c'
src/foo.rb:this is a ruby file

There are a few things to note in that example. The first is that we had to put our pathspec after a -- (double-dash) separator. This is necessary because most Git commands actually take a combination of revisions and pathspecs. The full syntax is [<revisions>] -- [<pathspecs>]. If you omit the double-dash, Git will check each argument to see if it’s either a valid object name or a file in the filesystem. But since our exclude pattern is neither, without the double-dash Git would give up and complain (this may change in a future version of Git; wildcards like *.c used to have the same problem, but the rules were recently loosened to resolve them as pathspecs). More information is available via git help cli.

The second thing to note is that typing :(exclude) is a pain, and we have to quote it from the shell. But there’s a solution for that: short form pathspec magic. The short form for exclude is ! (exclamation point). This is easy to remember, since it matches the syntax in other parts of Git, like .gitignore files.

$ git grep -- src ':!*.c'
src/foo.rb:this is a ruby file

That’s shorter than exclude, but we still have to quote, since the exclamation point triggers history expansion in most shells. Git 2.13 adds ^ (caret) as a synonym for the exclamation point, letting you do the same thing without any shell quoting:

$ git grep -- src :^*.c
src/foo.rb:this is a ruby file

Ah, much better. Technically we would need to also quote the *.c wildcard from the shell, but in practice it works out. Unless you have a file that starts with :^ and ends in .c, the shell will realize that the wildcard matches nothing and pass it through to Git verbatim.

But wait, there’s more! Git 2.13 also adds the attr token, which lets you select files based on their gitattributes values. For instance, if you use Git LFS, you may want to get a list of files which have been configured to use it:

$ git ls-files

$ git ls-files ':(attr:filter=lfs)'

You can even define your own attributes in order to group files. Let’s say you frequently want to grep a certain set of files. You can define an attribute, and then select those files using that attribute:

$ echo 'libfoo/ vendored' >>.gitattributes
$ echo 'imported-tool/ vendored' >>.gitattributes
$ git grep -i license -- ':(attr:vendored)'

And if you want to get really fancy, you can combine the attr and exclude tokens:

$ git grep foobar -- ':(exclude,attr:vendored)'

Note that the attr token is not yet supported in all parts of the code. Some commands may report that it cannot be used with them, but this is likely to be expanded in future versions of Git.

[negative pathspecs, attribute pathspecs]

Conditional configuration

Git’s configuration system has several levels of priority: you can specify options at the system level, the user level, the repository level, or for an individual command invocation (using git -c). In general, an option found in a more specific location overrides the same option found in a less specific one. Setting in a repository’s .git/config file will override the user-level version you may have set in ~/.gitconfig.

But what if you need to set an option to one value for a group of repositories, and to another value for a different group? For example, you may use one name and email address when making commits for your day job and another when working on open source. You can set the open source identity in the user-level config in your home directory and then override it in the work repositories. But that’s tedious to keep up to date, and if you ever forget to configure a new work repository, you’ll accidentally make commits with the wrong identity!

Git 2.13 introduces conditional configuration includes. For now, the only supported condition is matching the filesystem path of the repository, but that’s exactly what we need in this case. You can configure two conditional includes in your home directory’s ~/.gitconfig file:

[includeIf "gitdir:~/work/"]
  path = .gitconfig-work
[includeIf "gitdir:~/play/"]
  path = .gitconfig-play

Now you can put whatever options you want into those files:

$ cat ~/.gitconfig-work
name = Serious Q. Programmer
email =

$ cat ~/.gitconfig-play
name = Random J. Hacker
email =

The appropriate config options will be applied automatically whenever you’re in a repository that’s inside your work or play directories.

[conditional includes]

Bits and bobs

  • --decorate=auto is now the default for git log. When output is sent to the user’s terminal, commits that are pointed to directly by a branch or tag will be “decorated” with the name of the branch. [source]

  • git branch’s output routines have been ported to the ref-filter system shared by git for-each-ref and git tag. This means you can now use git branch --format= to get custom output. See git help for-each-ref for the list of substitutions. As a side note, these patches are from Karthik Nayak, Git’s Google Summer of Code student from 2015. Though his GSoC project to introduce ref-filter was completed almost two years ago, he’s continued contributing to the project. Great work! [source]

  • git branch, git tag, and git for-each-ref all learned the --no-contains option to match their existing --contains option. This can let you ask which tags or branches don’t have a particular bug (or bugfix). [source]

  • git stash now accepts pathspecs. You can use this to create a stash of part of your working tree, which is handy when picking apart changes to turn into clean commits. [source]

  • The special branch names @{upstream}, @{u}, and @{push} are now case-insensitive. This is especially convenient as both @ and { require holding down the shift key on most keyboards, making it easy to accidentally type a capital U. Now you can hold that shift key AS LONG AS YOU WANT. [source]

  • More commands have learned to recurse into submodules in the past few versions of Git, including checkout, grep, and ls-files. git status --short also now reports more information about submodules. [source, source, source, source]

  • The last few versions of Git have cleaned up many corner cases around repository discovery and initialization. As a final step in that work, Git 2.13 introduced a new assertion to catch any cases that were missed. After being tested for months in development versions, this shouldn’t trigger. But it’s possible that you may see BUG: setup_git_env called without repository. If you do, please consider making a bug report. [source]

The whole kit and caboodle

That’s just a sampling of the changes in Git 2.13, which contains over 700 commits. Check out the the full release notes for the complete list.

Protect your organization's repositories with new security settings

Organization owners can now limit the ability to delete repositories. The new repository deletion setting is available for all plans hosted by GitHub and will be coming to GitHub Enterprise soon.

The setting is enabled by default, allowing organization members with admin permissions for a repository to delete it. When the feature is disabled, only organization owners will be able to delete the repository.

how to set repository deletion settings

When deleting a repository, you’ll still see Danger Zone warnings. If the repository deletion setting is disabled and you are not an organization admin, you’ll get a message letting you know that only owners can delete the repository.

image 2017-04-12 at 9 40 54 pm

Coming soon in the next GitHub Enterprise release

The next GitHub Enterprise release will include the same organization setting for repository deletion. In addition, there will be an appliance-level override that will limit repository deletion to only site-administrators.

The appliance-level setting is enabled by default. This allows users with admin permissions for a repository to delete it and defers to the organization-level repository deletion setting. If disabled, only site administrators will be able to delete the repository.

how to set GitHub Enterprise appliance-level repository deletion settings

When the appliance-level setting is disabled, users will see a similar message as they would at the organization-level when trying to delete a repository.

Documentation and support

For more information about limiting repository deletion for your organization, see our help documentation on deleting repositories. You can learn more about how repository deletion will work on GitHub Enterprise when the next version is released.

If you have any questions, please get in touch with us. We’d be happy to help!

Integrations moves into pre-release with new features

Last September, we launched the Early Access Program of GitHub Integrations, a new option for extending GitHub. We’ve recently added some new features and moved Integrations into pre-release so you can begin using it within your production workflows. Here’s a summary of the latest features. You can learn more about what’s changed from our Developer Blog.

Enabling users to log in from your Integration

Users can now log in with your Integration using the OAuth protocol, allowing you to identify users and display data to them from the relevant installations. Additionally, an Integration can now make authorized API requests on behalf of a user; for example, to deploy code or create an issue. Learn more about authenticating as a user via an Integration.

Updating an Integration’s permissions

When you create an Integration, you have to specify which permissions it needs; for example, the ability to read issues or create deployments. Now you can update the requested permissions via Settings > Developer settings > Integrations, whenever the needs of your Integration change. Users will be prompted to accept these changes and enable the new permissions on their installation.

Post-installation setup

Finally, you now have the option to configure a Setup URL to which you can redirect users after they install your integration if any additional setup is required on your end.


More information on getting started can be found on our Developer Blog and in our documentation. We’d also love to hear what you think. Talk to us in the new Platform forum.



Discover new ways to build better

Try Marketplace apps free for 14 days

Learn more