📜 ⬆️ ⬇️

What's new Git 2.7 offers

Just two months after version 2.6, Git 2.7 was released with new features, fixes and performance improvements. What interesting things did he cook for us? I will talk about several new products that seemed interesting to the Bitbucket team.

Full git worktree command set


The git worktree command appeared in Git 2.5 , it allows you to upload and simultaneously work with many branches of the repository in separate folders. For example, if you need to make an urgent revision, but you do not want to touch the current working copy, you can simply unload the necessary branch into a new folder using the command:
$ git worktree add -b hotfix/BB-1234 ../hotfix/BB-1234 Preparing ../hotfix/BB-1234 (identifier BB-1234) HEAD is now at 886e0ba Merged in bedwards/BB-13430-api-merge-pr (pull request #7822) 


Git 2.7 adds the git worktree list command , which lists the working copies of the repository and the branches associated with them:
 $ git worktree list /Users/kannonboy/src/bitbucket/bitbucket 37732bd [master] /Users/kannonboy/src/bitbucket/staging d5924bc [staging] /Users/kannonboy/src/bitbucket/hotfix/BB-1234 37732bd [hotfix/BB-1234] 

Improved support for many working copies with the git bisect command. The links that were used by the bisect for “good” and “bad” commits moved from .git / refs / bisect to .git / refs / worktrees / $ worktree_name / refs / bisect , so now the bisect can work in different working copies of the repository .

In addition, starting with Git 2.7, you can use git clone , specifying such a separate working copy as an argument - this will create an independent git-repository, and not another working copy of the existing one.
')
It is noteworthy that separate working copies can be created not only for branches. Like many other commands, git worktree add can be called with a pointer to a commit, be it its hash or tag:
 $ git worktree add ../git-2.4.7 ca00f80 Preparing ../git-2.4.7 (identifier git-2.4.7) HEAD is now at ca00f80 Git 2.4.7 $ git worktree add ../git-v2.6.0 v2.6.0 Preparing ../git-v2.6.0 (identifier git-v2.6.0) HEAD is now at be08dee Git 2.6 $ git worktree add ../git-v2.7.0 v2.7.0 Preparing ../git-v2.7.0 (identifier git-v2.7.0) HEAD is now at 7548842 Git 2.7 $ git worktree list /Users/kannonboy/src/git 7548842 [master] /Users/kannonboy/src/git-2.4.7 ca00f80 (detached HEAD) /Users/kannonboy/src/git-v2.6.0 be08dee (detached HEAD) /Users/kannonboy/src/git-v2.7.0 7548842 (detached HEAD) 


Some git stash improvements


If you are a fan of git rebase , then you are most likely familiar with the --autostash option. It automatically saves all local changes to temporary storage ( stash ) before rebase , and after its completion applies them again.
 $ git rebase master --autostash Created autostash: 54f212a HEAD is now at 8303dca It's a kludge, but put the tuple from the database in the cache. First, rewinding head to replay your work on top of it... Applied autostash. 

This is convenient because you can rebase on a dirty working copy. For even more convenience, there is the rebase.autostash option , which makes this described as the default behavior. Apply it globally using the command:
 $ git config --global rebase.autostash true 

This parameter still exists with Git 1.8.4 , but the ability to cancel it with the option --no-autostash has been added to Git 2.7. Most likely, this option is added for completeness, since the only thing it gives when trying to rebase on a dirty working copy is the corresponding warning:
 $ git rebase master --no-autostash Cannot rebase: You have unstaged changes. Please commit or stash them. 

Speaking of configuration, it is also worth mentioning the stash.showPatch parameter, which also appeared in Git 2.7. At standard settings, the git stash show command displays only brief information about the files in the temporary storage:
 $ git stash show package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 

If you additionally specify the -p option, the output will be supplemented with an extended description of file changes:
 diff --git a/package.json b/package.json index c876b26..e21eeb3 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "mkdirp": "^0.5.0", "byline": "^4.2.1", "express": "~3.3.4", - "git-guilt": "^0.1.0", + "git-guilt": "^0.1.1", "jsonfile": "^2.0.0", "jugglingdb-sqlite3": "0.0.5", "jugglingdb-postgres": "~0.1.0", 

The stash.showPatch parameter makes this the default behavior. Apply it globally using a similar command:
 $ git config --global stash.showPatch true 

As in the previous case, the included parameter can be canceled and thus return to the old brief output - using the option --stat :
 $ git stash show --stat package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 

Be careful: the option --no-patch does not cause an error, but it does not cancel the stash.showPatch , as you would expect.

Acceleration git filter-branch and progress indicator


git filter-branch is a universal tool for changing the repository history. Since each commit has references to parent commits, which means it transitively refers to all commits that are its ancestors, changing one commit inevitably entails changing all its descendants. This, in turn, means that an operation of even an elementary change in history can take some time, if you need to change a rather old commit.

In Git 2.7, an elegant progress indicator appeared that displays the estimated time until the end of the filter-branch run:


In addition, if filter-branch does not change objects in the index or trees, then the index is not read at all when the command is executed, which significantly increases its performance. The --commit-filter option on the animation above changes only the author of each commit and does not affect the tree objects associated with them. Changing the first 1000 commits of Bitbucket Server took only 38 seconds using Git 2.7.0, while a similar operation with Git 2.6.0 took 64 seconds, that is, the speed increase was as much as 40% . Performance tests, introduced in Git 2.7 with these improvements, show an even more impressive acceleration - up to 60% .

Improved Negation in .gitignore


The .gitignore files allow you to exclude some files in the working copy from the repository, i.e. they will not be added to the index. Patterns support the negation flag with the prefix ! so that it is possible to cancel the ignoring of a specific file. For example, with such templates, git will ignore all files with a .json extension, except cat.json :
 # .gitignore *.json !cat.json 

However, in Git 2.6 it was impossible to apply a negative to a file that is already in the ignored folder.
 # .gitignore /animals !/animals/cat.json # <--     Git 2.6     

Starting from Git 2.7, the second example works exactly as expected: with ! Now you can cancel ignoring files in folders that would otherwise be ignored.

But that's not all!


This is only a small part of the buns that appeared in Git 2.7. The full list of changes can be found in the release notes , as well as in the comments to the commits in the Git repository itself :
 $ git log v2.6.0..v2.7.0 



The author of the original article , Tim Pettersen, participated in the development of JIRA, FishEye / Crucible and Stash. From the beginning of 2013, he talks about development processes, git, continuous integration and continuous integration / deployment, and Atlassian tools for developers, especially Bitbucket. Tim regularly posts notes about these and other things on Twitter under the pseudonym @kannonboy .

Source: https://habr.com/ru/post/276679/


All Articles