John Kary

git 1.7.8 was released a little over a week ago. You can view the 1.7.8 release notes for a full list of changes.

Most changes will probably not affect your every day use of git, but a few new features should be useful.

git merge learned the --edit option to allow editing the merge commit log message

If your development revolves around feature branches, you probably already branch and merge daily. Depending on your preference, you might preserve merge commits in your log history. If you abide by gitflow or manually specify the --no-ff option when merging, you are preserving the merge commit.

By default, these commits are auto-generated by git and don't tell you much. They list which files had conflicts, if any, and the name of the merged branch. Unless there is a conflict, you are not given the chance to edit the commit message when making the merge. But thanks to the new --edit option, you can now add a custom message when merging.

Using --edit will cause git to perform the merge then drop you into your core.editor application to edit the merge commit message itself before finally writing it to your history.

You could use this functionality to write a quick all-inclusive summary of a feature you are merging and how it might integrate with other pieces of your software. If I'm working on an internal team project, I'll also include any commands my co-developers need to make in lieu of these new changes.

git merge --no-ff --edit

git grep learned --untracked option

If you aren't familiar with the Unix tool grep, it basically allows you to search for text within other blocks of text. That block of text may be a large log file or any other type of output sent to your console.

git grep is similar to normal grep, but provides grep functionality within the context of a git repository. For example, git grep takes into account the files ignored in .gitignore and will not return results found in those files.

With the new --untracked option, git grep can now search through untracked files as well. So if you have untracked files you might have created but not yet added to your project, you can search through them as well.

git grep --untracked "string to find"

git diff learned --function-context option to show the whole function as context that was affected by a change

When displaying a diff, a one-line change is normally shown with 3 lines of context. This means the 3 lines both before and after the change are displayed to help remind you where this change was made.

 (master) ~/Sites/hallcenter_awards/symfony $ git diff
diff --git a/apps/applicant/modules/application/actions/actions.class.php b/apps/applicant/modules/application/actions/actions.class.php
index 5092da4..ec22e6d 100644
--- a/apps/applicant/modules/application/actions/actions.class.php
+++ b/apps/applicant/modules/application/actions/actions.class.php
@@ -21,7 +21,6 @@ class applicationActions extends BaseActions

     $this->route = $this->getContext()->getRouting()->getCurrentRouteName();

- $this->competition = $this->getCompetitionBySlug($request); $this->forward404Unless($this->competition->isPassedOpenDate(), 'Competition not open for Applications yet.');

     $this-&gt;applicant = $this-&gt;getUser()-&gt;getGuardUser();</code></pre></figure>

If your change is within a larger function or block of code, like the previous example, 3 lines of context isn't enough to tell exactly where in the function this change was made. git shows us the class declaration as context (seen above as class applicationActions extends BaseActions), but wouldn't it be great if we could see the entirety of the function where the change was made?

The new option --function-context (or its -W short option) attempts to provide you this context, giving you all lines of the function within which your change was made:

 (master) ~/Sites/hallcenter_awards/symfony $ git diff --function-context
diff --git a/apps/applicant/modules/application/actions/actions.class.php b/apps/applicant/modules/application/actions/actions.class.php
index 5092da4..ec22e6d 100644
--- a/apps/applicant/modules/application/actions/actions.class.php
+++ b/apps/applicant/modules/application/actions/actions.class.php
@@ -11,203 +11,202 @@
 class applicationActions extends BaseActions
 {
     /*
      * Executes before every action
      *
      * Sets navigation breadcrumbs
      /
     public function preExecute()
     {
         $request = $this->getRequest();

     $this-&gt;route = $this-&gt;getContext()-&gt;getRouting()-&gt;getCurrentRouteName();

- $this->competition = $this->getCompetitionBySlug($request); $this->forward404Unless($this->competition->isPassedOpenDate(), 'Competition not open for Applications yet.');

     $this-&gt;applicant = $this-&gt;getUser()-&gt;getGuardUser();
     $this-&gt;application = $this-&gt;getApplicantCompetitionApplication($this-&gt;applicant, $this-&gt;competition);

     $this-&gt;setSlotBreadcrumbCompetition($this-&gt;competition-&gt;getTitle(), &#39;application_overview&#39;, array(&#39;slug&#39; =&gt; $this-&gt;competition-&gt;getSlug()));
     $this-&gt;setSlotBreadcrumbCompetitionPage(&#39;Application Form&#39;);
 }

 /**
  * Displays Application form
  *
  * If Applicant has already started applying, display their info
  *
  * @param sfWebRequest $request
  */
 public function executeNew(sfWebRequest $request)
 {
     $this-&gt;redirectIf($this-&gt;applicationExists($this-&gt;application), array(
         &#39;sf_route&#39; =&gt; &#39;application_edit&#39;,
         &#39;slug&#39; =&gt; $this-&gt;competition-&gt;getSlug(),
     ));
}
// basically continues until the end of the file</code></pre></figure>

I've found this option rather unreliable, at least within a large PHP class. My tests found --function-context often results in displaying almost all of the original file, and git appears ignorant of PHP's function boundaries. The number of context lines before and after a change seem random, and the diff doesn't necessarily always show all lines of the function, either.

The original patch message that introduced this change sheds some light:

This implementation has the same shortcoming as the one in grep, namely that there is no way to explicitly find the end of a function. That means that a few lines of extra context are shown, right up to the next recognized function begins.

So it appears detecting a function's boundaries is difficult for git. It seems in this instance, git never detects a function boundary and gives us the context of the entire file.

Perhaps support for this functionality will improve in future versions.

For now, git diff already supports the --unified= option, or its short version -U, for displaying a larger number of context lines than the default of 3. At this point, I can only recommend using --unified= to display more lines of context in your diffs.

git diff --unified=10

comments powered by Disqus