<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brandon Pugh</title>
    <description>The latest articles on DEV Community by Brandon Pugh (@bpugh).</description>
    <link>https://dev.to/bpugh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F197150%2Faee7f037-ce9f-4337-8056-18c7195c40bf.jpeg</url>
      <title>DEV Community: Brandon Pugh</title>
      <link>https://dev.to/bpugh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bpugh"/>
    <language>en</language>
    <item>
      <title>Tips for creating merge commits</title>
      <dc:creator>Brandon Pugh</dc:creator>
      <pubDate>Tue, 03 Sep 2024 17:01:55 +0000</pubDate>
      <link>https://dev.to/bpugh/tips-for-creating-merge-commits-7jk</link>
      <guid>https://dev.to/bpugh/tips-for-creating-merge-commits-7jk</guid>
      <description>&lt;p&gt;I've reviewed quite a few pull requests in recent years and I've noticed some less-than-ideal practices when it comes to creating merge commits so I thought I'd list some things you can do to make life a little easier for someone reviewing your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the commit message as useful as possible
&lt;/h2&gt;

&lt;p&gt;A lot has been written about &lt;a href="https://cbea.ms/git-commit/" rel="noopener noreferrer"&gt;how to write good commit messages&lt;/a&gt;, but I rarely see the advice applied to merge commits.&lt;br&gt;
They may not be the most exciting type of commit, but they're still very important.&lt;/p&gt;
&lt;h3&gt;
  
  
  When merging PRs
&lt;/h3&gt;

&lt;p&gt;Merge commits that merge a pull request are more straight forward because, these days, they're generally created by the git hosting service so you know they only contain all the changes from that feature branch.&lt;/p&gt;

&lt;p&gt;But you can still make sure they convey the most useful info.&lt;br&gt;
I like the default from Azure DevOps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Merged PR 123: &amp;lt;PR title&amp;gt;

&amp;lt;PR Description&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can get a similar defult in GitHub by configuring the default merge commit settings in the repository settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  For other merge commits
&lt;/h3&gt;

&lt;p&gt;Now, keep in mind that the need for other merge commits can be mitigated by keeping feature branches small and short-lived, but that's not the reality for a lot of teams.&lt;/p&gt;

&lt;p&gt;For the most part I recommend sticking with the default message that git generates when you run &lt;code&gt;git commit&lt;/code&gt; to complete a merge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Merge branch 'main' into feature-branch
&lt;span class="gh"&gt;# Please enter a commit message to explain why this merge is necessary,&lt;/span&gt;
&lt;span class="gh"&gt;# especially if it merges an updated upstream into a topic branch.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you notice though, it includes a comment recommending explaining why the merge was necessary.&lt;br&gt;
This could be something like "Merging in updated auth flow" or "Merging in changes to &lt;code&gt;sharedService&lt;/code&gt; to avoid conflicts".&lt;br&gt;
This also implies that you should have a reason for the merge which I agree with because otherwise you're adding unnecessary noise to the git log.&lt;/p&gt;

&lt;p&gt;At the very least make it clear that it's a merge commit.&lt;br&gt;
Don't just put something like &lt;code&gt;update database migrations&lt;/code&gt; if you did have to do that as a result of the merge then mention it in the body of the message (though as I'll explain shortly, it should go in a followup commit).&lt;br&gt;
Otherwise, depending on how you're viewing the git log, it might not be obvious that it's a merge commit.&lt;/p&gt;
&lt;h3&gt;
  
  
  List conflicts in the commit message
&lt;/h3&gt;

&lt;p&gt;If there were conflicts during the merge, then git will list the files in the commit message, but they're commented out by default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Merge branch 'main' into feature-branch

&lt;span class="gh"&gt;# Conflicts:&lt;/span&gt;
&lt;span class="gh"&gt;#   package.json&lt;/span&gt;
&lt;span class="gh"&gt;#   package-lock.json&lt;/span&gt;
&lt;span class="gh"&gt;#&lt;/span&gt;
&lt;span class="gh"&gt;# It looks like you may be committing a merge.&lt;/span&gt;
&lt;span class="gh"&gt;# If this is not correct, please run&lt;/span&gt;
&lt;span class="gh"&gt;#   git update-ref -d MERGE_HEAD&lt;/span&gt;
&lt;span class="gh"&gt;# and try again.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can remove the &lt;code&gt;#&lt;/code&gt; from the lines to uncomment them and include them in the commit message.&lt;/p&gt;

&lt;p&gt;As a reviewer, I appreciate this because it's easy to make mistakes when resolving conflicts so if I see files listed then I can scrutinize them more closely.&lt;/p&gt;

&lt;p&gt;You can make it even more convenient by using a &lt;a href="https://git-scm.com/docs/githooks#_prepare_commit_msg" rel="noopener noreferrer"&gt;&lt;code&gt;prepare-commit-msg&lt;/code&gt;&lt;/a&gt; hook to uncomment them automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;COMMIT_MSG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;COMMIT_SOURCE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMIT_SOURCE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"merge"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;.bak &lt;span class="s1"&gt;'/^# Conflicts:/,/^#$/ s/..//'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMIT_MSG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Bonus: use &lt;code&gt;git show --remerge-diff&lt;/code&gt; to see how they were resolved
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.blog/2022-04-18-highlights-from-git-2-36/#review-merge-conflict-resolution-with-remerge-diff" rel="noopener noreferrer"&gt;In Git 2.36&lt;/a&gt;, the &lt;code&gt;--remerge-diff&lt;/code&gt; option was added to &lt;code&gt;git show&lt;/code&gt;.&lt;br&gt;
This makes it easier to see how conflicts were resolved in a merge commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid "evil" merges
&lt;/h2&gt;

&lt;p&gt;An "evil" merge as defined by the &lt;a href="https://git-scm.com/docs/gitglossary.html#Documentation/gitglossary.txt-aiddefevilmergeaevilmerge" rel="noopener noreferrer"&gt;git docs&lt;/a&gt; is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a merge that introduces changes that do not appear in any parent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or as Linus himself &lt;a href="https://www.mail-archive.com/git@vger.kernel.org/msg73938.html" rel="noopener noreferrer"&gt;puts it&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;an "evil merge" is something that makes changes that came from neither side and aren't actually resolving a conflict&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A merge commit is likely pulling in a large amount of unrelated changes, so it can be hard to notice if you add in your own changes.&lt;br&gt;
I prefer to do the bare minimum to resolve any textual conflicts.&lt;/p&gt;

&lt;p&gt;If there are semantic issues that need to be resolved (i.e. a database view was renamed so my code fails at runtime), then I fix them in a separate commit which not only makes it easier to review but also makes commands like &lt;code&gt;git blame&lt;/code&gt; more useful.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Git Config Settings I Always Recommend</title>
      <dc:creator>Brandon Pugh</dc:creator>
      <pubDate>Sun, 21 Jan 2024 06:16:28 +0000</pubDate>
      <link>https://dev.to/bpugh/git-config-settings-i-always-recommend-11fa</link>
      <guid>https://dev.to/bpugh/git-config-settings-i-always-recommend-11fa</guid>
      <description>&lt;p&gt;&lt;a href="https://www.brandonpugh.com/es/blog/configuraciones-de-git-que-siempre-recomiendo/"&gt;Spanish translation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've ever worked on a project with me then I've probably recommended at least one of these config settings in git.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git config --global pull.rebase true&lt;/code&gt; - tells git to always pull with rebase instead of merge (the equivalent of &lt;code&gt;pull --rebase&lt;/code&gt;). This not only saves you having to type the flag every time, but also ensures gui clients will also use rebase when pulling.
&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/em&gt; You should only enable this if you’re comfortable with rebasing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git config --global fetch.prune true&lt;/code&gt; - tells git to automatically run &lt;code&gt;git remote prune&lt;/code&gt; after a &lt;code&gt;fetch&lt;/code&gt;. This will clean up any local objects that no longer exist on the remote like tracking branches that have been deleted from the remote server.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git config --global rebase.autoStash true&lt;/code&gt; - tells git to automatically stash when you perform a pull and then attempt to unstash them once the rebase is complete. This is almost always my workflow so it's nice to have git do it for me.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git config --global rebase.autosquash true&lt;/code&gt; - tells git to automatically include the &lt;code&gt;--autosquash&lt;/code&gt; parameter when doing a &lt;code&gt;git rebase --interactive&lt;/code&gt;. You should &lt;a href="https://thoughtbot.com/blog/autosquashing-git-commits"&gt;read more about autosquashing&lt;/a&gt; commits if you're unfamiliar with it. I use it all the time for fixing up or rewording previous commits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Newer settings
&lt;/h2&gt;

&lt;p&gt;If you haven't updated git in a couple years then you should as it's worth it just for these new config options.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git config --global push.useForceIfIncludes true&lt;/code&gt; (2.30.0) - This setting makes &lt;code&gt;push --force-with-lease&lt;/code&gt; even safer. &lt;a href="https://git-scm.com/docs/git-push#Documentation/git-push.txt---no-force-if-includes"&gt;See the docs&lt;/a&gt; for more info.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git config --global push.autoSetupRemote true&lt;/code&gt; (2.37.0) - Git will automatically setup an upsteam tracking when you run &lt;code&gt;git push&lt;/code&gt; from a new branch.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git config --global rebase.updateRefs true&lt;/code&gt; (2.38.0) - the &lt;code&gt;--update-refs&lt;/code&gt; option &lt;a href="https://andrewlock.net/working-with-stacked-branches-in-git-is-easier-with-update-refs/"&gt;makes working with stacked branches easier&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Personal preference
&lt;/h2&gt;

&lt;p&gt;You might find these useful depending on your personal workflow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git config --global commit.verbose true&lt;/code&gt; - Git will include the diff of the changes at the bottom of the commit message template. I like this because your text editor can then autocomplete variable or function names you want to include in the commit message.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git config --global rerere.enabled true&lt;/code&gt; - It stands for Reuse Recorded Resolution, and tells Git to remember how you resolved a merge conflict and automatically reapply if it sees it again.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Blazor Best Practices Borrowed From React</title>
      <dc:creator>Brandon Pugh</dc:creator>
      <pubDate>Tue, 21 Mar 2023 16:26:01 +0000</pubDate>
      <link>https://dev.to/bpugh/blazor-best-practices-borrowed-from-react-pp7</link>
      <guid>https://dev.to/bpugh/blazor-best-practices-borrowed-from-react-pp7</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally published on&lt;/em&gt; &lt;a href="https://www.brandonpugh.com/blog/blazor-best-practices/"&gt;https://www.brandonpugh.com/blog/blazor-best-practices/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Blazor took a lot of design decisions from React and other frontend frameworks and as a stateful component-based UI framework there is quite a bit of experience that can be transferred from one to the other.&lt;/p&gt;

&lt;p&gt;I gave this talk earlier this year at KCDC and then last week I presented an updated version as a Jetbrains webinar. Special thanks to &lt;a href="https://khalidabuhakmeh.com/"&gt;Khalid&lt;/a&gt; for inviting me on and being an excellent host!&lt;/p&gt;

&lt;p&gt;I hope to write up the content in a more in depth post sometime soon, but in the mean time you can watch the recording on &lt;a href="https://www.youtube.com/watch?v=q7qgSzAALLg"&gt;Youtube&lt;/a&gt; and view the slides at &lt;a href="https://www.brandonpugh.com/blazor-talk/#/"&gt;brandonpugh.com/blazor-talk&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some of the points I cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State management&lt;/li&gt;
&lt;li&gt;Reusable components&lt;/li&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/q7qgSzAALLg"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=q7qgSzAALLg"&gt;Blazor Best Practices Borrowed from React&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blazor</category>
      <category>dotnet</category>
      <category>aspnet</category>
    </item>
  </channel>
</rss>
